C++ 如何从向量中删除第一次出现的值?

C++ 如何从向量中删除第一次出现的值?,c++,c++11,C++,C++11,我试图从一个向量中得到一个元素,把它推到向量的后面,然后删除它,这样我的内存中就不会有一个空的部分。擦除-删除习惯用法可以做到这一点,但它会删除特定值的所有实例。我只想去掉第一个 我对标准库算法没有太多经验,我找不到合适的方法(如果有的话)来实现这一点。以下是一个例子: int main() { std::vector<int> v{1, 2, 3, 3, 4}; remove_first(v, 3); std::cout << v; // 1

我试图从一个向量中得到一个元素,把它推到向量的后面,然后删除它,这样我的内存中就不会有一个空的部分。擦除-删除习惯用法可以做到这一点,但它会删除特定值的所有实例。我只想去掉第一个

我对标准库算法没有太多经验,我找不到合适的方法(如果有的话)来实现这一点。以下是一个例子:

int main() {
    std::vector<int> v{1, 2, 3, 3, 4};

    remove_first(v, 3);

    std::cout << v; // 1, 2, 3, 4
}
intmain(){
std::向量v{1,2,3,3,4};
首先移除_(v,3);

std::cout首先找到它,然后将其删除:

auto it = std::find(v.begin(),v.end(),3);
// check that there actually is a 3 in our vector
if (it != v.end()) {
  v.erase(it);
}

先找到它,然后删除它:

auto it = std::find(v.begin(),v.end(),3);
// check that there actually is a 3 in our vector
if (it != v.end()) {
  v.erase(it);
}

如果不关心保持向量中元素的顺序,可以避免在擦除时复制剩余元素的“尾部”:

auto it = std::find(v.begin(), v.end(), 3);
if (it != v.end()) {
  std::iter_swap(it, v.end() - 1);
  v.erase(v.end() - 1);
}

如果不关心保持向量中元素的顺序,可以避免在擦除时复制剩余元素的“尾部”:

auto it = std::find(v.begin(), v.end(), 3);
if (it != v.end()) {
  std::iter_swap(it, v.end() - 1);
  v.erase(v.end() - 1);
}

注意:从向量中删除一个元素很糟糕。删除元素后的所有元素都需要复制回1个元素。从
列表中删除
非常困难cheaper@Dave是的,但是数据结构的选择取决于更多。如果擦除很多,这是一个问题,但通常只擦除几次,但访问索引元素l时间,这对列表来说很糟糕。@Dave:事实上,可能不是。列表不能很好地与缓存配合使用。你可以让它们与缓存配合使用,但这并不比使用矢量更容易,除非评测要求这样做。从列表中擦除是O(1),但在列表中查找元素是O(n)。组合的查找/擦除操作是O(n)对于vector和list,正如我们所知,vector的常数往往比list的常数小得多。注意:从vector中删除元素很糟糕。删除元素后的所有元素都需要复制回1个元素。从
列表中删除
非常困难cheaper@Dave没错,但数据结构的选择取决于那就是。如果你擦除很多,这是一个问题,但通常你只擦除几次,但总是访问索引元素,这对列表来说很糟糕。@Dave:实际上可能不是。列表不能很好地与缓存配合使用。你可以让它们与缓存配合使用,但在评测要求不这样做之前,使用vector并不容易。从列表中擦除是O(1) ,但在列表中查找元素是O(n)。对于vector和list两者,组合查找/擦除操作是O(n)-正如我们所知,vector的常数往往比list的常数小得多。find(v.begin(),v.end(),3)有什么问题然后删除迭代器?你关心
向量
中元素的顺序吗?如果不关心,
交换
-
删除
效果很好。@Yakk我喜欢这个主意(也许把它作为一个答案添加进来?),但我想既然OP问如何删除容器中的前3个元素,他有点关心顺序:)@us2012假设问题是询问此人需要知道什么。例如,他们可能不在乎这是否是第一个,但他们只想删除其中的一个。“只删除第一个”如果他们不知道不关心顺序会让他们的问题变得更容易,他们可能不知道这很重要他们不关心…@us2012不,我是说第一个数字是3。你知道我说的是什么意思吗?我不是说前三个元素。find(v.begin(),v.end(),3)有什么问题吗然后删除那个迭代器?你关心
向量中元素的顺序吗?如果不关心,
交换
-
删除
效果很好。@Yakk我喜欢这个主意(也许可以把它作为答案添加进来?),但我认为,由于OP询问如何删除其容器中的前3个,他确实关心顺序:)@us2012,假设问题是询问此人需要知道什么。例如,他们可能不关心是否是第一个,但他们只想删除其中1个。“仅删除第一个”如果他们不知道不关心顺序会让他们的问题变得更容易,他们可能不知道这很重要他们不关心…@us2012不,我是说第一个数字是3。你知道我说的是什么意思吗?我不是指前三个元素。很好的解决方案:-)因为我只想删除第一个出现的数字因为我的向量不包含重复项,所以我不喜欢std::forward_list::remove。在我看来,这是目前最好的解决方案。很好的解决方案:-)因为我的向量不包含重复项,所以我只想删除元素的第一个匹配项,所以我不喜欢std::forward_list::remove。在我看来,这是目前最好的解决方案。