【问题标题】:Counting how many times a number appears in a random array计算一个数字在随机数组中出现的次数
【发布时间】:2020-08-13 01:52:37
【问题描述】:

C 函数。 这是我的工作代码。当给定一个随机数组大小时,它会显示此输出;

输入数组的大小:20

数组中有什么:

3 6 17 15 13 15 6 12 9 1 2 7 10 19 3 6 0 6 12 16

3 出现 2 次。

6 出现 4 次。

15 出现 2 次。

6 出现 3 次。

12 出现 2 次。

6 出现 2 次。

但是我想知道一旦搜索了某个数字以不重复循环,您将如何实施?

#include <stdio.h>                                                              
#include <stdlib.h>                                                             
                                                                            
/* shows duplicate numbers in randomly generated array*/                        
void display_repeats(int *a, int n){                                            
    int i, j;                                                                   
    int count = 0;                                                              
                                                                            
    for(i = 0; i < n; i++){                                                     
        for(j = i; j < n; j++){                                                 
            if(a[i] == a[j]){                                                   
                count++;                                                        
            }                                                                   
        }                                                                       
        if(count > 1){                                                          
            printf("%3d occurs %3d times.", a[i], count);                       
            printf("\n");                                                       
        }                                                                       
        count = 0;                                                              
    }                                                                           
}                       

int main(void){                                                                 
    int array_size = 0;                                                         
    int *my_array;                                                              
    int i = 0;                                                                  
                                                                            
    printf("Enter the size of the array: ");                                    
    scanf("%d", &array_size);                                                   
                                                                            
    /*initialises the array to the appropriate size */                          
    my_array = malloc(array_size * sizeof my_array[0]);                         
    if(NULL == my_array){  
        fprintf(stderr, "memory allocation failed!\n");                         
        return EXIT_FAILURE;                                                    
    }                                                                           
                                                                            
    for(i = 0; i < array_size; i++){                                            
        my_array[i] = rand() % array_size;                                      
    }                                                                           
    printf("What's in the array:\n");                                           
    for(i = 0; i < array_size; i++){                                            
        printf("%d ", my_array[I]);
    }
    printf("\n");                                                               
    display_repeats(my_array, array_size);                                      
                                                                            
    /* release the memory associated with the array */                          
    free(my_array);                                                             
                                                                            
    return EXIT_SUCCESS;                                                        
}                       


   

【问题讨论】:

  • 欢迎来到 SO!保留另一个数组seen 来跟踪您已经处理过的每个元素怎么样?如果您尚未处理该号码,请对其进行处理并将其添加到seen。如果它在seen 中,请不要重新处理它。另一个想法:对数组进行排序并计算运行次数。
  • 如果存储在数组中的数字范围很小(例如,数组包含从 0 到 1000 的数字),那么您可以在 O(n) 时间内使用单个循环执行此操作计数排序。我举个例子。
  • 这是一个示例:onlinegdb.com/rk2ADXMMv 我将范围设置为 -20 到 20,但您可以将其更改为任何值 - 您甚至可以再添加一个循环来确定这些值。
  • 这里是一个计算范围的例子:onlinegdb.com/SkML5mGMD
  • 发布的代码缺少rand()函数的初始化。建议:#include &lt;time.h&gt;srand( (unsigned)time( NULL ) );

标签: arrays c


【解决方案1】:

您可以对数组进行排序并计算每个数字的运行次数。时间复杂度为 O(n log(n)) 但如果没有干净的哈希解决方案,它应该是合理的并且是最简单的方法。

顺便说一句,将打印(side effect)与逻辑分开是个好主意。将结果作为数据结构返回,并让调用者决定如何处理它。保持逻辑和打印紧密耦合会损害可重用性,并阻止您在应用函数后以编程方式对数据进行操作。

这是概念的快速证明。基于上述提示还有很大的改进空间 - 如果您确实将其移出 main,请考虑在排序前复制 int 数组以保留函数 idempotent

#include <stdio.h>
#include <stdlib.h>

int cmp_ints(const void *a, const void *b) {
    return *((const int *)a) - *((const int *)b);
}

int main(void) {
    int nums[] = {1, 1, 5, 6, 1, 6, 2, 4, 6, 8};
    int len = sizeof nums / sizeof nums[0];
    qsort(nums, len, sizeof *nums, cmp_ints);

    for (int i = 0; i < len;) {
        int count = 1;
        int num = nums[i++];

        for (; i < len && nums[i] == num; i++, count++);

        printf("%d => %d\n", num, count);
    }

    return 0;
}

输出:

1 => 3
2 => 1
4 => 1
5 => 1
6 => 3
8 => 1

【讨论】:

    【解决方案2】:

    以下建议代码:

    1. 干净编译
    2. 通过调用srand()正确初始化rand()函数
    3. 正确检查对scanf() 的调用是否成功/失败,并通过stderr 通知用户并退出代码来正确处理任何失败
    4. 利用了 C 的可变长度数组特性,因此不需要动态内存
    5. 尽可能限制局部变量的范围
    6. 不重复检查一个值超过一次
    7. 使用适当的水平和垂直间距以提高可读性
    8. 按升序输出数组中的值
    9. 执行所需的功能

    现在,建议的代码:

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    /* shows duplicate numbers in randomly generated array*/
    /* note: order of parameters in function
     * so can clearly indicate the array sizing
     */
    void display_repeats(int arraySize, int Array[ arraySize ] )
    {
        int minValue = 0;
        int maxValue = 0;
        
        for( int i = 0; i < arraySize; i++ )
        {
            if( Array[i] > maxValue )
            {
                maxValue = Array[i];
            }
        }
        
        for( int j = minValue; j <= maxValue; j++ )
        {
            int count = 0;
            
            for( int i = 0; i < arraySize; i++) 
            {
                if( Array[i] == j )
                {
                    count++;
                }
            }
    
            if(count > 1 )
            {
                printf( "%d occurs %d times.\n", j, count );
            }
        }
    }
    
    
    int main( void )
    {
        int array_size = 0;
    
        printf( "Enter the size of the array: " );
        if( scanf( "%d", &array_size ) != 1 )
        {
            fprintf( stderr, "scanf for array size failed\n" );
            exit( EXIT_FAILURE );
        }
    
        /* use VLA feature of C to declare array */
        int my_array[ array_size ];
        srand( (unsigned)time(NULL) );
        
        for( int i = 0; i < array_size; i++ )
        {
            my_array[i] = rand() % array_size;
        }
    
        printf( "What's in the array:\n" );
        for( int i = 0; i < array_size; i++ )
        {
            printf( "%d ", my_array[i] );
        }
        printf( "\n" );
    
        display_repeats( array_size, my_array );
    }
    

    建议代码的典型运行会导致:

    Enter the size of the array: 100
    What's in the array:
    19 69 68 90 25 8 44 64 33 3 28 4 4 43 22 6 19 93 70 63 34 96 42 31 74 9 72 49 34 12 12 53 33 80 95 10 40 39 74 26 94 55 82 98 98 56 56 69 49 78 33 35 75 75 19 1 36 91 50 70 55 63 76 40 95 71 51 88 63 25 14 9 80 48 8 30 4 16 0 5 95 33 93 22 60 12 23 96 3 74 19 58 89 95 50 84 18 1 24 33 
    1 occurs 2 times.
    3 occurs 2 times.
    4 occurs 3 times.
    8 occurs 2 times.
    9 occurs 2 times.
    12 occurs 3 times.
    19 occurs 4 times.
    22 occurs 2 times.
    25 occurs 2 times.
    33 occurs 5 times.
    34 occurs 2 times.
    40 occurs 2 times.
    49 occurs 2 times.
    50 occurs 2 times.
    55 occurs 2 times.
    56 occurs 2 times.
    63 occurs 3 times.
    69 occurs 2 times.
    70 occurs 2 times.
    74 occurs 3 times.
    75 occurs 2 times.
    80 occurs 2 times.
    93 occurs 2 times.
    95 occurs 4 times.
    96 occurs 2 times.
    98 occurs 2 times.
    

    【讨论】:

      【解决方案3】:

      ggorlen 的第一个建议的实现,创建一个数组来存储每个索引处的数字是否已经被看到。

      void display_repeats(int *a, int n){                                            
          int i, j;                                                                   
          int count = 0;
          int seen[n]; //stores 1 if the number at this index has already been seen, 0 if not
          for (int i = 0; i<n; i++) seen[i] = 0; //initializes values to 0                                                     
                                                                                  
          for(i = 0; i < n; i++){
              if (seen[i]) continue; //skips this iteration of the for loop if this number has already been seen
                                                   
              for(j = i; j < n; j++){                                                 
                  if(a[i] == a[j]){                                                   
                      count++;
                      seen[j] = 1; //notes that we already seen the number at this index                                       
                  }                                                                   
              }                                                                       
              if(count > 1){                                                          
                  printf("%3d occurs %3d times.", a[i], count);                       
                  printf("\n");                                                       
              }                                                                       
              count = 0;                                                              
          }                                                                           
      } 
      

      【讨论】:

        猜你喜欢
        • 2021-07-02
        • 2021-03-22
        • 2020-03-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多