我如何停止计数一个特定的值重复后,它已经计数一次在数组中的C?



例如我有一个数组:

arr[9] = {1, 3, 4, 9, 2, 9, 2, 9, 7}

然后对数组进行排序得到

arr[9] = {1, 2, 2, 3, 4, 7, 9, 9, 9}

然后使用两个for循环计算每个值的重复数。我想要的输出是:

2 instances of 2
3 instances of 9
相反,我得到:
2 instances of 2
3 instances of 9
2 instances of 9

我知道循环进行一次后,当arr[6],外循环计算还有两个。但在此之后,循环进入arr[7],外循环仍然计数另一个9arr[8]. 所以我的问题是,当它对数组中的每个数字重复计数一次时,我如何停止代码?. 谢谢!

示例代码:

#define NUM = 9
int main() {
arr[NUM] = {1, 3, 4, 9, 2, 9, 2, 9, 7};
sort_int_array(arr, NUM); //insertion sort function
int i, j, count=1;
for (i=0; i<NUM; i++) {
for (j=i+1;j<NUM; j++) {
if (arr[i] == arr[j]) {
count++;
}
if (arr[i] != arr[j] && count>1) {
printf("%d instances of %dn", count, arr[i]);
count=1;
}
}
}
}

我找到了答案,谢谢大家的帮助。我只需要删除第二个for循环。

#define NUM = 9
int main() {
arr[NUM] = {1, 3, 4, 9, 2, 9, 2, 9, 7};
sort_int_array(arr, NUM); //insertion sort function
int i, count=1;
for (i=0; i<NUM; i++) {
if (arr[i] == arr[i+1]) {
count++;
}
if (arr[i] != arr[i+1] && count>1) {
printf("%d instances of %dn", count, arr[i]);
count=1;
}
}
}

我认为问题是你先看前九个,然后再数后面两个。然后,它将转到副本,并将副本与其他副本进行比较。我假设你能做的是检查arr[I]是否不等于arr[I - 1]这样你就不会比较重复项

下面是一个演示程序,演示如何计算数组中元素出现的次数。

#include <stdio.h>
#include <stdlib.h>
int cmp( const void *a, const void *b )
{
int x = *( const int * )a;
int y = *( const int * )b;

return ( y < x ) - ( x < y );
}
int main(void) 
{
int arr[] = {1, 3, 4, 9, 2, 9, 2, 9, 7};
const size_t N = sizeof( arr ) / sizeof( *arr );

qsort( arr, N, sizeof( int ), cmp );

for ( size_t i = 0; i != N; )
{
size_t j = i;
size_t count = 1;
while ( ++i != N && arr[i] == arr[j] ) ++count;
printf( "%zu instances of %dn", count, arr[j] );       
}

return 0;
}

程序输出为

1 instances of 1
2 instances of 2
1 instances of 3
1 instances of 4
1 instances of 7
3 instances of 9

如果您愿意,您可以替换printf的调用

printf( "%zu instances of %dn", count, arr[j] );

if ( count != 1 ) printf( "%zu instances of %dn", count, arr[j] );

在这种情况下,输出将是

2 instances of 2
3 instances of 9

编辑:至于你的解决方案作为你自己的问题的答案,然后代码调用未定义的行为,由于访问内存超出这个表达式arr[i+1]i等于NUM - 1

for (i=0; i<NUM; i++) {
if (arr[i] == arr[i+1]) {
^^^^^^^^  
count++;
}
if (arr[i] != arr[i+1] && count>1) {
^^^^^^^^
printf("%d instances of %dn", count, arr[i]);
count=1;
}
}

您不需要为此使用两个for循环,因为这会降低效率并增加代码的复杂性。

如果你用手做,你会

  1. 再拿一张纸来。
  2. 用于数组中的每个数字:
    • 如果这是你第一次看到这个数字:
      记下来并记录它的计数为1
    • else:
      然后增加1

如果你只需要出现至少两次的元素,你可以过滤掉count = 1的元素。

对于代码:

// this is called frequency array, which we will use to store the 
// number of occurrences (frequency) of a given number.
// The size of the array must be larger than the largest number in the array
int sz = 10  // sz = largest expected element + 1 (this only works for array of integers).
int freq[sz];
memset(freq, 0, sz * sizeof(int));  // reset all values in the array to 0
int arr[9] = {1, 2, 2, 3, 4, 7, 9, 9, 9};
int i;
for (i = 0;i < 9;i++){
cur = arr[i]; // read the current element
freq[cur] += 1;  // increment its count by 1
}
for (i = 0;i < sz;i++) {
count = freq[i];   // read the count of the number i
if(count != 0) {
// a count of 0 means that the number didn't occur in the array
// you can also exclude numbers occurring only once by count > 1
printf("%d instances of %dn", count, i);
}
}

我没有测试这段代码,但这是一个概念,你可以在这里找到更多。

这个实现使用了比需要的更多的空间,但是它有快速的访问时间,如果您移动到cpp,您可以使用stlmapunordered_map来获得更节省空间的解决方案。

最新更新