众数问题

来源:互联网 发布:spark sql insert 编辑:程序博客网 时间:2024/04/25 21:20

转自:http://blog.csdn.net/sophie_wise8/article/details/7690040

给定含有n个元素的多重集合S,每个元素在S中出现的次数称为该元素的重数。多重集S中重数最大的元素称为众数。  

例如,S={1,2,2,2,3,5}。  多重集S的众数是2,其重数为3。  
对于给定的由n 个自然数组成的多重集S,编程计算S 的众数及其重数。
Input  
  输入的第1行多重集S中元素个数n;接下来的n 行中,每行有一个自然数,值在整数范围内 
Output  

  程序运行结束时,将计算结果输出。输出文件有2 行,第1 行给出众数,第2 行是重数。如果很多数的出现次数相同则输出最小的那个。

方法一:递归实现

– 先根据某数X,将小于X的放于其左,大于X的放于其右– 统计X出现的次数T– 如果X左边数的个数>T,向左递归– 如果X右边数的个数>T,向右递归

代码如下:

[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <math.h>  
  4. #define MAX 100  
  5.   
  6. int Random(int p, int r){//随机化  
  7.         //return rand()*(r-p)/32767+p;  
  8.     return rand()%(r-p)+p;  
  9. }  
  10.   
  11. void Swap(int* a, int* b){  
  12.         int temp;   
  13.         temp= *a;  
  14.         *a = *b;  
  15.         *b = temp;  
  16. }  
  17.   
  18. int Partition(int* y, int p, int r){  
  19.         int i = p, j = r+1;  
  20.         int x = y[p];  
  21.         while(true){  
  22.                 while(y[++i]<x&&i<r);  
  23.                 while(y[--j]>x);  
  24.                 if(i>=j) break;  
  25.                 Swap(&y[i],&y[j]);  
  26.         }  
  27.         y[p] = y[j];  
  28.         y[j] = x;  
  29.         return j;  
  30. }  
  31.   
  32. int RandomizedPartition(int* y, int p, int r){  
  33.         int i = Random(p,r);  
  34.         Swap(&y[i],&y[p]);  
  35.         return Partition(y,p,r);  
  36. }  
  37. void FindModeIndex(int* y,int i,int* left_index,int* right_index)  
  38. {  
  39.         int mode=y[i];  
  40.         int left=i;  
  41.         int right=i;  
  42.         while(y[--left]==mode);  
  43.         while(y[++right]==mode);  
  44.         left++;  
  45.         right--;  
  46.         *left_index=left;  
  47.         *right_index=right;  
  48. }  
  49.   
  50. void FindMode(int* y, int p, int r, int* mode, int* count){  
  51.         int i = RandomizedPartition(y,p,r);  
  52.         int left_index;  
  53.         int right_index;  
  54.         int count_mid,count_left,count_right;  
  55.         FindModeIndex(y,i,&left_index,&right_index);  
  56.         count_mid=right_index-left_index+1;  
  57.         count_left=left_index-p;  
  58.         count_right=r-right_index;  
  59.         if(count_mid>=*count)  
  60.         {  
  61.             *mode=y[i];  
  62.             *count=count_mid;  
  63.         }  
  64.         if(count_left>=count_mid) FindMode(y,p,left_index-1,mode,count);  
  65.         if(count_right>=count_mid)  FindMode(y,right_index+1,r,mode,count);  
  66.         return;  
  67. }  
  68. int main()  
  69. {  
  70.     int n;  
  71.     int* a;  
  72.     int i;  
  73.     int mode;  
  74.     int count;  
  75.   
  76.     a=(int *)malloc(sizeof(int)*MAX);  
  77.     scanf("%d",&n);  
  78.     for(i=0;i<n;i++)  
  79.       scanf("%d",&a[i]);  
  80.     i=0;  
  81.     mode=MAX;  
  82.     count=0;  
  83.     FindMode(a,0,n-1,&mode,&count);  
  84.     printf("mode is %d\ncount is %d\n",mode,count);  
  85.     free(a);  
  86.     return 0;  
  87.   
  88. }  
方法二:先排序,然后再统计,时间复杂度较高。

方法三:利用数组或散列表统计,如果数据分布稠密采用数组,如果数据分布稀疏采用散列表。


原创粉丝点击