标签: std

在保留原始顺序的同时擦除/删除多个std :: vector元素的最有效方法?


我有一个std::vector<int>和第二个容器持有迭代器或索引(没有键,我希望不断访问元素)到这个向量用于删除目的.让我们假设我有一个1000个元素的向量,并想要删除其中的200个元素.在删除操作之后,未删除元素的顺序应该与之前相同.

我在问题的第一个版本中错过了另一件事:价值观是独一无二的.他们是身份.

你如何在安全(关于stl规则)和有效方式(传统的决定是最终的)中做到这一点?

我想到的可能性方法:

  • 所述擦除remove惯用法(http://en.wikipedia.org/wiki/Erase-remove_idiom):最初为其中满足条件(包括直链的搜索)的元素的删除,但我认为有尺寸1这种方法可能是范围习惯于已经给定的迭代器和虚拟条件.问题:保留的元素的原始顺序是否比最后一种方法更高效?
  • 循环遍历索引并使用vector.erase(vector.begin()+index+offset)同时删除元素,同时保持在容器中删除索引以计算偏移量.可以使用std::lower_bound已经移除的元素的容器来确定每次移除迭代的该偏移.问题:由于随机位置删除,很多binary_searches用于获取偏移量和大量移动操作.
  • 目前我正在做以下事情:获取要删除的元素的所有迭代器.根据向量中的位置按降序对它们进行排序,并在它们上面循环以进行最终删除vector.erase.现在我没有使任何迭代器失效,除了删除本身之外没有向量重新排列操作.问题:很多排序

那么,你会如何解决这个问题呢?有什么新想法吗?有什么建议?

感谢您的输入.

萨沙

编辑/更新/拥有结果:我实现了擦除 - 删除习惯用法,这也是KennyTM提到的,带有一个基于boost :: dynamic_bitset中的查找谓词,并且它的速度非常快.此外,我尝试了PigBen的move-and-truncate方法(也由Steve Jessop提到),它也在它的while循环中访问bitset.对我的数据来说,两者似乎同样快.我试图删除100个1000个元素(无符号整数)中的100个,这100个删除了1M次并且没有显着差异.因为我认为基于stl的擦除删除成语更"天生",我选择了这种方法(KennyTM也提到了参数).

c++ algorithm performance stl std

16
推荐指数
2
解决办法
2万
查看次数

std :: vector差异

如何确定2个向量的差异是什么?

我有vector<int> v1vector<int> v2;

我正在寻找的是vector<int> vDifferences仅包含仅在v1或中的元素v2.

有没有标准的方法来做到这一点?

c++ std

16
推荐指数
1
解决办法
1万
查看次数

C++:"vector <int> :: size_type variable" - 以这种方式声明的重点是什么?

我认为这是一个非常基本的问题,但我无法弄明白.

我习惯于在C++中使用数组,但我现在开始学习矢量.我正在制作一个测试代码,我遇到了一个问题.

首先,这是我制作的代码:

#include <iostream>
#include <vector>
#include <numeric>
using namespace std;

int main(){
  vector<double> score(10);

  for(vector<double>::size_type i=0;i<20;i++) {
    cout<<"Enter marks for student #"<<i+1<<":"<<flush;
    cin>>score[i];
  }

  double total = accumulate(score.begin(), score.end(),0);

  cout<<"Total score:"<<total<<endl<<"Average score:"<<total/score.size()<<flush;

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

for第9行的句子中,我宣称i是一种vector<double>::size_type类型(因为我被告知要这样做).我测试了上面用上面所说的类型取代的代码int,它工作得非常好.为什么比较vector<double>::size_type优先int

c++ types vector std

16
推荐指数
2
解决办法
2452
查看次数

c ++ 20 std::integral_constant?

我刚刚进入元编程,正在 youtube 上观看 Cppcon 频道,看到了这个std::integral_constant,但找不到它的用途。

据我所知,这是一种将值与其类型一起“打包”的方法,它可以用

std::integral_constant<int, 42> i;
std::integral_constant<bool, true> b;
std::integral_constant<float, 3.14> f;
...
Run Code Online (Sandbox Code Playgroud)

并且这些实例中的每一个都可以像它们包含的值一样使用,即:可以传递、用于数学运算、比较等。

但是我不明白为什么我应该使用这些结构而不是实际包含的值,也不明白我是否可以在运行时实际访问值类型(即:intboolfloat)来处理它。

有人可以提供一个实际使用此功能的简单示例吗?一个解释它的用法与使用实际值的区别的例子?

c++ std

16
推荐指数
1
解决办法
591
查看次数

C++ std :: queue :: pop()调用析构函数.指针类型是什么?

我有一个std::queue被包装为模板化的类来创建一个线程安全的队列.我有这个类的两个版本:一个存储值类型,一个存储指针类型.

对于指针类型,我在销毁时删除队列的元素时遇到问题.原因是我不知道如何安全地从队列中删除项目.

参考状态(无思考力的,所以我想它实际上并没有状态的话)是从队列中删除元素的唯一方法是调用pop().该引用还表示pop()调用该项的析构函数.

好吧,这会导致我的指针类型出现问题,因为它们可能会或可能不会指向聚合.如果其中一个指向聚合,它们都会,但由于包装是模板化的,因此无法保证我们正在处理哪种类型(聚合或非聚合).

那么,当pop()调用析构函数时,会发生什么?如何确保删除所有内容并正确释放内存?

最后,我的解决方案是使用旧版本的GCC for ARM9.我无法控制这一点.我知道有些库有智能指针和容器可以在这里提供帮助,但它们对我来说是禁止的.

c++ queue memory-management std

15
推荐指数
3
解决办法
3万
查看次数

为什么std :: type_info不可复制?我可以把它存放在某个地方吗?

std::type_info课程不可复制.这使得将其存储在对象中以供以后使用变得困难.我该怎么办?

c++ std typeid typeinfo

15
推荐指数
2
解决办法
2587
查看次数

libstdc ++不实现std :: stoi吗?

我想用std::stoi.虽然我可以使用::atoi(str.c_str())它会使代码更清洁,如果这将工作.但Eclipse告诉我:

函数'stoi'无法解决

我查了一下

  • 标题<string>包括在内,
  • 包含路径设置正确,我可以使用std::string,
  • 编译器标志-std=c++0x -std=c++11也是设置的.

stoi()失踪的gcc,或者是不知何故我的错?

我正在使用gcc(Debian 4.7.2-4)4.7.2.

c++ gcc std c++11

15
推荐指数
2
解决办法
9498
查看次数

什么是scanf格式输入的cin analougus?

通过scanf,通常可以直接获取格式化输入:

1)具有大于0且小于1的实数的行.在'x'上结束,例如:0.32432523x

scanf("0.%[0-9]x", &number);
Run Code Online (Sandbox Code Playgroud)

2)line代表格式的加法:30 + 28 =五十八

scanf(":%d+%d=%99s", &number1, &number2, &total);
Run Code Online (Sandbox Code Playgroud)

什么是cin解决方案,只使用标准库?

c++ input std

15
推荐指数
2
解决办法
7152
查看次数

'sqrt'不是'std'的成员

我在linux中编译我的程序 - 它有以下几行:

std::sqrt((double)num);
Run Code Online (Sandbox Code Playgroud)

在Windows上没关系,但是在linux上我得到'sqrt'不是'std'的成员我有一个包括math.h

有什么问题吗?

c++ math std sqrt

15
推荐指数
2
解决办法
3万
查看次数

Barebones C++没有标准库?

GCC和Clang等编译器允许在没有C++标准库的情况下编译C++程序,例如使用-nostdlib命令行标志.似乎这种情况经常无法与您联系,例如:

void f() noexcept { throw 42; }
int main() { f(); }
Run Code Online (Sandbox Code Playgroud)

通常无法链接由于像未定义的符号__cxa_allocate_exception,typeinfo for int,__cxa_throw,__gxx_personality_v0,__clang_call_terminate,__cxa_begin_catch,std::terminate()等.

即使是简单的

int main() {}
Run Code Online (Sandbox Code Playgroud)

无法链接

ld:警告:找不到输入符号_start; 默认为0000000000400120

并在执行时被操作系统杀死.使用-c编译器仍会运行显式失败的链接器:

LD:错误mytest(.eh_frame); 不会.eh_frame_hdr创建任何表.

在不使用和链接到标准库的情况下编程和编译C++应用程序或库是否是一个现实的目标?如何在Linux上使用GCC或Clang编译我的代码?没有标准库,哪些核心语言功能无法使用?

c++ std

15
推荐指数
2
解决办法
4150
查看次数

标签 统计

c++ ×10

std ×10

algorithm ×1

c++11 ×1

gcc ×1

input ×1

math ×1

memory-management ×1

performance ×1

queue ×1

sqrt ×1

stl ×1

typeid ×1

typeinfo ×1

types ×1

vector ×1