从 C++ 中的数组中删除重复项 [关闭]
Posted
技术标签:
【中文标题】从 C++ 中的数组中删除重复项 [关闭]【英文标题】:Delete Duplicates from Array in C++ [closed] 【发布时间】:2020-10-14 03:45:10 【问题描述】:我正在尝试编写一个程序来删除数组中的所有重复值而不更改值的顺序。输出应如下所示:
5 3 7 1 7 7 2 3 5 5
5 3 7 1 2
但是在我的程序中,其重复值已被删除的新数组不会打印。
这是我的代码:
#include <iostream>
using namespace std;
int unique(int array[], int n)
if (n==0 || n==1)
return n;
int temp[n];
int j = 0;
int i = 0;
for(i = 0; i < n -1; i++)
if (array[i] != array[i+1])
temp[j++] = array[i];
temp[j++] = array[n-1];
for(i = 0; i < j; i++)
array[i] = temp[i];
return j;
int main()
int array[10];
int n, i;
for(int i = 0; i < 10; i++)
cin >> array[i];
int size = unique(array, n);
if(size < 0 || size > 10)
return -1;
for(int size = 0; i < size; i++)
cout << array[i] << " ";
cout << endl;
return 0;
编辑:在收到有关约束和数组大小的一些建议后,我重新编写了代码。我还取消了 temp
的使用,因为它不是正确的 C++。这是新代码:
#include <iostream>
using namespace std;
int unique(int array[])
int size = 10;
int i, j, k;
for(i = 0; i < size; ++i)
for(j = i + 1; j <size;)
if(array[i]==array[j])
for( k = j; k<size-1;++k)
array[k]=array[k+1];
--size;
else
++j;
return size;
int main()
int array[10];
for(int i = 0; i < 10; i++)
cin >> array[i];
int size = unique(array);
if(size < 0 || size > 10)
return -1;
for(int i = 0; i < size; i++)
cout << array[i] << " ";
cout << endl;
return 0;
【问题讨论】:
if (array[i] != array[i+1])
-- 如果数字不相邻,这将如何检测重复项?我认为您需要重新考虑逻辑,并且可能使用不同的数据结构来“记住”已经看到的值。例如:[8 1 2 3 4 5 8]
-- 你将如何检测 8
是重复的?
@PaulMcKenzie 即使数字彼此相邻,它也不会打印任何内容,但您是对的。由于我是初学者,还不知道std::vector<int> temp(n)
怎么用。
使用 std::vector
是您在 C++ 中处理动态数组的方式。第二件事是你的逻辑是错误的——你从unique
返回的值决定了要打印多少(size
变量)。为什么不打印出unique
的返回值,看看会打印多少?如果它是 0 或更少,请不要感到惊讶。所以你需要先让unique
的逻辑工作。此外,C++ 初学者不会遇到这些类型的问题——这听起来像是来自在线编码网站之一的问题。
@PaulMcKenzie 你是对的,当我直接打印unique
返回的内容时,它打印出零。
for(int size = 0; i < size; i++)
-- 另外,请仔细看看这一行。你看出什么不对了吗?此外,它只有 10 个数字,还是数组可以是任意大小?数字的最大数量是多少?
【参考方案1】:
首先从数组中删除元素意味着它需要调整大小,因此最好使用向量。
基本思路是这样的
-
将您看到的值存储在某种数据结构中,称为映射。在 C++ 中 std::unordered_map 使用哈希表,因此搜索和插入是 O(1)
逐个元素扫描向量
在地图中查找该元素,如果存在则删除该元素
否则将元素添加到映射并继续到下一个元素
C++ implementation
编辑:
正如 PaulMckenzie 建议的那样,最好使用 std::unordered_set 在这种情况下是正确的,因为在这种情况下不需要值,只有键
【讨论】:
最好使用std::unordered_set
。
@PaulMcKenzie 你说得对,我刚刚编辑了帖子。
@PaulMcKenzie 但是unordered_set
也不会保持元素的原始顺序。
该集合不会用于维护订单。它将被简单地用作确定已经看到的内容的一种方式。 See this【参考方案2】:
您应该使用std::vector
而不是数组,或者如果您在编译时知道元素的数量,请使用std::array
。这是适用于数组或任何 STL 容器的解决方案(稍作语法修改,即使用 std::begin
和 std::end
):
int unique(int *arr, int n)
auto end = arr + n;
for (auto begin = arr; begin != end; ++begin)
end = std::remove(begin + 1, end, *begin);
return end - arr;
【讨论】:
以上是关于从 C++ 中的数组中删除重复项 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章