exam13-衆數問題

給定含有n個元素的多重集合S,每個元素在S中出現的次數稱爲該元素的重數。多重集S中重數最大的元素爲衆數。例如,S={1,2,2,2,3,5},多重集S的衆數是2,其重數爲3。 對於給定的由n(n<100)個自然數組成的多重集S,計算S的衆數及其重數。
輸入格式:
輸入在一行中給出多重集S中的元素個數n;在接下來的n行中,每行有一個自然數。
輸出格式:
輸出有2行,第1行是衆數,第2行是重數。
輸入樣例:
6
1
2
2
2
3
5
輸出樣例:
2
3
算法思想:
對於這個算法,我們採用分治的思想。我們先給定一個數組a,然後將數組排序,我們找到數組a中位於中間的數及其重數n,如果左邊的元素個數大於n,那麼衆數在左邊可能出現,我向左遞歸,右邊同理。這樣遞歸下去我們就可找到衆數及其重數了。在這裏我們要用到三個函數,分別爲count(用於統計數組中間數出現的次數),start(用於返回當前數組的中間數第一次出現位置的索引),mode(用於找衆數)。

在這裏插入代碼片
#include<iostream>
using namespace std;
int num=0;  //定義全局變量n用來存儲衆數
int sum=0;  //定義一個全局變量sum用來存儲重數

int count(int a[],int p,int q)
{//定義一個統計數組中間數出現的次數。a爲待統計的集合,參數p爲待遞歸數組第一個數的索引,q爲帶遞歸數組最後一個數的索引
	int n=a[(p+q)/2];
	int counts=0;
	for(int i=p;i<q;i++)
	{//從待統計數組的第一個數的索引開始統計,直到q結束
		if(a[i]==n)
		{
			counts++;				
		}		
	}	
	return counts;	
}

int start(int a[],int p,int q)
{//定義一個方法,用於返回當前數組的中間數第一次出現位置的索引。參數p爲當前數組第一個數的位置索引,q爲最後一個索引	
	int x=0;	
	//從當前數組的第一個數開始,當第一次找到與當前數組的中間數相等的數,跳出循環,並返回i	
	for(int i=p;i<q;i++)		
	{		
		if(a[i]==a[(p+q)/2])			
		{			
			x=i;			
			break;			
		}		
	}	
	return x;	
}

void mode(int a[],int p,int q) //剛開始第一步時p=0,q=n
{	
	int tnum=(p+q)/2;       //tnum爲當前數組中間數的索引	
	int tsum=count(a,p,q);  //統計中間數的重數	
	int left=start(a,p,q);  //找到當前數組中間數第一次出現的位置,記錄下來
	if(tsum>sum)            //如果中間數的重數大於sum,將中間數賦給num		
	{		
		sum=tsum;		
		num=a[tnum];		
	}	
	if(q-(left+tsum)>sum)  //如果當前數組右邊元素的個數大於重數sum,那麼右邊可能出現衆數,向右遞歸尋找		
	{		
		mode(a,left+tsum,q);		
	}	
	if(left>sum)        //如果當前數組左邊元素的個數大於重數sum,那麼左邊可能出現衆數,向左遞歸尋找		
	{ 		
		mode(a,0,left);		
	}	
}

//主函數
int main()
{   int arr[100]; //定一個100大小的整型數組
	int n;
	cin>>n;   
  	for(int i=0;i<n;i++)		
	{		
     	cin>>arr[i];	
	//	arr[i] = n;  //賦值1-100的數
	}
	mode(arr,0,n);	
	cout<<num<<endl;   //衆數
	cout<<sum<<endl;   //重數
	return 0;
}

/*cannot convert from ‘int *’ to ‘int []’
出錯報告說是賦值時發生錯誤,無法將整型數據轉化爲整型指針變量。
你不能把一個對象的值賦給指針,只能將一個對象的地址賦給指針。改成:p=&a[i];
*/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章