天天看點

衆數的求法 - 想總結卻停留不前?

衆數的求法

★問題描述:

給定含有n個元素的多重集合S,每個元素在S中出現的次數稱為該元素的重數。多重集S中重數最大的元素稱為衆數。

例如,S={1,2,2,2,3,5}。

多重集S的衆數是2,其重數為3。

★程式設計任務:

對于給定的由n個自然數組成的多重集S,程式設計計算S的衆數及其重數。

★資料輸入:

輸入資料由檔案名為input.txt的文本檔案提供。檔案的第1行多重集S中元素個數n;接下來的n行中,每行有一個自然數。

★結果輸出:

程式運作結束時,将計算結果輸出到檔案output.txt中。輸出檔案有2行,第1行給出衆數,第2行是重數。

輸入檔案示例   輸出檔案示例

input.txt       output.txt

6              2

1              3

2

2

2

3

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

1、數組的衆數求法

這回是對上次發帖後改用分治法解決的,還有待改進之處。

  1. #include<iostream>  
  2. #include<fstream>  
  3. using namespace std;  
  4. //結構體用來儲存衆數的元素與重數  
  5. typedef struct  
  6. {  
  7.     int element;//元素  
  8.     int sum;//重數  
  9. }zs;  
  10. //記錄中位數的起始下标  
  11. typedef struct  
  12. {  
  13.     int low;  
  14.     int high;  
  15. }node;  
  16. //快排  
  17. zs x;  
  18. //int data=1;  
  19. void sort(int a[],int s,int t)//對a[s]到a[t]的元素排序  
  20. {  
  21.     int i=s,j=t;  
  22.     int temp;  
  23.     if(s<t)//區間裡至少存在一個元素的情況  
  24.     {  
  25.         temp=a[s];//用區間的第一個元素做基準  
  26.         while(i!=j)//區間兩端交替向中間掃描,知道I=J  
  27.         {  
  28.             while(j>i&&a[j]>temp)  
  29.                 j--;//從右向左掃描,找到第一個小于temp的a[j]  
  30.             if(i<j)//表示找到a[j],則a[i],a[j]交換  
  31.             {  
  32.                 a[i]=a[j];  
  33.                 i++;  
  34.             }  
  35.             while(i<j&&a[i]<temp)  
  36.                 i++;//從左向右掃描,找到第一個大于temp的a[i]  
  37.             if(i<j)//表示找到a[i],則a[i],a[j]交換  
  38.             {  
  39.                 a[j]=a[i];  
  40.                 j--;  
  41.             }  
  42.         }  
  43.         a[i]=temp;  
  44.         sort(a,s,i-1);//對左遞歸  
  45.         sort(a,i+1,t);//對右遞歸  
  46.     }  
  47. }  
  48. //中位數  
  49. int madian(int *a,int l,int r)  
  50. {  
  51.     int x=r+l+1;  
  52.     //  if(x%2)  
  53.     return a[x/2];//為奇數時  
  54.     //  else  
  55.     //      return (a[x/2]+a[x/2+1])/2;//為偶數時  
  56. }  
  57. //傳回中位數的起始點  
  58. node spalit(int *a,int med,int l,int r)  
  59. {  
  60.     node m;  
  61.     m.low=l;m.high=r;  
  62.     for(int i=0;i<=r;i++)  
  63.     {  
  64.         if(med==a[i])  
  65.         {  
  66.             m.low=i;  
  67.             break;  
  68.         }  
  69.     }  
  70.     for(int j=r;j>=0;j--)  
  71.     {  
  72.         if(med==a[j])  
  73.         {  
  74.             m.high=j;  
  75.             break;  
  76.         }  
  77.     }  
  78.     return m;  
  79. }  
  80. //衆數的重數求取  
  81. void mode(int *a,int l,int r)  
  82. {  
  83.     if(l>=r)return;  
  84.     //x.sum=0;  
  85.     else  
  86.     {  
  87.         node n;  
  88.              int temp=0;  
  89.         int med;  
  90.         med=madian(a,l,r);  
  91.         n=spalit(a,med,l,r);  
  92.         temp=n.high-n.low+1;  
  93.         if(x.sum<temp)  
  94.         {  
  95.             x.element=med;  
  96.             x.sum=temp;  
  97.         }  
  98.         if(n.low-l>temp)//  
  99.         {  
  100.             if(x.sum<temp)  
  101.             {  
  102.                 x.element=med;  
  103.                 x.sum=temp;  
  104.             }  
  105.             mode(a,l,n.low-1);  
  106.         }  
  107.         if(r-n.high>temp)  
  108.         {  
  109.             if(x.sum<temp)  
  110.             {  
  111.                 x.element=med;  
  112.                 x.sum=temp;  
  113.             }  
  114.             mode(a,n.high+1,r);  
  115.         }  
  116.     }  
  117. }  
  118. void main()  
  119. {  
  120.     x.sum=0;  
  121.     int n;  
  122.     int *a;  
  123.     ifstream in("C://inputdate.txt");  
  124.     if(!in)  
  125.     {  
  126.     cout<<"the file can\'t open!"<<endl;  
  127.     }  
  128.     in>>n;  
  129.     a=new int[n];  
  130.     for(int i=0;i<n;i++)  
  131.     {  
  132.     in>>a[i];  
  133.          }  
  134.     sort(a,0,n-1);  
  135.     mode(a,0,n-1);  
  136.     cout<<x.element<<" "<<x.sum<<endl;  
  137.     delete []a;  
  138. }  

 第二種

void mode(int l,int r){

int l1,r1;

int med=median(a,l,r);

split(a,med,l,r,l1,r1);

if(largest<r1-l1+1){

largest=r1-l1+1;

element=med;

}

if(l1-1>largest)

mode(1,l1-1);

if(r-r1>largest)

mode(r1+1,r);

}

3、利用先排序,然後統計個數。考慮時間效率,采用快排,count (統計個數),maxCount(最多的個數),element(重數最大的數即衆數)

4.可以利用散列法。

發表于

2015-01-09 17:09 

想總結卻停留不前? 

閱讀(852) 

評論(0) 

編輯 

收藏 

舉報