繁体   English   中英

计算和删除数组c中的重复项

[英]Counting and removing duplicates in an array c

假设我有一个[2,4,6,7,7,4,4]数组,我想要一个可以迭代的程序,然后打印出类似以下内容的代码:

Value:     Count:
2          1
4          3
6          1
7          2

我不希望它在ex 4上打印三遍。 我到目前为止所得到的:

for (int i = 0; i < numberOfInts; i++)
{
    dub[i] = 0;
    for (int y = 0; y < numberOfInts; y++)
    {
        if (enarray[i] == enarray[y])
        {

            dub[i]++;
        }
    }

}

因此,基本上我会对照所有元素检查数组中的每个元素,并为每个重复项在新数组dub []中的索引中添加一个。 因此,如果我在上面的示例数组中运行了这段代码,然后将其打印出来,则会得到以下内容:1,3,1,2,2,3,3。 这些数字非常混乱,因为我真的不知道这些数字属于哪个数字。 尤其是当我将数组中的数字随机化时。 然后我必须删除数字,所以每个数字只有一个。 任何人都有更好的解决方案?

您可以在检查每个元素是否重复时遍历数组,在这种情况下,您可以增加其计数(循环仅检查节省头部时间的值)。 这使您无需创建任何额外的缓冲区数组或结构即可完成所需的工作。

布尔值“ bl”可防止重复打印

int main() {

    int arr[] = { 2, 4, 6, 7, 7, 4, 4 };
    int size = (sizeof(arr) / sizeof(int));

    printf("Value:\tCount\n");
    for (int i = 0; i < size; i++) {
        int count = 0, bl = 1; //or 'true' for print
        //check elements ahead and increment count if repeated value is found 
        for (int j = i; j < size; j++) {
            if (arr[i] == arr[j]) {
                count++;
            }
        }
        //check if it has been printed already
        for (int j = i-1; j >= 0; j--) {
            if (arr[i] == arr[j]) {
                bl = 0; //print 'false'
            }
        }
        if (bl) { printf("%d\t\t%d\n", arr[i], count); } 
    }

    return 0;
}

给定char数组只包含'0'到'9',您可以利用一个简单的查找表,如下所示:

#include <stdio.h>

typedef struct
{
    char c;
    int  num;
} TSet;

TSet my_set[] =
{
    { '0', 0 },
    { '1', 0 },
    { '2', 0 },
    { '3', 0 },
    { '4', 0 },
    { '5', 0 },
    { '6', 0 },
    { '7', 0 },
    { '8', 0 },
    { '9', 0 },
};

int main()
{
    char a[] = {'2','4','6','7','7', '4','4'};
    int i;
    for( i = 0; i < sizeof(a) / sizeof(char); i++ )
    {
        my_set[ a[i] - '0' ].num++;
    }

    printf( "%-10s%-10s\n", "Value:", "Count:" );
    for( i = 0; i < sizeof(my_set) / sizeof(TSet); i++ )
    {
        if( my_set[i].num != 0 )
        {
            printf( "%-10c%-10d\n", my_set[i].c, my_set[i].num );
        }
    }
}

输出:

Value:    Count:    
2         1         
4         3         
6         1         
7         2    

我不明白这里的复杂性。 我认为有两种方法是高效且易于实现的:

计数排序

  • 需要int数组中数组中最大元素的大小
  • 总体复杂度O(n + m),其中m是数组中的最大元素

qsort和枚举

  • qsort在O(n * log(n))中工作,并为您提供排序的数组
  • 数组排序后,您可以简单地对其进行遍历并计数
  • 总体复杂度O(n * log(n))
  1. 通常通过使用qsort()函数对数组进行排序
  2. 遍历所有元素,依次计数相等的元素,如果检测到下一个不同的元素,则打印前一个元素的计数

这适用于任意数量不同元素。 同样,不需要第二个数组。

在外部for循环中放置一个打印语句以打印重复

for (int i = 0; i < numberOfInts; i++)
{
    dub[i] = 0;
    for (int y = 0; y < numberOfInts; y++)
    {
        if (enarray[i] == enarray[y])
        {

            dub[i]++;
        }
    }
printf("%d%d",enarray[i], dub[i]);
}

您有大致的想法。 除了输入数组之外,我还建议另外三个数组:

  • 一个used数组, used跟踪输入中的哪些条目已被计数。
  • 跟踪input数组中不同数字的value数组。
  • 一个count数组,用于跟踪一个数字出现了多少次。

例如,在处理输入数组中的2和4之后,该数组的内容将是

input[] = { 2,4,6,7,7,4,4 };
used[]  = { 1,1,0,0,0,1,1 };  // all of the 2's and 4's have been used
value[] = { 2,4           };  // unique numbers found so far are 2 and 4
count[] = { 1,3           };  // one '2' and three '4's

您要的东西很奇怪。 通常,我会创建一个具有2个成员的结构,例如“数字”和“计数”。 但是,让我们精确地尝试您要的是什么(每个数字后跟计数的一维数组):

int 
   i,
   numberOfInts = 7,
   numberOfDubs = 0,
   enarray[7] = {2,4,6,7,7,4,4},
   dub[14]; // sizeof(enrray) * 2 => maximum number of dubs (if there are no duplicates)

// For every number on enarray
for(i = 0; i < numberOfInts; i++)
{
    int jump = 0;

    // Check if we have already counted it
    // Only check against pairs: Odds are the dub counter
    for(int d = 0; d < numberOfDubs && !jump; d += 2)
    {
       if(dub[d] == enarray[i])
       {
          jump = 1;
       }
    }

    // If not found, count it
    if(!jump)
    {
       // Assign the new number
       dub[numberOfDubs] = enarray[i];
       dub[numberOfDubs + 1] = 1;

       // We can begin from 'i + 1'
       for(int y = i + 1; y < numberOfInts; y++)
       {
          if(enarray[i] == enarray[y])
          {
               dub[numberOfDubs + 1]++;
          }
       }

       // Increment dub's counter by 2: number and it's counter
       numberOfDubs += 2;
    }
}

// Show results
for(i = 0; i < numberOfDubs; i += 2)
{
   printf("%d repeated %d time%s\n", dub[i], dub[i + 1], (dub[i + 1] == 1 ? "" : "s"));
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM