将“奇数位置上的每个数字”与“偶数位数上的每个数字乘以3”相加的最优雅方法是什么?我必须遵守这个原型
int computeCheckSum(const int* d)
我的第一次尝试是使用它,但我的想法是有缺陷的。我找不到一种方法来判断哪个元素就是这样。
int sum=0;
for_each(d,
d+11,
[&sum](const int& i){sum+=(i%2==1)?3*i:i;}
);
例如
1 2 3 4 5
1 + 2 * 3 + 3 + 4 * 3 + 5 = 27
答案 0 :(得分:2)
我无法找到一种方法来判断哪个元素就是这样。
如果您坚持使用for_each
(这里没有理由这样做),那么您将单独跟踪索引:
int computeCheckSum(const int* d, int count)
{
int sum=0;
int pos=1;
std::for_each(d, d+count,
[&sum,&pos](const int& value) { sum += pos++ % 2 ? value : value * 3; } );
return sum;
}
注意我添加了count
参数,因此该函数可以处理任何长度的数组。如果你感觉真的很反常,你可以删除该参数并返回硬编码长度,这样该函数只能使用12个元素的数组。但是,如果你希望有一天能够擅长这一点,那么这样做会让你觉得很糟糕。
答案 1 :(得分:1)
这些东西很少变得非常优雅"在C ++中(似乎C ++在"线路噪声"索引上渐近接近Perl),但由于accumulate
是左侧折叠,您可以传递索引"沿着折叠" :
int sum = std::accumulate(d,
d + 11,
std::make_pair(0,0), // (index, result)
[](std::pair<int, int> r, int x) {
r.second += r.first % 2 ? x : 3 * x;
r.first++;
return r;
}).second;
答案 2 :(得分:0)
你是对的。正如Mud所说,这只是一个糟糕的功能设计。这就是我需要的。
int computeCheckSum(){
int sum = 0;
bool multiplyBy3 = false;
for (auto i : m_digits){
sum += multiplyBy3 ? 3*i : i;
multiplyBy3 = !multiplyBy3;
}
return sum;
}
使用我的有缺陷的设计,泥浆的解决方案是正确的。正如大家所说的那样,简单的for循环可能甚至是更好的解决方案。