問題描述:
給定含有n個元素的多重集合S,每個元素在S中出現的次數稱爲該元素的重數。多重集S中重數最大的元素稱爲衆數。例如,S={1,2,2,2,3,5}。多重集S的衆數是2,其重數爲3。對於給定的n個自然數組成的多重集S,計算S的衆數及其重數 。
問題分析:
1、 分治法
分治法解題過程主要分爲分、治、合三個步驟“,應用該方法的基本過程如下:
(1) 將原問題分解爲若干個規模較小的子問題
(2) 對這些子問題分別求解
(3) 對各個子問題的解進行合併
2、 衆數:一組數據中出現次數最多的數值,叫衆數。有時一組數據中有多個衆數。
重數:重數是指該衆數出現的次數。
3、 根據以下實例理解分治法求解衆數及其重數
給定含有n個元素的多重集合S,每個元素在S中出現的次數稱爲該元素的重數。多重集S中重數最大的元素稱爲衆數。
例如,S = {1,2,2,2,3,5}。
多重集S的衆數是2,其重數是3.
算法實現:
// Test_01.cpp : 定義控制檯應用程序的入口點。
//
#include "stdafx.h"
void split(int s[],int n,int &l,int &r){
int mid = n/2;
for(l = 0; l<n; ++l){
if(s[l] == s[mid])
break;
}
for(r = l+1;r<n;++r){
if(s[r] != s[mid])
break;
}
}
//num表示衆數 maxCnt表示重數
void getMaxCnt(int &mid,int &maxCnt, int s[],int n){
int l ,r;
split(s,n,l,r); //將數組進行切割成兩端
int num = n/2;
int cnt = r - 1;
if(cnt > maxCnt){
maxCnt = cnt;
mid = s[num];
}
//l表示左邊的個數,左邊的個數必須大於中位數的個數,纔有進行搜索的意義
if(l+1 > maxCnt){
getMaxCnt(mid, maxCnt, s, l+1);
}
//同理,右邊的個數將要大於中位數的個數纔有繼續搜尋的意義,同時右邊數組的起始位置進行改變
if(n-r > maxCnt){
getMaxCnt(mid, maxCnt, s+r, n-r);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int s[] = {1,2,2,2,3,5};
int n = sizeof(s)/sizeof(s[0]);
int maxCnt = 0;
int num = 0;
getMaxCnt(num ,maxCnt, s, n);
printf("%d %d\n",num,maxCnt);
return 0;
}
運行結果
由於初始數組爲int s[] = {1,2,2,2,3,5};所以運行結果中衆數爲 2 重數爲 3
2 3
請按任意鍵繼續. . .