从 C++ 中的排序数组中删除重复项
Posted
技术标签:
【中文标题】从 C++ 中的排序数组中删除重复项【英文标题】:Removing duplicates from a sorted array in c++ 【发布时间】:2021-12-12 01:54:47 【问题描述】:我正在尝试从已排序的数组中删除重复项。代码为一个测试用例提供了正确的输出,但未能为多个测试用例提供正确的输出。我用其他方法得到了正确的输出,但这种方法有什么问题?我该如何解决这个问题?
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
int main()
// your code goes here
int t;
cin>>t;
while(t--)
int n;
cin>>n;
int a[n],i,k,temp,count;
for(i=0;i<n;i++)
cin>>a[i];
sort(a,a+n);
count=0;
for(i=0;i<n;i++)
if(a[i-1]-a[i]==0)
temp = a[i];
count++;
for(k=i;k<n;k++)
a[k] = a[k+1];
for(i=0;i<n-count;i++)
cout<<a[i]<<" ";
cout<<endl;
【问题讨论】:
我在 3 次罢工后停止阅读:#include<bits/stdc++.h>
然后using namespace std;
最后是int a[n]
。请考虑从介绍性 C++ 书籍开始,而不是使用hackerrank 或 leetcode 学习编码
Why should I not #include <bits/stdc++.h>? 和 Why is “using namespace std;” considered bad practice?
我认为新的打击应该是那些发布代码的人,其输出依赖于 std::cin 的输入。基本上,如果您想从 SO 那里得到答案,则永远没有充分的理由发布使用 std::cin 的代码,除非您的问题与 std::cin 有关。
en.cppreference.com/w/cpp/algorithm/unique
Why aren't variable-length arrays part of the C++ standard?
【参考方案1】:
这样的变长数组
int a[n],i,k,temp,count;
不是标准的 C++ 功能。相反,您应该使用标准容器std::vector<int>
。
这个 if 语句
if(a[i-1]-a[i]==0)
由于表达式 a[i-1]
而在 i
等于 0
时调用未定义的行为。
这个for循环也存在同样的问题
for(k=i;k<n;k++)
a[k] = a[k+1];
当k
等于n - 1
由于表达式a[k+1]
。
此外,每次找到重复元素后复制所有元素的效率也很低。
请注意,可以使用标准算法std::unique
代替您的循环。
如果要使用 for 循环,那么您可以实现类似以下的内容
#include <iostream>
int main()
int a[] = 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5 ;
const size_t N = sizeof( a ) / sizeof( *a );
size_t n = 0;
for ( size_t i = 0; i < N; i++ )
if ( i == 0 || a[i] != a[n-1] )
if ( i != n ) a[n] = a[i];
++n;
for ( size_t i = 0; i < n; i++ )
std::cout << a[i] << ' ';
std::cout << '\n';
return 0;
程序输出是
1 2 3 4 5
如果使用标准算法std::unique
,那么解决方案会更简单,因为不需要自己编写for循环。
#include <iostream>
#include <iterator>
#include <algorithm>
int main()
int a[] = 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5 ;
auto last = std::unique( std::begin( a ), std::end( a ) );
for ( auto first = std::begin( a ); first != last; ++first )
std::cout << *first << ' ';
std::cout << '\n';
return 0;
程序输出和上图一样就是
1 2 3 4 5
【讨论】:
【参考方案2】:我发现您的代码有两个主要问题,都是从数组中越界读取:
if(a[i-1]-a[i]==0)
将在某一时刻被i==0
调用,访问元素a[-1]
。
这里:
for(k=i;k<n;k++)
a[k] = a[k+1];
在最后一次循环迭代中,当k == n-1
数组元素a[n]
被访问时,也是越界访问。
【讨论】:
以上是关于从 C++ 中的排序数组中删除重复项的主要内容,如果未能解决你的问题,请参考以下文章