如何查找数组中重复的次数?

我很困惑如何找出用户输入中重复了多少次。 我能够输入数字并查看哪些数字正在重复但不确定如何打印出每个输入的数字以及该数字的使用次数。 这就是我到目前为止所拥有的

#include  #include  int main(){ double numArray[100]; int x = 0; int y = 0; int counter = 1; int count = 0; setvbuf(stdout, NULL, _IONBF, 0); printf("Enter any number of integers between 0 and 99 followed a non-numeric: \n"); for (x = 0; x < 100; x++) { if (scanf("%lf", &numArray[x]) != 1) break; counter = counter + 1; } counter = counter - 1; for(x = 0; x < counter; x++){ for(y = x + 1; y < counter; y++){ if(numArray[x] == numArray[y]){ printf("duplicate found: %lf\n", numArray[x]); break; } } } return EXIT_SUCCESS; } 

继续我的初始注释,每当你想捕获一个范围内的值的频率时,你通常想要声明一个数组,并让数组的每个元素代表该范围内的一个值。 (这适用于整数输入)。 例如,在您的情况下,如果要查找用户在0-99范围内输入的整数值的频率,您将声明一个包含100个元素的数组(表示值0-99 )并将所有值初始化为0[1]

然后,每次用户在范围中输入有效值时,都会递增该元素。 例如,如果您的用户输入58 ,您将增加array[58] = array[58] + 1; (或者只是array[58]++; )。 array[58]值现在为1表示用户输入了一次58 。 (如果再次输入58 ,则为2 ,依此类推……)

这非常适合您的输入循环。 你只需声明说int x; 在你的scanf调用中,你填充x ,validation它是否在范围内,然后是array[x]++; 例如,将numarray声明为int [100] ,您可以执行[2]

 #define NMAX 100 /* define constants, avoid 'magic' numbers in code */ ... for (;;) { /* loop until non-numeric encountered */ int x; if (scanf("%d", &x) != 1) /* check for non-numeric */ break; if (x < 0 || x >= NMAX) { /* validate value in range */ fprintf (stderr, "error: value outside of range -- " "try again.\n"); continue; /* if out of range - get new number */ } numarray[x]++; /* increment frequency at element x */ } 

现在,在您的情况下, 0-99与C中使用的从零开始的数组索引完全匹配,但您可以通过调整索引来索引任何范围。 例如,如果您对50-150的范围感兴趣,您只需根据需要调整索引(例如numarray[x-50]++;

但是,在您的代码中,我们还不清楚您的实际意图是什么。 例如,您要求0-99之间的值,但然后将numarray声明为浮点类型。 如果您的目的是让用户输入整数值,那么您的数组类型应该是整数类型。 这减少了您可以简单地以类似于以下方式处理的经典频率问题:

 #include  #include  #define NMAX 100 /* define constants, avoid 'magic' numbers in code */ int main (void){ int i, numarray[NMAX] = {0}; /* C favors all lower-case over * camelCase variable names */ printf ("Enter any number of integers between 0 and 99 " "followed a non-numeric: \n"); for (;;) { /* loop until non-numeric encountered */ int x; if (scanf("%d", &x) != 1) /* check for non-numeric */ break; if (x < 0 || x >= NMAX) { /* validate value in range */ fprintf (stderr, "error: value outside of range -- " "try again.\n"); continue; /* if out of range - get new number */ } numarray[x]++; /* increment frequency at element x */ } for (i = 0; i < NMAX; i++) /* output frequency of values */ printf (" %2d : %d times\n", i, numarray[i]); return EXIT_SUCCESS; } 

示例使用/输出

例如,您可以在0-99之间生成500值,并为使用类似于以下内容生成的500数字中的每个输出频率:

 $ ./bin/freqarray < <(for i in $(seq 1 500); do printf " %d" $(($RANDOM %100)); done; echo "done") Enter any number of integers between 0 and 99 followed a non-numeric: 0 : 4 times 1 : 7 times 2 : 7 times 3 : 4 times 4 : 5 times 5 : 11 times 6 : 5 times 7 : 5 times 8 : 3 times 9 : 8 times 10 : 5 times ... 90 : 8 times 91 : 2 times 92 : 5 times 93 : 8 times 94 : 4 times 95 : 4 times 96 : 8 times 97 : 6 times 98 : 4 times 99 : 8 times 

处理浮点值

现在,如果你真的希望你的用户输入浮点值,例如58.01831等......,从概念上考虑每个数字的频率并没有任何差别,但是实现更多涉及浮动 -点数存储在内存中。 请参阅IEEE浮点和此站点上的众多post。 与浮点存储和随机用户输入的精确比较相关的问题可以变得相当复杂 - 很快。 即使在0-99的范围内,也涉及字面上的4e+18 + 64位值。

如第二条评论中所述,一种可以帮助的方法是散列输入值并将散列值存储在散列表中,以减小跟踪/存储所有值所需的数组大小。 您必须平衡与存储大小相关的精度。

你无法声明一个4e+18元素的数组。 哈希表本质上提供了一种存储和查找机制,可以为您提供合理的准确性,并提供合理的存储大小。 如果用户输入具有相同散列的2值,则会在表中生成冲突 ,您可以使用该冲突来指示重复的条目。 如果这是你的意图,那么你需要研究可用于满足你需求的浮点哈希函数(从你的问题来看,这看起来不像你想要的那样,并且它远远超出了完整的解释)

仔细看看,如果您有任何疑问,请告诉我。 如果您的意图不同,请编辑问题,我很乐意与您进一步合作。

脚注1:选择一个能够保存您期望的最大条目数的数组类型 ,例如,数组的每个int元素可以捕获最多INT_MAX2147483647重复(其中int32-bits

脚注2: C通常支持所有小写的变量名,并避免使用camelCaseMixedCase变量名; 保留常量和宏的所有大写 。 这是一个风格问题 - 所以它完全取决于你。