我有两个向量:
struct MyData{
double value;
};
std::vector<int> remove_flags = {0, 1, 0, 0, 0, 0, 1, 0};
std::vector<MyData> data = {{},{},{},{},{},{},{},{}};
Run Code Online (Sandbox Code Playgroud)
该remove_flags向量包含一个大小与 完全相同的标志数组data,每个标志要么是 0,要么是 1,其中 1 表示应删除数据。
我想用来remove_flags从data原地删除元素,即执行擦除删除习语,但根据remove_flags. 最终结果应该是data删除了元素,并希望删除remove_flags了那些相同的元素。
手动执行此操作很烦人,我想为此使用 Range-v3。我目前正在使用 C++17。
在查看文档后,我认为我没有找到解决方案,我能想到的最接近的事情是:
auto result = ranges::views::zip(remove_flags, data) | ranges::actions::remove_if([](std::pair<const int&, const MyData&> pair){
return pair.first != 0;
});
remove_flags.erase(result.first, remove_flags.end());
data.erase(result.second, data.end());
Run Code Online (Sandbox Code Playgroud)
但是操作无法对视图 zip 进行操作,因此无法编译。如果我切换ranges::actions::remove_if到ranges::views::remove_if一个奇怪的视图对象被返回,大概是一个没有实际std::remove对两个向量执行等效操作的对象。
我可以使用,contaner_to …
class A
{
bool OutofRange(string& a, string& b, string c);
void Get(vector <string>& str, string& a, string& b);
}
void A::Get(vector <string>& str, string& a, string& b)
{
str.erase(
std::remove_if (str.begin(), str.end(), BOOST_BIND(&A::OutOfRange, a, b, _1)),
str.end()
);
}
Run Code Online (Sandbox Code Playgroud)
我收到的错误如下:
Error 7 error C2825: 'F': must be a class or namespace when followed by '::' File:bind.hpp
Error 8 error C2039: 'result_type' : is not a member of '`global namespace'' t:\3rdparty\cpp\boost\boost-1.38.0\include\boost\bind.hpp 67
Run Code Online (Sandbox Code Playgroud)
有人能告诉我我做错了什么吗?
请考虑以下情形:
bool is_odd(int i)
{
return (i % 2) != 0;
}
int main()
{
// ignore the method of vector initialization below.
// assume C++11 is not to be used.
std::vector<int> v1 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::vector<int> v2 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
// removes all odd numbers, OK
v1.erase( std::remove_if(v1.begin(), v1.end(), is_odd), v1.end() );
// remove all even numbers
v2.erase( std::remove_if(v2.begin(), …Run Code Online (Sandbox Code Playgroud) 我有代码删除std::vector<int>少于一些的所有元素int limit.我写了一些部分应用lambdas的函数:
auto less_than_limit = [](int limit) {
return [=](int elem) {
return limit > elem;
};
};
auto less_than_three = less_than_limit(3);
Run Code Online (Sandbox Code Playgroud)
当我测试它时std::vector<int> v{1,2,3,4,5};,我得到了预期的结果:
for(auto e: v) {
std::cout << less_than_three(e) << " ";
}
// 1 1 0 0 0
Run Code Online (Sandbox Code Playgroud)
我可以轻松删除少于三个的所有元素:
auto remove_less_than_three = std::remove_if(std::begin(v), std::end(v), less_than_three);
v.erase(remove_less_than_three, v.end());
for(auto e: v) {
std::cout << e << " ";
}
// 3 4 5
Run Code Online (Sandbox Code Playgroud)
如何使用less_than_three?删除大于或等于3的元素?
我试过包装less_than_three中std::not1,却得到了错误:
/usr/local/Cellar/gcc/5.3.0/include/c++/5.3.0/bits/stl_function.h:742:11: …Run Code Online (Sandbox Code Playgroud) 我想基于索引删除向量的元素,比如所有偶数索引元素.我已经阅读了关于擦除删除习惯用法,但看不到如何应用它.这是我试过的:
vector<int> line;
line.reserve(10);
for(int i=0;i<10;++i)
{
line.push_back(i+1);
}
for(unsigned int i=0;i<line.size();++i)
{
//remove the even indexed elements
if(i%2 == 0)
{
remove(line.begin(),line.end(),line[i]);
}
}
line.erase( line.begin(),line.end() );
Run Code Online (Sandbox Code Playgroud)
这会擦除整个矢量.我希望只删除已删除算法标记的元素.
然后我尝试了这个
for(unsigned int i=0;i<line.size();++i)
{
//remove the even indexed elements
if(i%2 == 0)
{
line.erase( remove(line.begin(),line.end(),line[i]),line.end() );
}
}
Run Code Online (Sandbox Code Playgroud)
由于在移除时存在问题,这再次不起作用,索引似乎在迭代矢量时移位.应该采取什么样的正确方法来实现这一目标.
我的目标是尝试解决这个问题:从 end 中删除向量中的所有空元素。使用擦除删除成语。
这个想法是在给定std::vector<std::string>的字符串a中删除从末尾开始的所有元素,这些元素是空的(等于空白)。当发现非空元素时,应停止删除元素。
例子:
vec = { " ", "B", " ", "D", "E", " ", " ", " " };
Run Code Online (Sandbox Code Playgroud)
移除后:
vec = { " ", "B", " ", "D", "E"};
Run Code Online (Sandbox Code Playgroud)
这是我尝试的解决方案:
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <iterator>
int main()
{
std::vector<std::string> vec = { " ", "B", " ", "D", "E", " ", " ", " " };
bool notStop = true;
auto removeSpaceFromLast = [&](const std::string& …Run Code Online (Sandbox Code Playgroud) 我经常发现自己想要根据向量的索引而不是值来过滤向量。
auto some_values = std::vector{1, 0, 4, 6, 2};
// Somewhere I figure out which items to remove.
// This may be from user interaction or something
// nothing to do with the original values:
const auto removing = std::vector<bool>{0, 0, 1, 0, 1};
Run Code Online (Sandbox Code Playgroud)
erase_if所以,我很想像这样使用:
std::erase_if(some_values, [it = removing.begin()](auto) mutable {return *it++;});
Run Code Online (Sandbox Code Playgroud)
它似乎适用于 gcc 和 clang。但是, std::erase cppref 页面上似乎没有任何关于谓词调用顺序的内容,所以我认为这是未定义的行为?
与 相同的问题std::remove_if。请注意,压缩范围不适用于大多数压缩选项,因为通常生成的范围无法调整基础数据的大小。
使用 for 循环并创建数组的副本并不是太多的样板文件,但我目前正在将过滤器应用于一些低级代码,在这些代码中我无法复制所有数据。有些数据会很大,需要在这些过滤操作期间做出响应。
最坏的情况我可以添加这样的函数来解决问题:
template <class T, auto N, class Pred>
size_t …Run Code Online (Sandbox Code Playgroud) 当谈到从容器中删除多个元素时,C++ 中有一个“擦除-删除”习惯用法,并且有关于替代“调整大小-删除”方式的讨论,例如,此处。人们说“擦除删除”比“调整大小删除”更好,但根据我的测试,后者在矢量上(稍微)更快。那么,当涉及到矢量时我应该使用“调整大小删除”吗?
这是我的基准测试代码:
#include <benchmark/benchmark.h>
#include <algorithm>
#include <functional>
#include <iostream>
#include <random>
#include <vector>
using namespace std;
constexpr size_t N_ELEMS = 1000000;
constexpr int MAX_VAL = N_ELEMS / 10;
constexpr int THRESH = MAX_VAL / 5 * 3;
static vector<int> generate_input() {
vector<int> nums(N_ELEMS);
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dist(0, N_ELEMS);
std::generate(nums.begin(), nums.end(), std::bind(dist, std::ref(gen)));
return std::move(nums);
}
static void bm_erase_remove(benchmark::State &state) {
for (auto _ : state) {
state.PauseTiming();
auto nums = generate_input();
state.ResumeTiming();
nums.erase(std::remove_if(nums.begin(), …Run Code Online (Sandbox Code Playgroud) 我有一个成员为j,k和l的元组向量。我正在尝试适应“擦除删除”习惯用法,以便如果.k成员的值满足特定条件,则可以删除整个元组。
我尝试使用标准.erase(removeif())方法,其中谓词引用了元组成员位置,但被告知所涉及的向量类中没有成员“ k”。
vec_list_iter_exp_out.erase(
std::remove_if(
vec_list_iter_exp_out.begin(),
vec_list_iter_exp_out.end(),
vec_list_iter_exp_out.k < 33), vec_list_iter_exp_out.end());
Run Code Online (Sandbox Code Playgroud)
我希望如果vec_list_iter_exp_out由以下假设值组成:
vec_list_iter_exp_out[0] = 5, 22, 9
vec_list_iter_exp_out[1] = 12, 31, 54
vec_list_iter_exp_out[2] = 17, 42, 0
vec_list_iter_exp_out[3] = 253, 3, 5
vec_list_iter_exp_out[4] = 65, 110, 24
Run Code Online (Sandbox Code Playgroud)
vec_list_iter_exp_out [2]和vec_list_iter_exp_out [4]的全部将被删除,然后vec_list_iter_exp_out将包括以下内容:
vec_list_iter_exp_out[0] = 5, 22, 9
vec_list_iter_exp_out[1] = 12, 31, 54
vec_list_iter_exp_out[2] = 253, 3, 5
Run Code Online (Sandbox Code Playgroud)
相反,我得到了上述编译错误。
任何帮助将不胜感激!
编辑:根据要求定义所讨论的向量。
struct TriStore
{
double j,k,l;
};
std::vector<TriStore> vec_list_iter_exp_out;
Run Code Online (Sandbox Code Playgroud)
和用于插入的代码段(显然引用了其他功能和所拥有的功能,但这会占用太多空间)
for(int z = 1; z <= iters; z++)
{
vec_iters.push_back(vec_list_iter_exp_out.size());
for(int i = …Run Code Online (Sandbox Code Playgroud)