使用 C++17 或更高版本对向量中的元素对求和的最'functional'方法?
Most 'functional' way to sum pairs of elements from a vector using C++17 or later?
我想得到一些建议,以最简洁和"功能"的方式使用现代C++从向量(第 1 和第 2、第 3 和第 4 等(收集连续元素对。 假设向量是任意但长度均匀的。 对于我放在一起的例子,我把每对的元素相加,但这不是主要问题。 我应该补充一点,我将只使用 STL,没有 Boost。
在 Python 中,我可以通过迭代器将它们压缩成 2 元组
s = range(1,11)
print([(x + y) for x,y in zip(*[iter(s)] * 2)])
在 Perl 5 中,我可以剥离成对
use List::Util qw/pairs sum/;
use feature 'say';
@s = 1 .. 10;
say sum @$_ foreach (pairs @s);
在Perl 6中,我可以一次将它们两个推入一个块中
my @s = 1 .. 10;
for @s -> $x, $y { say $x + $y; }
在 R 中,我可以将向量包装成一个 2 列数组并将行求和
s <- 1:10
print(apply(matrix(s, ncol=2, byrow=TRUE), 1, sum))
我C++不流利,我的解决方案使用 for(;;)
. 这感觉太像C了。
#include <iostream>
#include <vector>
#include <numeric> // std::iota
int main() {
std::vector<int> s(10);
std::iota(s.begin(), s.end(), 1);
for (auto p = s.cbegin(); p != s.cend(); p += 2)
std::cout << (*p + *(p + 1)) << std::endl;
}
输出当然应该是某种变体
3
7
11
15
19
使用 range-v3:
for (auto v : view::iota(1, 11) | view::chunk(2)) {
std::cout << v[0] + v[1] << 'n';
}
请注意,chunk(2)
不会为您提供编译时固定大小视图,因此您无法执行以下操作:
for (auto [x,y] : view::iota(1, 11) | view::chunk(2)) { ... }
不使用 range-v3,我可以使用函数或 lambda 模板来做到这一点。我将在这里展示 lambda 版本。
#include <iostream>
#include <string>
#include <vector>
template<typename T>
auto lambda = [](const std::vector<T>& values, std::vector<T>& results) {
std::vector<T> temp1, temp2;
for ( std::size_t i = 0; i < values.size(); i++ ) {
if ( i & 1 ) temp2.push_back(values[i]); // odd index
else temp1.push_back(values[i]); // even index
}
for ( std::size_t i = 0; i < values.size() / 2; i++ )
results.push_back(temp[i] + temp[2]);
};
int main() {
std::vector<int> values{ 1,2,3,4,5,6 };
for (auto i : values)
std::cout << i << " ";
std::cout << 'n';
std::vector<int> results;
lambda<int>(values, results);
for (auto i : results)
std::cout << i << " ";
std::cout << 'n';
std::vector<float> values2{ 1.1f, 2.2f, 3.3f, 4.4f };
for (auto f : values2)
std::cout << f << " ";
std::cout << 'n';
std::vector<float> results2;
lambda<float>(values2, results2);
for (auto f : results2)
std::cout << f << " ";
std::cout << 'n';
std::vector<char> values3{ 'a', 'd' };
for (auto c : values3)
std::cout << c << " ";
std::cout << 'n';
std::vector<char> results3;
lambda<char>(values3, results3);
for (auto c : results3)
std::cout << c << " ";
std::cout << 'n';
std::vector<std::string> values4{ "Hello", " ", "World", "!" };
for (auto s : values4)
std::cout << s;
std::cout << 'n';
std::vector<std::string> results4;
lambda<std::string>(values4, results4);
for (auto s : results4)
std::cout << s;
std::cout << 'n';
return EXIT_SUCCESS;
}
输出
1 2 3 4 5 6
3 7 11
1.1 2.2 3.3 4.4
3.3 7.7
a d
┼
Hello World!
Hello World!
冒着听起来像我试图变得聪明或烦人的风险,我说这就是答案:
print(sums(successive_pairs(range(1,11))));
当然,这些不是内置函数,所以你必须定义它们,但我不认为这是一件坏事。 代码以函数式风格清楚地表达了您想要的内容。 此外,每个函数的职责都是很好的分离的,易于测试和可重用。 没有必要使用很多棘手的专用语法来编写函数式风格的代码。
相关文章:
- 如何对多维 std::vector 的所有元素求和?
- 使用 C++17 或更高版本对向量中的元素对求和的最'functional'方法?
- 在 MPI 中逐个元素对数组元素求和和收集
- 以C++递归方式对链表中的元素求和
- CUDA:所有矢量元素的级联求和
- 将彼此平行的两个 int 向量的元素求和
- 使用变换和加 () 对向量的元素进行求和和模 10^9+7<int>。有什么办法可以做到这一点吗?
- 用以下方法对数组中的元素求和的有效方法是什么
- 难以对 2D 矢量的元素求和
- 循环访问 CUDA 中的三维数组以对它们的元素求和
- 如何将函数静态应用于非类型模板包的各个元素并对结果求和
- 我如何确定我是否可以将数组中的某些元素求和为 K
- 在C++中使用do-while循环对向量的元素求和
- 在c++中对最小数组元素求和
- 递归算法对数组中值小于x的每个元素求和
- 如何使用本函数对两个字符数组进行元素相乘,并将相乘结果求和为int
- 如何对一个公共矩阵中的所有元素求和
- 通过迭代器对map的元素求和
- 如何在c++中对multimap中具有相同键的所有元素求和
- 在一个数组中查找求和为k的两个元素