如何使用 accumulate 函数对变量数组中的一行值求和?
How to use accumulate function to sum a row of values in a variable array?
我一直在开发一个程序,在该程序中我需要能够对列数为变量的二维数组中的行求和。我还应该补充一点,这些行 "split" 分为两部分(部分 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);
但是,我收到一个构建时错误,指出:
Indirection requires pointer operand ('double' invalid')
我认为这是一个语法错误,但改变我定义数组开始和结束的方式并没有解决错误。
accumulate
的两个第一个参数是函数将用来遍历范围的迭代器,但您传递的是数组的实际元素
Iterator in C++ is a concept that requires certain operations to be valid on your object, as defined per the standard. For instance, pointer types usually match the LegacyRandomAccessIterator,这意味着你基本上可以将它们用作类似数组的对象(你可以用 ++
增加它们,你可以用 *
间接它们,你可以访问位置 i
处的元素 []
,等等)。我不会详细介绍什么是 C++ 中的迭代器,因为这是一个完整的主题,您可以找到大量参考资料,特别是在我提供的两个链接上。
回到你的问题,你想要的是给你的行的开始和结束,或者你的子范围的开始和结束提供 accumulate
迭代器。有两种方法可以做到这一点:
- 获取元素的地址
stat[MASS][partStart[func]]
,即 &stat[MASS][partStart[func]]
,这将为您提供范围的开头,然后 &stat[MASS][partEnd[func]]
将为您提供范围的结尾.这是有效的,因为 stat
是 double stat[5][total]
和访问运算符 ([]
) 给你一个引用 (a double&
),你可以获取地址和元素行在内存中是连续的(这不适用于列)。
- 使用
stat[MASS] + partStart[func]
和 stat[MASS] + partEnd[func]
。在这种情况下,您采用行的开头 (stat[MASS]
),它是(或隐式转换为)指向双精度 (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);
我一直在开发一个程序,在该程序中我需要能够对列数为变量的二维数组中的行求和。我还应该补充一点,这些行 "split" 分为两部分(部分 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);
但是,我收到一个构建时错误,指出:
Indirection requires pointer operand ('double' invalid')
我认为这是一个语法错误,但改变我定义数组开始和结束的方式并没有解决错误。
accumulate
的两个第一个参数是函数将用来遍历范围的迭代器,但您传递的是数组的实际元素
Iterator in C++ is a concept that requires certain operations to be valid on your object, as defined per the standard. For instance, pointer types usually match the LegacyRandomAccessIterator,这意味着你基本上可以将它们用作类似数组的对象(你可以用 ++
增加它们,你可以用 *
间接它们,你可以访问位置 i
处的元素 []
,等等)。我不会详细介绍什么是 C++ 中的迭代器,因为这是一个完整的主题,您可以找到大量参考资料,特别是在我提供的两个链接上。
回到你的问题,你想要的是给你的行的开始和结束,或者你的子范围的开始和结束提供 accumulate
迭代器。有两种方法可以做到这一点:
- 获取元素的地址
stat[MASS][partStart[func]]
,即&stat[MASS][partStart[func]]
,这将为您提供范围的开头,然后&stat[MASS][partEnd[func]]
将为您提供范围的结尾.这是有效的,因为stat
是double stat[5][total]
和访问运算符 ([]
) 给你一个引用 (adouble&
),你可以获取地址和元素行在内存中是连续的(这不适用于列)。 - 使用
stat[MASS] + partStart[func]
和stat[MASS] + partEnd[func]
。在这种情况下,您采用行的开头 (stat[MASS]
),它是(或隐式转换为)指向双精度 (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);