我有一个名为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;
}
答案 0 :(得分:1)
您尚未创建MCVE(Minimal, Complete, Verifiable Example,这是一个问题。如果提供的代码是MCVE,则以下某些批评可能无关紧要。
代码片段(temp
,temp2
)中的全局变量太多,也不够(您尚未显示allnumbersarray[]
的定义方式)。使用参数传递函数。
您说您有:
int temp[], temp2[];
int removeDuplicates()
{
int n, j =0;
temp[n];
temp2[n];
for (int i=0; i<n-1; i++){
您不会显示temp
和temp2
在哪里定义了大小,这行之前应该有extern
。 (我不确定您为什么不使用temp1
和temp2
,但这是常见的特质。)
该函数未使用原型定义;使用int removeDuplicates(void)
表示应在不带参数的情况下调用它。就目前而言,同一文件中的代码可能会写removeDuplicates(3.14, "astronomy");
,并且编译器没有义务发现差异,因为函数定义没有给出该函数的原型。
函数内部有一个未初始化的变量n
;它的价值是不确定的。由于某些无法解释的原因,您有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;您提交的内容太小,无法提供舒适感。并避免像鼠疫这样的全局变量。大多数功能应具有参数,以标识它们将要进行的工作。