码迷,mamicode.com
首页 > 其他好文 > 详细

分治法求众数问题 (配图)

时间:2015-08-10 02:00:32      阅读:620      评论:0      收藏:0      [点我收藏+]

标签:

分治法求众数问题 (配图)


采用分治法,以中间为界限, 先计算围绕中间这个数字的众数情况,然后左右分开递归计算结果,取最值即可。

左右递归计算的时候要先做判断,假如左边或是右边的个数都比已求的重数小,就没必要计算了,即使左边或是右边全部都是一样的,那么他的重数也是小于已求的,所以没必要进行运算,这一周在加深分治算法的学习,这题着实花了我不少时间。


具体代码:


// 用分治法求众数

#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;
}



大概思路图:

技术分享





版权声明:本文为博主原创文章,未经博主允许不得转载。 http://blog.csdn.net/core__code

分治法求众数问题 (配图)

标签:

原文地址:http://blog.csdn.net/core__code/article/details/47385045

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!