分治法求眾數問題 (配圖)


分治法求眾數問題 (配圖)


採用分治法。以中間為界限。 先計算環繞中間這個數字的眾數情況。然后左右分開遞歸計算結果,取最值就可以。

左右遞歸計算的時候要先做推斷。假如左邊或是右邊的個數都比已求的重數小。就不是必需計算了。即使左邊或是右邊所有都是一樣的。那么他的重數也是小於已求的,所以不是必需進行運算,這一周在加深分治算法的學習,這題着實花了我不少時間。


詳細代碼:


// 用分治法求眾數

#include <iostream>
#include <cstdio>

using namespace std;

// 本程序的關鍵。 以中間的數字為界限。 確定左右起始和終止界限
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-l;

    // update
    if (cnt > maxCnt)
    {
        maxCnt = cnt;
        mid = s[num];
    }

    // l 表示左邊的個數。左邊的個數必須大於 maxCnt 才有必要搜尋
    if (l+1 > maxCnt)
    {
        getMaxCnt(mid, maxCnt, s, l+1);
    }

    // 右邊搜尋, 右邊數組的起始地址要變更
    if (n-r > maxCnt)
    {
        getMaxCnt(mid, maxCnt, s+r, n-r);
    }
}

int main(void)
{
    int s[] = {1, 2, 2, 2, 3, 3, 5, 6, 6, 6, 6};
    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;
}



大概思路圖:







免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM