给定一个未排序的数组,如何删除重复项然后对其进行排序?
Posted
技术标签:
【中文标题】给定一个未排序的数组,如何删除重复项然后对其进行排序?【英文标题】:Given an unsorted array, how to remove duplicates then sort it? 【发布时间】:2020-10-30 15:53:07 【问题描述】:我遇到了麻烦,你能帮帮我吗?
我成功删除了重复项,然后我使用冒泡排序对其进行排序,但效率低下。
如何删除重复项然后对其进行排序?使用2个功能不能带来我想要的。
#include <stdio.h>
#include <conio.h>
int arr[100];
int n;
void RemoveDuplicate(int arr[]);
void Print(int arr[]);
int main()
int i;
printf("Enter n:");
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&arr[i]);
RemoveDuplicate(arr);
Print(arr);
getch();
return 0;
void Print(int arr[])
int i;
for(i=0;i<n;i++)
printf("%d ",arr[i]);
void RemoveDuplicate(int arr[])
int i,j,k;
for(i=0;i<n;i++)
for(j=i+1;j<n;)
if(arr[i]==arr[j])
for(k=j;k<n;k++)
arr[k]=arr[k+1];
n--;
else
j++;
【问题讨论】:
翻转操作。排序,然后删除重复项。让它更容易。 提示:通常以相反的方向进行:首先对序列进行排序,而不是删除重复项。删除未排序序列中的重复项很痛苦。 C 还是 C++?请选择一个。 您可以在排序时删除重复项。如果你进行堆排序,你可以比较从堆中弹出的项与数组的已排序部分中的前一项,如果它与前一项匹配,则丢弃新值。 在 C++ 中,您可以使用std::set
容器来存储唯一项
【参考方案1】:
所有示例均未经测试,并以以下内容开头
if (n<1 || n > sizeof(arr))
return;
auto begin = std::begin(arr);
auto end = begin+n;
使用 std::set
std::set<int> unique(begin, end);
std::copy(unique.begin(), unique.end(), std::begin(arr));
int size = unique.size();
使用堆
std::make_heap(begin, end);
std::sort_heap(begin, end);
auto last = std::unique(begin, end);
auto size = std::distance(begin, last);
只使用 std::sort 而不是 sort_heap
std::sort(begin, end);
auto last = std::unique(begin, end);
auto size = std::distance(begin, last);
使用堆和手动弹出
std::make_heap(std::begin(arr), std::end(arr));
auto first = begin;
auto last = end;
auto sorted = std::prev(last);
std::pop_heap(first, last--); // initial value
while (first != last)
std::pop_heap(first, last--);
if (*last != *sorted && last != sorted)
*--sorted = *last;
auto size = std::distance(sorted, end);
std::copy(sorted, end, begin); // move values to start of array
条件
last != sorted
在第一次复制之前为假,之后为真,因此可以将循环分成两部分以获得更好的性能,但分支预测器应该因此消除大多数性能问题。
如果唯一值的数量很小且分布范围很小,并且“n”很大,则使用计数数组。
std::vector 文本的字符计数示例;
std::array<int,256> count;
std::vector<char> result;
for (auto ch : text)
count[ch]++;
for (auto idx = 0; idx < count.size(); ++idx)
if (count[idx])
result.emplace_back(idx);
如果重复的数量较大但值分散,请考虑使用 std::unordered_set 代替并在末尾排序。
std::unordered:set<int> unique(begin, end);
std::copy(unique.begin(), unique.end(), std::begin(arr));
int size = unique.size();
std::sort(begin, begin+size);
【讨论】:
以上是关于给定一个未排序的数组,如何删除重复项然后对其进行排序?的主要内容,如果未能解决你的问题,请参考以下文章