如何将迭代器值与整数进行比较?

问题描述

[2021 年 3 月 1 日编辑]谢谢大家!问题已经解决了:)

函数 <img src="/images/phatdeptrai.jpg" style="width: 28px;border-radius: 50%;float: left;clear: both;margin-left: 7px;margin-right: 7px;position: relative;top: 38px;"> <div style="float: left;max-width: 45%;"> <div style="font-size: .6875rem;color: #65676b;margin-left: 13px;margin-top: 10px;">Hoàng Phát đẹp trai</div> <div style="margin-top: 2px;"> <span style="display: inline-block; padding: 7px 10px 7px 10px; color: black; background-color: #e4e6eb;border-radius: 20px;"> sas</span> </div> 旨在删除除第一个元素之外等于 removeAll(vector<int>& v,const int& x) 的所有元素。

例如

int x

但是我的代码似乎无法比较originally v = [2,2,3,5,6,8,6] after removeAll(v,2) the output should be [2,6] ,所以有人知道原因吗?我在网上没有找到任何类似的问题。

if (*it == x)

解决方法

你想要的是这个:

void remove_duplicates_of(std::vector<int>& v,int value)
{
    auto it = std::find(v.begin(),v.end(),value);
    if (it != v.end())
        v.erase(std::remove(std::next(it),value),v.end());
}

这将找到 value 的第一个实例,如果找到,则擦除从紧接发现点之后的迭代器位置开始的每个后续实例。

,

当你删除一个迭代器时,它就会失效。最好的方法是使用标准算法,如 another answer 所示。问题是,从向量中间删除元素是昂贵的。每次调用它时,它都会将该位置之后的所有元素移动 1 个元素。最好在一次迭代中移动所有元素,然后删除最后剩下的元素。从末端移除元素相对便宜。以下是在没有标准算法的情况下如何做到这一点的粗略方法:

void remove_duplicates_of(std::vector<int>& v,int x) {
  auto it = v.begin();
  auto last = v.end();

  while (it != last && *it != x) ++it;  // find the first one

  if (it == last) return;  // if we didn't find anything,return

  ++it;                                 // skip the first
  while (it != last && *it != x) ++it;  // find the second

  if (it == last) return;  // if we didn't find anything,return

  auto next = it;
  while (++it != last)  // shift all other elements to front
    if (*it != x) *next++ = *it;

  // remove the rest
  v.erase(next,last);
}
,

有几个问题:

  • count 必须在循环外声明,否则在每次迭代时都会重置为 0

  • it 仅在您选择不擦除元素时才必须递增。

  • 当你擦除一个元素时,erase 的返回值应该赋值给 it。 (不这样做会正式导致 UB,但实际上可能不会破坏任何东西,如果您使用的是 std::vector。但它不适用于大多数其他容器。)

这是固定代码:

void removeAll(vector<int>& v,const int& x)
{
    int count = 0;
    for (vector<int>::iterator it = v.begin(); it < v.end();)
    {
        if (*it == x)
        {
            count++;
        }

        if (*it == x && count > 1)
        {
            it = v.erase(it);
        }
        else
        {
            it++;
        }
    }
}

这里是相同的代码,但在样式上有细微的改进:

void removeAll(std::vector<int> &v,int x)
{
    std::size_t count = 0;
    for (auto it = v.begin(); it < v.end();)
    {
        if (*it == x && count++ != 0)
            it = v.erase(it);
        else 
            it++;
    }
}