数组-消除所有重复的C++

Array - Eliminate all duplicates C++

本文关键字:C++ 数组      更新时间:2023-10-16

我有以下数组

a[0]=4, a[1]=6, a[2]=9, a[3]=4, a[4]=4 ...

我想从数组中消除所有重复的值并打印数组。因此阵列4 6 9 4 4将变为4 6 9

我的代码是这样写的:

for(int i=0;i<=n-1;i++)
    {
        if(frec[a[i]]>1) //see if there are duplicate values in frequency array.
        {
            for(int j=i;j<=n-1;j++)
                a[i]=a[i+1];
            frec[a[i]]--;
            n=n-1;
        }
    }

然而,我得到的不是4 6 9,而是6 6 9。非常感谢。

编辑:完整代码

#include <iostream>
#include <limits.h>
using namespace std;
void readarray(int a[], int frec[],const int &n)
{
    for(int i=0;i<=n-1;i++)
    {
        cout<<"a["<<i<<"]=";
        cin>>a[i];
        frec[a[i]] += 1;
    }
}
void printarray(int a[], int frec[], const int &n)
{
    for(int i=0;i<=n-1;i++)
        cout<<a[i]<<" ";
    cout<<endl;
    for(int i=0;i<UCHAR_MAX;i++)
        cout<<frec[i]<<" ";
    cout<<endl;
}
void eliminareduplicate(int a[],int frec[], int &n)
{
    for(int i=0;i<=n-1;i++)
    {
        if(frec[a[i]]>1)
        {
            for(int j=i;j<=n-1;j++)
                a[i]=a[i+1];
            frec[a[i]]--;
            n=n-1;
        }
    }
}
int main()
{
   int a[100], frec[UCHAR_MAX]={0}, n;
   cout<<"n= "; cin>>n;
   readarray(a,frec,n);
   eliminareduplicate(a,frec,n);
   printarray(a,frec,n);
}

有一点可以肯定,这是一个最糟糕的程序,您可以设计它来检测/删除数组中的重复项。这是因为frec数组的大小取决于数组中的数字。

所以,更好的选择是使用std::set

如果您不希望在元素之间排序,那么您可以为此选择哈希表实现。

原因是打字错误:

   if(frec[a[i]]>1)
    {
        for(int j=i;j<=n-1;j++)
            a[i]=a[i+1];     // <===== USE j not i !  
     ....

但是,结果将是,第一个重复项将被删除,并且只保留最后一个出现的项(因为如果项目的频率大于1,则会删除这些项目,而以前所有出现的项都已被删除)。

如果你喜欢保留第一次出现,但删除其余的,这里是你原始算法的变体:

for (int i = 0; i <= n - 1; i++)
{
    if (frec[a[i]] > 1) //if there are duplicate values in frequency array.
    {
        int m = 0;      // number of items removed 
        for (int j = i + 1, k = i + 1; j <= n - 1; j++) // start looping from next
            if (a[j] != a[i])    // if it's not one of the duplicate,
                a[k++] = a[j];   // copy it
            else m++;            // otherwhise don't copy it, and icrease items not copied. 
        frec[a[i]] -= m; 
        n -= m;
    }
}

我不知道这是否与您有关,但对于每个重复,您的版本会将第n次出现后的所有元素移动n-1次,而此变体只移动它们一次

您还将注意到,该变体可以在根本不使用频率表的情况下工作(除了它将系统地循环遍历其余项目,而不是只对重复项进行循环)

您可以尝试以下代码。我不需要使用frec数组。如果数组中有重复的元素,我会忽略它,并减小原始数组的大小。

for (i = 0; i < size; i++) {
      for (j = i + 1; j < size;) {
         if (a[j] == a[i]) {
            for (k = j; k < size; k++) {
               a[k] = a[k + 1];
            }
            size--;
         } else
            j++;
      }
}

打印阵列:

 for (i = 0; i < size; i++) {
      std::cout << a[i] << " ";
 }