将奇数定位和偶数定位的整数求和

时间:2015-10-15 23:57:18

标签: c++ algorithm

将“奇数位置上的每个数字”与“偶数位数上的每个数字乘以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

3 个答案:

答案 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循环可能甚至是更好的解决方案。