我想为使用现代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
答案 0 :(得分:8)
使用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)) { ... }
答案 1 :(得分:1)
不使用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!
答案 2 :(得分:0)
冒着听起来我想变得聪明或烦人的风险,我说这就是答案:
print(sums(successive_pairs(range(1,11))));
现在,这些当然不是内置函数,因此您必须定义它们,但是我认为这不是一件坏事。该代码以功能性样式清楚地表达了您想要的内容。而且,每个功能的职责是完全分开的,易于测试的和可重用的。不必使用许多复杂的专门语法来以功能样式编写代码。