在列表<int>或向量<int>中添加备用数字
Add alternate numbers in a list<int> or vector<int>
我试图访问列表中的备用数字以添加其值。例如,如果List的值={1,2,3,5}。我应该得到输出,4和7。
为了达到这个目的,我使用了std::List。首先,我需要能够访问序列的第n个元素,std::list
,以便能够添加值。也就是说,我知道我可以使用std::advance
:
获得到第n个元素的迭代器std::list<Object> l;
unsigned N = /* index of the element that I want to retrieve */;
if (l.size() > N)
{
std::list<Object>::iterator it = l.begin();
std::advance(it, N);
}
然而,这并不能解决我的问题,因为我不明白如何能够访问替代值,同时添加它们,因为它不提供随机访问。
所以,我尝试使用std::vector
,我使用
sum_of_vector =std::accumulate(vector.begin(),vector.end(),0);
当我添加向量的所有值时,这工作得很好,但我不理解逻辑,如果我只需要添加std::list
或std::vector
的替代值。
请看下面的代码。我已经添加了注释,所以它将是不言自明的。
#include <bits/stdc++.h>
using namespace std;
int main()
{
//Your vector of integers
vector<int> V = {1, 2, 3, 5};
//Size of your vector
int n = V.size();
//Initialise two integers to hold the final sum
int sum1 = 0;
int sum2 = 0;
//Calculate sum1 starting from first element and jumping alternate element until you reach end
for(int i=0; i<n; i+=2)
sum1 += V[i];
//Calculate sum2 starting from second element and jumping alternate element until you reach end
for(int i=1; i<n; i+=2)
sum2 += V[i];
//Print your answer
cout << "Sum1 = " << sum1 << " " << "Sum2 = " << sum2 << endl;
return 0;
}
解决方法很简单。
- 创建包含两个元素的数组来累加总和。
- 使用在
0
和1
之间交替的索引
Object sum[2] = {0};
int index = 0;
auto iter = l.begin();
auto end = l.end();
for ( ; iter != end; ++iter, index = (index+1)%2 )
{
sum[index] += *iter;
}
代码解释,回应OP的注释
让我们以你的清单为例:
l is {1, 2, 3, 5}
在for
循环开始处:
sum[0] = sum[1] = 0
index = 0
iter points to the element whose value is 1
当循环执行时,
sum[index] = sum[0] = 1
在循环的下一次迭代中,
index = 1
iter points to the element whose value is 2
当循环执行时,
sum[index] = sum[1] = 2
在循环的下一次迭代中,
index = 0
iter points to the element whose value is 3
当循环执行时,
sum[index] = sum[0] = 4
在循环的下一次迭代中,
index = 1
iter points to the element whose value is 5
当循环执行时,
sum[index] = sum[1] = 7
在循环的下一次迭代中,指数= 0Iter指向终点。循环停止执行。
此时,
sum[0] = 4
sum[1] = 7
这样如何:
Object sum[2];
size_t i = 0;
for (auto it = l.begin(); it != l.end(); ++it, ++i)
sum[i % 2] += *it;
递归爱好者可能会建议:
typedef std::list<int> IntList;
typedef IntList::iterator IntListIT;
void odd (IntListIT IT, int& sumEven, int& sumOdd, IntListIT ITend);
void even(IntListIT IT, int& sumEven, int& sumOdd, IntListIT ITend);
void even(IntListIT IT, int& sumEven, int& sumOdd, IntListIT ITend) {
sumEven += *IT;
if(++IT != ITend)
odd(IT, sumEven, sumOdd, ITend); // tail-recursion
}
void odd(IntListIT IT, int& sumEven, int& sumOdd, IntListIT ITend) {
sumOdd += *IT;
if(++IT != ITend)
even(IT, sumEven, sumOdd, ITend); // tail-recursion
}
int t209(void)
{
IntList intList;
for (int i=0; i<10; ++i)
intList.push_back(i+1);
int sumEven = 0;
int sumOdd = 0;
even(intList.begin(), sumEven, sumOdd, intList.end());
std::cout << "nsumEven: " << sumEven
<< "n sumOdd: " << sumOdd
<< "n total: " << (sumEven + sumOdd)
<< std::endl;
return(0);
}
与输出sumEven: 25
sumOdd: 30
total: 55
一个不同的递归爱好者不会喜欢"混乱的"4参数递归函数,并且可能会建议一个类来完成这项工作。令人惊讶的是(?或者你是否怀疑这一点),他能够消除(!)所有(可见)参数为类的两个相互递归方法。
// class Even-Odd-Sum
class EOSum // wrap recursive efforts
{
public:
EOSum(IntList& intList) :
m_list(intList),
m_eSum(0),
m_oSum(0),
m_IT(intList.begin()),
m_ITend (intList.end())
{ }
~EOSum() { m_eSum = 0; m_oSum = 0; }
std::string operator()()
{
// do the math
e(); // recursively
// report results
std::stringstream ss;
ss << "n eSum: " << m_eSum
<< "n oSum: " << m_oSum
<< "n total: " << (m_eSum + m_oSum)
<< "nn sizeof(this): " << sizeof(this) << " bytes. "
<< "nestimated total stack needed with unoptimized recursive call: "
<< DTB::digiComma(C100M*(2*sizeof(this)))
<< "ndefault stack size Ubuntu 15.04 : "
<< DTB::digiComma(8*1024*1024)
<< std::endl;
return(ss.str());
}
static const int C100M = 100000000;
private:
IntList& m_list;
int64_t m_eSum;
int64_t m_oSum;
IntListIT m_IT; // iterate thru the list
IntListIT m_ITend;
// the new and improved recursion - NO (visible) PARAMETERS
void e()
{
m_eSum += *m_IT;
if (++m_IT != m_ITend)
o(); // tail-recursion
}
void o()
{
m_oSum += *m_IT;
if (++m_IT != m_ITend)
e(); // tail-recursion
}
};
// test
int t209b(void)
{
std::cout << "nnt209b start: using EOSum::C100M = "
<< DTB::digiComma(EOSum::C100M) << " multiplier (~10 seconds on lab005)"
<< std::endl;
uint64_t t209bStartMS = DTB::getSystemMillisecond();
uint64_t dtorStartMS;
{
IntList intList;
{
uint64_t startMS = DTB::getSystemMillisecond();
for (int i=0; i<EOSum::C100M; ++i) // use -O3 to avoid segfault - tail recursion optimized
intList.push_back(i+1);
uint64_t durationMS = DTB::getSystemMillisecond() - startMS;
std::cout << "n100M list push_back's : " << durationMS << " ms"
<< "n to 'new' intList elements " << std::endl;
}
{
uint64_t startMS = DTB::getSystemMillisecond();
// Ubuntu 15.04 default stack size 8 M Bytes
// 100,000: No stack over flow
// 1,000,000: -O0 stack overflow segfault, -O3: No segfault
// 100,000,000: -O3: No segfault
std::cout << EOSum(intList)() << std::endl;
uint64_t durationMS = DTB::getSystemMillisecond() - startMS;
std::cout << "100 M recursion calls : " << durationMS << " ms "
<< "n to compute eSum, oSum, total shown above " << std::endl;
}
dtorStartMS = DTB::getSystemMillisecond();
} // intList destruction at this brace
uint64_t dtorDurationMS = DTB::getSystemMillisecond() - dtorStartMS;
std::cout << "n100 M list item dtor's : " << dtorDurationMS
<< "n to 'delete' intList elements " << std::endl;
uint64_t t209bDurationMS = DTB::getSystemMillisecond() - t209bStartMS;
std::cout << "n t209b() duration MS : " << t209bDurationMS << std::endl;
return(0);
}
在这段代码中,当使用优化级别0(- 0)时,堆栈溢出(在递归期间),将100,000到1m个元素添加到列表中。注意Ubuntu 15.04的默认堆栈只有8 M字节,每个方法调用可能会使用16个字节(this ptr,并返回addr)。
然而,作者实现了尾部递归,并且由于g++ 4.9.2编译器令人印象深刻的优化(在第3级,-O3),该递归现在使用固定的堆栈元素数!尽管双重相互递归方法增加了复杂性。
这段代码有一些个人的库使用,所以下面是测试的输出:
请随意在您的机器上尝试(使用一些简单的替换或删除我的DTB::方法)。
所有的持续时间是从我的6年以上的戴尔。
t209b start: using EOSum::C100M = 100,000,000 multiplier (~10 seconds on lab005)
100M list push_back's : 6930 ms
to 'new' intList elements
eSum: 2500000000000000
oSum: 2500000050000000
total: 5000000050000000
sizeof(this): 8 bytes.
estimated total stack needed with unoptimized recursive call: 1,600,000,000
default stack size Ubuntu 15.04 : 8,388,608
100 M recursion calls : 1320 ms
to compute eSum, oSum, total shown above
100 M list item dtor's : 2754
to 'delete' intList elements
t209b() duration MS : 11035
real 0m11.290s
user 0m8.532s
sys 0m2.556s
在这种情况下,std::valarray
可能是合适的。假设您的目标是添加所有偶数成员和所有奇数成员,您可以这样做:
std::valarray<int> l;
// Put stuff into the array
std::valarray<int> even = l[std::slice(0, l.size() / 2, 2)]
std::valarray<int> odd = l[std::slice(1, l.size() / 2, 2)];
int sum_of_odd = odd.sum(), sum_of_even = even.sum();
- 为什么在全局范围内使用"extern int a"似乎不行?
- int(c) 和 c-'0' 之间的区别。C++
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 为什么野牛仍在使用"int yylex(void)",却找不到"int yylex(YYS
- 有符号的int和int-有没有一种方法可以在C++中区分它们
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 是否可以从int转换为enum类类型
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- 'short int'持有的值溢出,但"自动"不会溢出?
- 如何在C++中将一个无符号的 int 转换为两个无符号的短裤?
- 调用'begin(int [n])'没有匹配函数
- 没有显式声明的int[]中的foreach
- 在c++中访问int到类对象的映射时出错
- 为什么我无法更改"set<set>"循环中的值<int>
- EASTL矢量<向量<int>>连续的
- 为什么将此对向量&lt; map&lt; int,int&gt;&gt;中的地图进行更新.失败
- 如何加入向量&lt; int&gt;到C 中的单个INT
- 是numeric_limits&lt; int&gt; :: is_modulo从逻辑上矛盾
- 'structstd::对<int,int>'没有名为'push_back'