问题描述
我一直在开发一个程序,在该程序中,我需要能够对列数为变量的二维数组中的行进行求和。我还应该补充一点,行被“拆分” 分为两部分(A 部分和 B 部分),其大小取决于用户输入。
我显然可以只使用 for 循环对一行求和,但我想要一个更优雅的解决方案,它也更容易在整个程序中设置。我偶然发现了数字库中的 accumulate
函数,但我能找到的所有示例都专门用于一维数组。
这是我的问题代码示例:
total = partNum[PART_A] + partNum[PART_B];
partStart[PART_A] = 0;
partEnd[FUNC_A] = partNum[PART_A];
partStart[PART_B] = partNum[PART_A];
partEnd[FUNC_B] = total;
double stat[5][total];
double mass_sum = 0.0
func = PART_A;
accumulate(stat[MASS][partStart[func]],stat[MASS][partStart[func]],mass_sum);
间接需要指针操作数('double'无效')
我认为这是一个语法错误,但是改变我定义数组的开始和结束的方式并没有解决这个错误。
解决方法
accumulate
的两个第一个参数是函数将用于迭代范围的迭代器,但您传递的是数组的实际元素
Iterator 是一个概念,它要求某些操作对您的对象有效,如标准所定义。例如,指针类型通常匹配 LegacyRandomAccessIterator,这意味着您基本上可以将它们用作类数组对象(您可以使用 ++
增加它们,您可以使用 *
间接它们,您可以使用 i
等访问位置 []
处的元素)。我不会详细介绍什么是 C++ 中的迭代器,因为这是一个完整的主题,您可以找到大量参考资料,尤其是我提供的两个链接。
回到您的问题,您想要的是将 accumulate
迭代器赋予行的开头和结尾,或子范围的开头和结尾。有两种方法可以做到这一点:
- 取元素
stat[MASS][partStart[func]]
的地址,即&stat[MASS][partStart[func]]
,它会给你范围的开始,然后&stat[MASS][partEnd[func]]
会给你范围的结束。这是有效的,因为stat
与double stat[5][total]
一样,并且访问运算符 ([]
) 为您提供了一个引用(double&
),您可以获取其地址和元素行在内存中是连续的(这不适用于列)。 - 使用
stat[MASS] + partStart[func]
和stat[MASS] + partEnd[func]
。在这种情况下,您取行的开头 (stat[MASS]
),它是(或隐式转换为)指向 double (double*
) 的指针,然后将该指针增加partStart[func]
或partEnd[func]
,为您提供行中所需元素的地址。
所以基本上:
std::accumulate(&stat[MASS][partStart[func]],&stat[MASS][partEndfunc]],mass_sum);
// or
std::accumulate(stat[MASS] + partStart[func],stat[MASS] + partEnd[func],mass_sum);