C - 从数组中删除重复项并将这些重复项存储在另一个数组中

标签 c arrays sorting integer

我有一个名为 allnumbersarray 的数组我需要删除数组的重复项并将它们存储在另一个名为 uniqueprimes . allnumbersarray由素数组成。当我尝试使用 if - else if 语句时,输出变得困惑,许多元素变为 0 并且不再排序。这是我尝试过的,不知道要更改什么:

int temp[], temp2[];
int removeDuplicates()
    {
        int n, j =0;
        temp[n];
        temp2[n];

        // Start traversing elements

        for (int i=0; i<n-1; i++){

            // If current element is not equal
            // to next element then store that
            // current element
            if (allnumbersarray[i] != allnumbersarray[i+1]){
                temp[j++] = allnumbersarray[i];
            }
            else if(allnumbersarray[i] == allnumbersarray[i+1])
                temp2[j++] = allnumbersarray[i];

        }
        // Store the last element as whether
        // it is unique or repeated, it hasn't
        // stored previously
        temp[j++] = allnumbersarray[n-1];

        // Modify original array
        for (int i=0; i<j; i++){
            allnumbersarray[i] = temp[i];
        }

        printf("\n\nprimes array with duplicates removed:\n");
          for (int i = 0; i < j; i++)
              printf("%d\n", allnumbersarray[i]);


        return j;
    }

最佳答案

您尚未创建 MCVE(Minimal, Complete, Verifiable Example - 这是一个问题。如果提供的代码是 MCVE,则以下一些批评可能无关紧要。

代码片段( temptemp2 )中有太多全局变量,而且还不够(您还没有显示 allnumbersarray[] 是如何定义的)。使用函数的参数来传递数据。

你说你有:

int temp[], temp2[];
int removeDuplicates()
    {
        int n, j =0;
        temp[n];
        temp2[n];
        for (int i=0; i<n-1; i++){

你不显示temptemp2用大小定义——这一行应该有 extern在它面前。 (我不确定你为什么不使用 temp1temp2 ,但这是一个常见的特质。)

该函数不是用原型(prototype)定义的;使用 int removeDuplicates(void)表明它应该在没有参数的情况下被调用。就目前而言,同一文件中的代码可以写入 removeDuplicates(3.14, "astronomy");并且编译器没有义务发现差异,因为函数定义没有给出函数的原型(prototype)。

您有一个未初始化的变量 n函数内部;它的值(value)是不确定的。由于某些无法解释的原因,您有 temp[n];temp2[n]; , 从可疑声明的数组中(或更可能在外部)的不确定位置读取的语句。如果幸运的话,编译器可能会删除这些引用,因为它们不会影响计算。但是他们被误导了两次——一次是因为他们什么都不做,一次是因为他们使用未初始化的变量来索引数组。

然后使用这个未初始化的变量 n作为您的主要方向for环形。这不会愉快地结束。您永远不会使用小心存储在 temp2 中的值.

我认为你需要彻底重新设计你的功能。例如,您可以使用:
 int removeDuplicates(int *n_values, int *values, int *dups)
 {

在哪里 *n_values是源数组 (values) 中的条目数,它成为输出数组之一。它通过引用传递,因此您可以向调用函数识别 values 中有多少唯一条目重复删除完成后的数组(在开始附近使用 int n = *n_values;,在结尾使用 *n_values = …new size…;)。 dups数组相当于你的 temp2 .它被假定为“足够大”(这实际上是一个危险的假设)。该函数将直接返回dups中的条目数,就像当前函数写得正确时一样。

在某处,使用当前方案,您必须将源数组 (values) 中的唯一值复制到备用空间中,以便稍后将其复制回来。更好的算法通过两个索引(当前读取位置和当前写入位置)逐步遍历源数组。当您找到相邻的副本时,您增加读取位置而不增加写入位置。这意味着您最终不需要 temp数组。

您还可以使用相同的代码“删除重复项”,但该算法仅查找相邻的重复项。如果你有一个输入列表 (int[]){ 2, 3, 3, 5, 7, 7, 3, 11, 11, 13, 17, 19, 11 } (那是 compound literal ),您的代码不会发现第三个 3 或第三个 11。目前尚不清楚这是否是一个问题 - 可能是重复项只能彼此相邻出现,在这种情况下您不如果重复项不需要相邻,则不必在分析中像您所做的那样复杂。

这至少给了你一些思考的东西。

下次,请确保您发布更完整的 MCVE;你所展示的内容太少了,无法舒适。并避免像瘟疫一样的全局变量。大多数函数都应该有参数来确定它们将要处理的内容。

关于C - 从数组中删除重复项并将这些重复项存储在另一个数组中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53586128/

相关文章:

qt - 如何对 QDateTime* 的 QList 进行排序?

c - 为什么 `gets_s()` 仍然没有在 GCC (9.3.0) 中实现?

c - 使用 C 将文本文件中的内容扫描到 2 个数组中

java - 字符数组和for循环错误

java - 表示带有列/行标签的矩阵

c# - IComparable<T>.CompareTo 与 Sort 中的 null 进行比较

c++ - 使用 VC 编译器在 Eclipse 中创建可执行文件

c - 让 printf() 删除值的尾随 ".0"

javascript - 要数组的对象数组

c++ - 寻找 vector 内的项目