问题描述
[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++;
}
}