在数组中搜索重复值
Posted
技术标签:
【中文标题】在数组中搜索重复值【英文标题】:Searching for duplicate values in an array 【发布时间】:2012-09-14 05:57:13 【问题描述】:我对 C 语言非常陌生,希望得到一些指点。我试图输入一个数组的 7 个整数并搜索它们以查看是否有任何数字只出现一次。这是我目前所拥有的:
#define size 7
int main(void)
int array[size], target, i, prev, count;
//Initialize the array
printf("Please enter %d integers", size);
scanf("%d", &target);
prev = array[0];
count = 1;
for(i = 0; i<size; i++)
scanf("%d", &array[i]);
...
我意识到这很糟糕,但 C 对我来说完全陌生。我想出了如何从用户那里输入 7 个整数,但我没有第一个线索来说明从哪里开始尝试索引它们。我还意识到有更高级的方法可以解决这个问题。但是,我正在尝试使用业余爱好者可以理解的基本概念来找到解决方案。
【问题讨论】:
别忘了检查scanf()
是否成功。输入数组后,您可以通过依次查看数组中的每个值(一个循环)来执行强力二次搜索重复项,并搜索数组的其余部分(嵌套循环)以查看是否任何其他值都等于外部循环中的当前值。
嘿,供您参考,我发现一个链接很好地解释了这个问题,看看***.com/questions/7117388/…
谢谢,这是有道理的。知道如何检查输入的数组吗?或者如何索引它?
“我对 C 语言非常陌生,希望得到一些指导。”哈!你得到了他们:)
【参考方案1】:
搜索重复项的最简单方法(虽然不是最有效的方法)是对数组进行排序。您可以像这样使用内置的qsort
函数:
int compare (const void * a, const void * b)
return ( *(int*)a - *(int*)b );
/* ... */
qsort (array, size, sizeof(int), compare);
int seen = 0;
for (int i = 1; i < size; ++i)
if (array[i] == array[i - 1])
if (!seen)
printf("%d\n", array[i]);
seen = 1;
else
seen = 0;
【讨论】:
这需要n log n + n
时间。它比 n ^ 2 大 n !!
O(nlogn + n) = O(nlogn)。这在 O(n) 中使用哈希表是可行的,但我认为这对于发帖人的理解水平来说太复杂了。
对,特别是他的数字没有范围(因此数组不能用于散列)并且C不提供set
数据结构
对,如果是 C++ 或 Java,我肯定会使用基于集合的实现。
+1 一般来说,这是查找重复项的最佳策略。【参考方案2】:
我知道 3 种查找重复项的方法,2 个已经回答,所以这里是第三种(简化)-
复杂度 O(N) 时间,O(M) 内存。
如果数字在某个范围内,例如 0 - M
和 M
与 N
的元素数量相当,您可以使用大小为 M+1
的数组来检查该数字是否之前出现过。
代码 -
int exists[M+1]; //set M to appropriate value
memset(exists, 0, sizeof(exists)); //set all 0
for (i = 0; i < N; i++)
if (exists[array[i]])
printf("Duplicate found\n");
break; //or something else
exists[array[i]] = 1;
注意 - 不要忘记输入元素应该是正整数,不大于M
【讨论】:
你也可以使用某种hashmap代替bitmap,当你在某个元素上发生hash冲突时你只需将当前值与桶中的值进行比较,会显着增加代码量,但也应该减少内存消耗 @Vorber:当然,我提到了 OP 的“简化”方法。【参考方案3】:这个读起来有点头疼,所以我在这里稍微解释一下我做了什么:
首先,包含标准 i/o 库,#define array size to any you want,声明你的数组(我叫我的:int entries[SIZE];)。
“输入 10 个数字”之后的第一个 for 循环是主要循环,它允许您将 10 个数字推入数组。
以下 if 语句是应用于在键入后立即输入的值的测试:
1) 第一个 if 语句确保我们输入的值在正确的范围内。
2) 下面的 'else if' 表明如果 entries[i] = entries[0](表示如果这是数组中的第一个对象),我们什么也不做,因为没有什么可以比较的。
3) 最后一个“else”包含一个嵌套循环。外部循环初始化为 1,因此我们确保在内部循环中进行的比较中,我们始终将当前值与前一个值进行比较。
我希望这会有所帮助...干杯:)
*/
#include <stdio.h>
#define SIZE 10
//declarations
int entries[SIZE];
int main(void)
printf("Enter 10 numbers:\n");
for(int i = 0; i <= SIZE-1; i++)
printf("[%d]:\n", i);
scanf("%d", &entries[i]);
if(entries[i] < 10 || entries[i] > 100)
printf("Please enter valid number (between 10 and 100)\n");
scanf("%d", &entries[i]);
else if(i == 0)
;
else
for(int j = 1; j <= i; j++)
*//internal loop goes through all the previous entries (entries[i-1], entries[i-2], etc)*
for(int k = 0; k < j; k++)
if(entries[j] == entries[k])
printf("%d is a duplicate value\n", entries[i]);
【讨论】:
【参考方案4】:这可以在 O(n^2) 算法中完成:
int yes = 1, i, j;
for (i = 0; i < n; ++i)
for (j = i + 1; j < n; ++j) if (arr[i] == arr[j])
printf("Found a duplicate of %d\n", arr[i]);
yes = 0;
break;
if (!yes) break;
if (yes) printf("No duplicates");
【讨论】:
我认为提到的“双打”是“重复”——因此我对标题进行了编辑。 谢谢,现在说得通了。以上是关于在数组中搜索重复值的主要内容,如果未能解决你的问题,请参考以下文章
在 MySQL JSON 字段中的数组中搜索值(Laravel/Lumen)[重复]
javascript - 如果在子对象中找到值,则搜索嵌套对象数组并返回父对象[重复]