c++ - 为什么在带有向量c ++的for循环结束时会发生这种情况
问题描述
我想擦除向量中的重复元素;我使用for
循环来检查向量中的下一个元素是否与迭代中的当前元素相同,如果为真则将其删除,但由于某种原因,它会删除最后一个元素而不相等。
这是我的代码:
#include <string>
#include <vector>
#include <iostream>
using namespace std;
template <typename T> vector<T> uniqueInOrder(const vector<T>& iterable){
vector<T> coolestVector = iterable;
for (int i = 0; i < coolestVector.size(); i++)
{
if (coolestVector[i] == coolestVector[i+1]){
coolestVector.erase(coolestVector.begin()+i);
i--;
}
/*for (int i = 0; i < coolestVector.size(); i++)
{
cout<<coolestVector[i]<<", ";
}
cout<<i<<", ";
cout<<coolestVector.size();
cout<<endl;*/
}
for (int i = 0; i < coolestVector.size(); i++)
{
cout<<coolestVector[i]<<endl;
}
return coolestVector;
}
vector<char> uniqueInOrder(const string& iterable){
vector<char> coolVector = {};
for (int i = 0; i < iterable.size(); i++)
{
coolVector.push_back(iterable[i]);
}
const vector<char> realVector = coolVector;
uniqueInOrder(realVector);
}
int main(){
const string test = "AAAABBBCCDAABBB";
uniqueInOrder(test);
}
输出:
vector 0: A, A, A, B, B, B, C, C, D, A, A, B, B, B, iterator value -1, vector size 14
vector 0: A, A, B, B, B, C, C, D, A, A, B, B, B, iterator value -1, vector size 13
vector 0: A, B, B, B, C, C, D, A, A, B, B, B, iterator value -1, vector size 12
vector 1: A, B, B, B, C, C, D, A, A, B, B, B, iterator value 0, vector size 12
vector 1: A, B, B, C, C, D, A, A, B, B, B, iterator value 0, vector size 11
vector 1: A, B, C, C, D, A, A, B, B, B, iterator value 0, vector size 10
vector 2: A, B, C, C, D, A, A, B, B, B, iterator value 1, vector size 10
vector 2: A, B, C, D, A, A, B, B, B, iterator value 1, vector size 9
vector 3: A, B, C, D, A, A, B, B, B, iterator value 2, vector size 9
vector 4: A, B, C, D, A, A, B, B, B, iterator value 3, vector size 9
vector 4: A, B, C, D, A, B, B, B, iterator value 3, vector size 8
vector 5: A, B, C, D, A, B, B, B, iterator value 4, vector size 8
vector 5: A, B, C, D, A, B, B, iterator value 4, vector size 7
vector 5: A, B, C, D, A, B, iterator value 4, vector size 6
vector 5: A, B, C, D, A, iterator value 4, vector size 5
A
B
C
D
A
预期的:
A
B
C
D
A
B
解决方案
我已将此与我之前的答案分开,因为之前的答案可以独立存在,我不希望它卷入因解释未定义行为而引起的潜在争议。
为什么程序总是删除最后一个元素?
正式地说,我们处于未定义行为的领域,所以一切皆有可能。但是,这种行为很可能会出现在所有发布版本中,但有两个警告。
- 删除了较早的元素。如果不应该删除任何元素(一个值得添加到测试套件的案例),那么行为是不可预测的,可能是崩溃,但很可能是预期的行为。
- 移动构造留下一个副本。对于像
char
. 对于 的向量,您可能不会看到这种行为std::string
。
当 a 中间的一个元素std::vector
被擦除时,该元素之后的所有元素都会向下移动一个索引;它们被复制(或移动)到前面的元素。
A B B C D
^
|-- erase this
A B B C D
^ ^ ^ <--- shift and copy (or move)
B C D
A B C D D
^
|-- Last element in the vector
请注意,擦除时不会释放空间。向量仍然拥有以前的内存D
;只是从向量实现之外访问元素是未定义的行为。此外,该内存不太可能在发布版本中通过向量更改其位。因此,向量的末尾很可能是向量最后一个元素的副本,除非移动构造函数更改了它。
现在来了你的条件。当i
is时coolestVector.size()-1
,您检查向量 ( ) 的最后一个元素是否coolestVector[i]
等于向量 ( ) 末尾之后的元素coolestVector[i+1]
。发布版本不会验证索引是否有效,并且操作系统不关心内存中的该位置是否被访问,因此这种比较很可能会像人们天真地期望的那样进行。向量的最后一个元素是否等于复制它的对象?是的!OK,删除最后一个元素。
很可能在发布版本中,但不要依赖它。
推荐阅读
- powershell - Update-Module 未在脚本中将 PSGallery 存储库作为计划任务找到
- python - 如何将字符串评估为变量名
- imageview - 在 ARCore 中显示来自网络的图像
- excel - 删除重复项,在不同列中保持最低值
- c - 为什么提供 1 个元素后 C 程序停止执行?
- r - Any pattern of same length that isn't the pattern desired
- javascript - 计算输入字段的总数并显示每个输入字段的百分比
- java - Write big files using RandomAccessFile class
- javascript - 在文本框上更改输入时调用函数?
- r - Image processing: Average grayscale images