zoukankan      html  css  js  c++  java
  • 分治法求众数问题 (配图)

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


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

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


    详细代码:


    // 用分治法求众数
    
    #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
    ", num, maxCnt);
    
        return 0;
    }
    



    大概思路图:






  • 相关阅读:
    佛教:禅宗和净土--佛教的归途
    佛教:从精英到世俗
    佛教:神迹的演变。
    收藏品:MP3播放器
    淘书百胜楼
    Spring注解是如何生效的?
    logstash6.8.3 导入 CSV 文件到 ElasticSearch
    三个线程交替按顺序打印ABC之条件队列的理解
    谈谈多线程
    ElasticSearch如何更新集群的状态
  • 原文地址:https://www.cnblogs.com/yangykaifa/p/7162192.html
Copyright © 2011-2022 走看看