在保留顺序函数的同时删除向量中的重复项的逻辑错误
Posted
技术标签:
【中文标题】在保留顺序函数的同时删除向量中的重复项的逻辑错误【英文标题】:Logic error in remove duplicates in a vector while preserving the order function 【发布时间】:2021-09-24 08:10:54 【问题描述】:void vectorDeduplicator(std::vector<std::string>& inputVector)
for(int i = 0; i < inputVector.size() - 1; i++)
for(int x = 1; x <= inputVector.size() - 1; x++)
if(inputVector.at(i) == inputVector.at(x) && i != x)
inputVector.erase(inputVector.begin() + x);
Input: 1 1 2 2 4 4 3 3 1 1 3 3 3 2 2
Output: [1,2,4,1,3,2]
您可以看到我试图用来删除 vector 内的重复项的函数。它在重复项相邻时起作用。我不想在不知道标准库或其他任何东西中已经存在的任何东西的情况下使用更快、更有效的方法。我想学习它背后的算法,因为这是出于学习目的。
【问题讨论】:
填充一个临时向量,然后将临时向量复制回原始向量。无需进行所有擦除。如果向量有数千个元素怎么办?每次擦除时,向量都必须缩小一。使用一些逻辑来填充临时向量。x <= inputVector.size() - 1
是x < inputVector.size()
的复杂表达方式。
如果你需要一个明确没有重复的容器,你也可以使用 std::set
@PaulMcKenzie 如果我理解正确,您是说我应该填充另一个向量,遍历第一个向量以排除重复项,然后将其复制回原始向量。我对吗?如果我这样做,它不会再次将重复项复制到临时向量如果我的算法有缺陷吗?
@ool123 -- 我的意思是扫描原始数组,然后使用一点逻辑 用非重复值填充临时数组。换句话说,你的方法应该改变——它在我提到的方式中是有缺陷的。在纸上算出来——创建原始向量,并用唯一的项目“构建”临时向量。
【参考方案1】:
问题是您在擦除时忽略了一个值。你需要减少 x:
#include <vector>
#include <iostream>
void vectorDeduplicator(std::vector<int>& inputVector)
for(int i = 0; i < inputVector.size() - 1; i++)
for(int x = 1; x < inputVector.size(); x++)
if(inputVector.at(i) == inputVector.at(x) && i != x)
inputVector.erase(inputVector.begin() + x);
x--; // go one back because you erased one value
// to debug
for(const auto& x : inputVector)
std::cout << x << " ";
std::cout << std::endl;
int main()
std::vector<int> vector1, 1, 2, 2, 4, 4, 3, 3, 1, 1, 3, 3, 3, 2, 2;
vectorDeduplicator(vector);
// output
for(const auto& x : vector)
std::cout << x << " ";
return 0;
那么输出是:
1 2 2 4 4 3 3 3 3 3 2 2
1 2 4 4 3 3 3 3 3
1 2 4 3 3 3 3 3
1 2 4 3
1 2 4 3
【讨论】:
@463035818_is_not_a_number 无论如何,它不会保持积极吗?因为每次减少 x 时,也会增加 x。所以 x 总是大于 0 此外,减少无符号数并没有错。 @bipll d'oh right。我很困惑。这里没有问题。我将删除 cmets以上是关于在保留顺序函数的同时删除向量中的重复项的逻辑错误的主要内容,如果未能解决你的问题,请参考以下文章
如何删除列表中重复的构造对象,同时保留顺序并在飞镖中返回列表?