我有一个整数向量:
std::vector<int> values = {1,2,3,4,5,6,7,8,9,10};
考虑到值。size()
将始终为偶数。
我只是想把相邻的元素转换成一对,像这样:
std::vector<std::pair<int,int>> values = { {1,2}, {3,4} , {5,6}, {7,8} ,{9,10} };
即,两个相邻元件接合成一对。
我可以使用什么STL算法轻松实现这一点?有没有可能通过一些标准算法来实现这一点?
当然,我可以很容易地编写一个旧的索引for循环来实现这一点。但我想知道最简单的解决方案是什么,使用rangebased for循环或任何其他STL算法,比如std::transform
,等等。
我不知道为什么你需要一个标准的算法,当你自己写它大约是5行代码(加上样板):
template<class T>
std::vector<std::pair<T, T>> group_pairs(const std::vector<T>& values)
{
assert(values.size() % 2 == 0);
auto output = std::vector<std::pair<T, T>>();
output.reserve(values.size()/2);
for(size_t i = 0; i < values.size(); i+=2)
output.emplace_back(values[i], values[i+1]);
return output;
}
这样说吧:
std::vector<int> values = {1,2,3,4,5,6,7,8,9,10};
auto result = group_pairs(values)
我不知道有一种标准算法可以直接做你想要的事情(尽管我不太熟悉C20及更高版本)。你总是可以写一个循环,大多数循环可以通过标准算法std::for_each来表达。
由于您是成对累积元素,我想尝试一下std::acculate
#include <vector>
#include <numeric>
#include <iostream>
struct pair_accumulator {
std::vector<std::pair<int,int>> result;
int temp = 0;
bool set = false;
pair_accumulator& operator+(int x){
if (set) {
result.push_back({temp,x});
set = false;
} else {
temp = x;
set = true;
}
return *this;
}
};
int main() {
std::vector<int> values = {1,2,3,4,5,6,7,8,9,10};
auto x = std::accumulate(values.begin(),values.end(),pair_accumulator{}).result;
for (const auto& e : x) {
std::cout << e.first << " " << e.second << "\n";
}
}
不可否认,这是否比编写普通循环更简单值得怀疑。
如果可能的话,我会尽量不变换向量。而不是访问结果[i]。首先
您也可以使用值[i*2]
和类似的值来表示第二个
。如果这不可行,下一个选项是填充std::vector
#include <vector>
#include <iostream>
struct view_as_pairs {
std::vector<int>& values;
struct proxy {
std::vector<int>::iterator it;
int& first() { return *it;}
int& second() { return *(it +1); }
};
proxy operator[](size_t index){
return proxy{values.begin() + index*2};
}
size_t size() { return values.size() / 2;}
};
int main() {
std::vector<int> values = {1,2,3,4,5,6,7,8,9,10};
view_as_pairs v{values};
for (size_t i=0; i < v.size(); ++i){
std::cout << v[i].first() << " " << v[i].second() << "\n";
}
}
TL;医生:考虑是否可以避免这种转变。如果无法避免,那么编写循环可能是最干净的。标准算法经常有用,但并不总是如此。
一旦我们有了C 23对
#include <iostream>
#include <ranges>
#include <vector>
int main()
{
std::vector<int> values = {1,2,3,4,5,6,7,8,9,10};
auto chunk_to_pair = [](auto chunk)
{
return std::pair(*chunk.begin(), *std::next(chunk.begin()));
};
for (auto [first, second] : values | std::ranges::views::chunk(2) | std::ranges::views::transform(chunk_to_pair))
{
std::cout << first << second << std::endl;
}
}
或者,您可以通过
zip
ing一对stride
d视图来实现类似的结果
#include <iostream>
#include <ranges>
#include <vector>
int main()
{
std::vector<int> values = {1,2,3,4,5,6,7,8,9,10};
auto odds = values | std::ranges::views::drop(0) | std::ranges::views::stride(2);
auto evens = values | std::ranges::views::drop(1) | std::ranges::views::stride(2);
for (auto [first, second] : std::ranges::views::zip(odds, evens))
{
std::cout << first << second << std::endl;
}
}
我有一个整数向量: 考虑到将始终为偶数。 我只是想把相邻的元素转换成一对,像这样: i、 两个相邻的元件连接成一对。 我可以使用什么STL算法轻松实现这一点?有没有可能通过一些标准算法来实现这一点? 当然,我可以很容易地编写一个旧的索引for循环来实现这一点。但我想知道,使用基于范围的for循环或任何其他STL算法(如等)最简单的解决方案是什么样的。
下面的代码显示了我要做的:
我在std::sort中发现了一个bug,特别是在一些QuickSort的实现中,我不知道问题是否出在一般的算法中。 精华: 当元素小于16时,所有的规范都被替换,因为std::sort使用插入排序。 当有17个或更多的元素时,使用快速排序,并从元素数量的对数限制递归深度,但向量在第一次__introsort_loop迭代时有时间恶化。 当有许多相同的元素时,就会出现向量损坏。用无效迭代器替换有效
我会期望std::reference_wrapper在将non-const转换为const方面可以作为参考,例如: 下面的代码在MSVC和GCC中编译并运行良好,但在Clang上则不行。我只是不明白为什么,它是UB,还是实际上是关于Clang编译器的问题? 仅在Clang上,显示以下错误: https://wandbox.org/permlink/FSY4tCvE9B17hbVn
错误:无法将类型为“std::_bit_reference&”的非常量lvalue引用绑定到类型为“std::vector::reference”{aka“std::_bit_reference”}的rvalue 因此,它抱怨,因为只有第二个参数是rvalue
https://godbolt.org/z/P97MaK 我玩的概念和预期d::is_equality_comparable工作矢量,但它没有。 编译错误在 内部失败,而不是在受概念保护的函数边界处失败。 这是错误还是预期行为?