算法設計--衆數和重數問題(分治法)

問題描述:
給定含有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
請按任意鍵繼續. . .
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章