1. 分治法

分治法解题过程主要分为分、治、合三个步骤“,应用该方法的基本过程如下:
(1) 将原问题分解为若干个规模较小的子问题
(2) 对这些子问题分别求解
(3) 对各个子问题的解进行合并

2. 众数与重数

众数:一组数据中出现次数最多的数值,叫众数。有时一组数据中有多个众数。
重数:重数是指该众数出现的次数。

3. 实例

给定含有n个元素的多重集合S,每个元素在S中出现的次数称为该元素的重数。多重集S中重数最大的元素称为众数。
例如,S = {1,2,2,2,3,5}。
多重集S的众数是2,其重数是3.
数据输入:6 1 2 2 2 3 5
结果输出:2 3

(1) 首先讲一下我在解决这个问题是参考的网上的答案,代码如下:

#include<stdio.h>
#include<stdlib.h>
#define M 20
int number=0;//number表示众数
int sum=0;//sum表示该众数的重数
int Partition(int a[],int p,int r)//在a[p]到a[r-1]中随机选择一个元素作为主元
{   int x=a[r-1];int i=p-1;int temp,j;for(j=p;j<=r-2;j++){ if(a[j]<=x){   i++;temp=a[i];a[i]=a[j];a[j]=temp;}}temp=a[i+1];a[i+1]=a[r-1];a[r-1]=temp;return i+1;
}
int Count(int a[],int x,int p,int r)//统计数组中与x相等的元素的个数并返回
{int count=0,i;for( i=p;i<r;i++){if(a[i]==x)count++;}return count;
}
void Modal(int a[],int p,int r)//通过分治法得到数组的众数和该众数的重数
{if(p<r){int q=Partition(a,p,r);//统计分解法的主元出现的个数int temp=Count(a,a[q],p,q+1);if(sum<temp){sum=temp;number=a[q];}      if(q-p-sum>sum)//如果该元素以左的个数大于重数,向左递归Modal(a,p,q); else if(r-q-1>sum)//如果该元素以右的个数大于重数,向右递归Modal(a,q+1,r);}
}
int main()
{int num[M],temp,n;int i=0,j=0;scanf("%d",&n);for(i=0;i<n;i++){scanf("%d",&num[i]);}printf("\n");Modal(num,0,n);printf("众数为:%d\n",number);printf("\n"); printf("重数为:%d\n",sum);
}

【我的理解】这的确是个分治法求解众数及其重数的算法,而且设计过程中充分地考虑了已经求解了的问题,利用已求解问题尽量排出不必要的运算。但是该实现有很大的问题,用一些数组进行测试就可以发现,如用int[] num = {1,2,7,7,3,5};进行测试,将无法得到正确答案。

(2) 站在巨人的肩膀上,我对以上实现进行了改进:
上面参考答案使用c语言来实现的,我这里用java进行实现,其实这并不影响算法的理解。


public class SearchMode_2
{static int number = 0;// number表示众数static int sum = 0;// sum表示该众数的重数/** 将数组a[]中从第p个到第r个数据已最后一个数据为主元素进行排序。* 主元素左边的为小于或等于主元素的元素,右边为大于主元素的元素* * 注意主元素两侧的数据是没有排好序的。这也就是在递归调用Modal()方法是只能+1或者-1而不是-temp的原因。*/int Partition(int a[], int p, int r)// 在a[p]到a[r]中随机选择一个元素作为主元{int x = a[r];int i = p - 1;int temp, j;for (j = p; j <= r - 1; j++){if (a[j] <= x){i++;temp = a[i];a[i] = a[j];a[j] = temp;}}temp = a[i + 1];a[i + 1] = a[r];a[r] = temp;return i + 1;}//统计数组a[]中从从第p个到第r个数据中有几个等于Xint Count(int a[], int x, int p, int r)// 统计数组中与x相等的元素的个数并返回{int count = 0, i;for (i = p; i <= r; i++){if (a[i] == x)count++;}return count;}//递归调用该方法找出众数number及其重数sumvoid Modal(int a[], int p, int r)// 通过分治法得到数组的众数和该众数的重数{if (p < r){int q = Partition(a, p, r);// 统计分解法的主元出现的个数int temp = Count(a, a[q], p, q);if (sum < temp){sum = temp;number = a[q];}//if (q - p + 1 - temp > sum) // 如果该元素以左的个数大于重数,向左递归Modal(a, p, q - 1);//else if (r - q > sum) // 如果该元素以右的个数大于重数,向右递归Modal(a, q + 1, r);}}public static void main(String[] args){int[] num = {2,4,7,8,5,6,5,5,6,7,1};
//      int[] num = {1,2,7,7,3,5};
//      int[] num = {3,6,7,6,4,5};SearchMode_2 SearchMode_2 = new SearchMode_2();SearchMode_2.Modal(num,0,num.length-1);System.out.println("众数为: "+ number);System.out.println("重数为: "+ sum);}}

对比上下两份代码可知,我把上面代码的Modal()方法中的判断删除了,并对递归调用时的参数进行了适当的修改,以减少不必要的运算。

4. 结语

希望以上代码对你有帮助,同时也感谢网友提供的参考代码。如有不同意见或者发现错误之处,欢迎指正。

分治法求解集合的众数及其重数相关推荐

  1. 算法设计与分析 实验二 分治法求解最近点对问题

    分治法求解最近点对问题 一.实验目的与要求 1.实验基本要求 2.实验亮点 二.实验内容与方法 三.实验步骤与过程 (一)一些准备工作 1.实验流程 2.数据生成与去除重复点 (二)暴力穷举法 1.算 ...

  2. 分治法 分治法求解递推式

    分治法 分治法基本就是下面的三步 分(divide):无法有效解决的划分更小的问题 治(conquer):递归求每一个子问题的解 合(combine):合并解得出原问题解 MergeSort:排列 1 ...

  3. 分治法求解大整数乘法

    算法导论课作业:分治法求解大整数乘法 – 学号:20204227058 求解思想 ​ 实现大整数乘法的方法有许多种,其中我们最简单的方法就是小学里面教的竖式算法,这种方法在计算过程中数AAA需要和数B ...

  4. 凸包问题 分治法求解

    问题介绍 给定平面上一些点的集合,找到一些点,使得这些点形成一个凸的包围,围住所有的点,如图 思路 采用分治法,将点集合一分为二,整体的凸包问题可以分为[求上半部分的凸包]+[求下半部分的凸包] 分策 ...

  5. 快包_分治法求解凸包问题

    凸包问题(分治法) 题目简述 P2742 [USACO5.1]圈奶牛Fencing the Cows   农夫约翰想要建造一个围栏用来围住他的奶牛,可是他资金匮乏.他建造的围栏必须包括他的奶牛喜欢吃草 ...

  6. java 循环赛问题,网球循环赛思路 - 分治法求解(无代码)

    分治法: 列出人数为的情况: K = 1 1 2 2 1 其中第一列是选手的序号,之后n列代表着选手的对手 K = 2 1 2 3 4 2 1 4 3 3 4 1 2 4 3 2 1 可以看出,k=4 ...

  7. 输油管道问题-分治法求解

    题目要求:某石油公司计划建造一条由东向西的主输油管道.该管道要穿过一个有n口油井的油田.从每口油井都要有一条输油管道沿最短路经(或南或北)与主管道相连. 如果给定n口油井的位置,即它们的x坐标(东西向 ...

  8. 分治法求解最大子数组问题

    最大子数组问题求解 将数组A分成两部分,A[left...mid]和A[mid+1..right]两部分,求解最大子数组之和包含了三种可能的情况: 1.完全位于子数组A[left...mid]中,因此 ...

  9. 算法设计棋盘覆盖问题c语言,棋盘覆盖问题(用分治法求解)

    // 棋盘覆盖 #include #include int Board[8][8]={0};//定义棋盘并初始化棋盘 void ChessBoard(int tr,int tc,int dr,int ...

最新文章

  1. golang 字符串拼接方式
  2. JAVA获取当前系统时间System.currentTimeMillis()
  3. 非确定性算法_使用最坏情况提高基于MPC的避障算法对参数不确定性的鲁棒性
  4. .NET之Docker部署详细流程
  5. linux tomcat 发布servlet,SpringBoot项目使用war包部署至云服务器(Linux+Tomcat)
  6. sklearn中的train_test_split函数
  7. exe软件打包工具哪个好_小视频制作软件哪个好?推荐五款超赞小视频制作工具...
  8. Matlab系列教程_基础知识_数据类型
  9. vb调用摄像头实现拍照源码_牛逼!终于搞了一个高大上的人脸识别登录玩玩(附源码),出乎意料的简单......
  10. SQL Server 数据库之数据约束
  11. houdini 常用
  12. Sobel 边缘检测 matlab代码实现
  13. 卡巴斯基安全部队 2012 (KIS 2018) 激活key (9月5日更新)=最新卡巴斯基永久激活码
  14. UVA12304 2D Geometry 110 in 1!
  15. 机器学习-训练了一个高效快速识别身份证正面关键信息的模型
  16. 05_CSS 盒模型
  17. #include指令引号与尖括号的区别
  18. 农村大学生的逆袭--025愉快的年夜饭
  19. 内存不能read written常见原因
  20. 8个好玩又实用的神奇网站,帮你打开新世界大门!

热门文章

  1. 最新Java面试题(附答案)
  2. Excel快速将自己的名字识别为二维码
  3. python os.environ.set_django os.environ慎用setdefault操作环境变量
  4. 1977年失踪事件_1977年黄延秋事件,不是首次发生,古籍中的早已多次记录
  5. CKEditor在线编辑器
  6. Android 4.3安全機制探討
  7. ubuntu安装nvidia显卡驱动后黑屏,进不去Ubuntu系统
  8. 想做一个手机点歌的程序,希望大家进来指点
  9. 计算机网络自上而下第六版答案,《计算机网络: 自顶向下方法》(第六版) 第一章习题...
  10. Windows10崩溃,在桌面不断闪烁黑屏