C语言 -- 计算一个数组中每个元素出现的频率

1. 问题描述:

假设有个整型数组inputArray,共有N个元素。我们要统计每个元素出现的频率。

2. 分析:

这个问题的难点在于保存每个元素的当前频率值。

比如元素1,当前出现1次了,怎么保存这个状态,解决了这个问题后,再遇到1就更新这个状态就好了,其它元素也是一样的道理。

如果用Java来解决这个问题会很简单,因为Java丰富的容器类为我们提供了上面问题的解决方案,HashMap。我们只须以这个元素为key,其出现频率为value,

后续更新它的value就可以了,而且效率还不错。

但是如果要用C语言来实现的话,一切都须得我们自己来手动解决了,这也是这篇博客的目的。

 C语言解决思路:

  • 首先我们声明一个大小和inputArray一样的数组countryArray,并将每个元素值初始化为-1,用来存储每个元素的频率。这需要一些技巧来达到和HashMap一样的效果却也不损失太多性能。
  • if countArray[i] == -1,表示我们还没有统计inputArray[i]这个元素的频率; if countArray[i] == 0,表示我们已经统计过元素inputArray[i]的频率了。
  • 用循环遍历InputArray,from 0 到 N-1,统计每个元素的频率。
  • 对于当前元素inputArray[i],if countArray[i] == -1,我们就保存这个元素的频率到countArray[i];否则,不保存,因为之前已经统计过它了。

大致的过程可用下图表示:


统计数组所有元素初始值为-1,在统计过程中这些元素可能存在三种类型的值,分别表示待统计数组中对应元素的三种状态:未统计(-1)、已统计(0)、出现频率(非0,非-1)。

时间复杂度最坏:O(n^2),即每个元素只出现一次;空间复杂度:O(n),为统计数组的开销。其中n为待统计元素总个数。

代码如下:

/* 
 * C Program to count frequency of each Array element  
 */ 
   
#include <stdio.h>  
   
int main() 
{  
    int inputArray[100], countArray[100];  
    int elementCount, i, j, count;  
   
    printf("Enter Number of Elements in Array\n");
    scanf("%d", &elementCount);
    printf("Enter %d numbers\n", elementCount);
     
    /* Read array elements */
    for(i = 0; i < elementCount; i++) {
        scanf("%d", &inputArray[i]);
        countArray[i] = -1;
    }
   
    /* 
     * for any element inputArray[i], If countArray[i] = -1, 
     * that means frequency is not counted for this number yet 
     * and countArray[i] = 0 means frequency is already 
     * counted for this number.
     */ 
    for(i = 0; i < elementCount; i++) {  
        //开始统计inputArray[i]这个元素的出现频率
		//至少出现1次
		count = 1;  

		// 值为0表示该数字已经被统计过
        if (countArray[i] == 0) {continue;} 
        for(j = i+1; j < elementCount; j++) {  
            if(inputArray[i]==inputArray[j]) {
                countArray[j] = 0;    
                count++;
            }  
        }  
		//记录inputArray[i]出现的频率
        countArray[i] = count;
    }  

    /* Print count of each element */   
    for(i = 0; i<elementCount; i++) {  
        if(countArray[i] != 0) {  
            printf("Element %d : Count %d\n", inputArray[i], countArray[i]);  
        }  
    }  
   
    return 0;  
}  

还想到一种更快的方式:

- 1 先对待统计数组进行排序,时间复杂度最快可达:O(nlogn)

- 2 一次遍历排序后数组,每当出现数值变动时就完成了这个数的统计。

实现代码略。




猜你喜欢

转载自blog.csdn.net/lx1848/article/details/52817802