分治法求解集合的众数及其重数
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.实验基本要求 2.实验亮点 二.实验内容与方法 三.实验步骤与过程 (一)一些准备工作 1.实验流程 2.数据生成与去除重复点 (二)暴力穷举法 1.算 ...
- 分治法 分治法求解递推式
分治法 分治法基本就是下面的三步 分(divide):无法有效解决的划分更小的问题 治(conquer):递归求每一个子问题的解 合(combine):合并解得出原问题解 MergeSort:排列 1 ...
- 分治法求解大整数乘法
算法导论课作业:分治法求解大整数乘法 – 学号:20204227058 求解思想 实现大整数乘法的方法有许多种,其中我们最简单的方法就是小学里面教的竖式算法,这种方法在计算过程中数AAA需要和数B ...
- 凸包问题 分治法求解
问题介绍 给定平面上一些点的集合,找到一些点,使得这些点形成一个凸的包围,围住所有的点,如图 思路 采用分治法,将点集合一分为二,整体的凸包问题可以分为[求上半部分的凸包]+[求下半部分的凸包] 分策 ...
- 快包_分治法求解凸包问题
凸包问题(分治法) 题目简述 P2742 [USACO5.1]圈奶牛Fencing the Cows 农夫约翰想要建造一个围栏用来围住他的奶牛,可是他资金匮乏.他建造的围栏必须包括他的奶牛喜欢吃草 ...
- 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 ...
- 输油管道问题-分治法求解
题目要求:某石油公司计划建造一条由东向西的主输油管道.该管道要穿过一个有n口油井的油田.从每口油井都要有一条输油管道沿最短路经(或南或北)与主管道相连. 如果给定n口油井的位置,即它们的x坐标(东西向 ...
- 分治法求解最大子数组问题
最大子数组问题求解 将数组A分成两部分,A[left...mid]和A[mid+1..right]两部分,求解最大子数组之和包含了三种可能的情况: 1.完全位于子数组A[left...mid]中,因此 ...
- 算法设计棋盘覆盖问题c语言,棋盘覆盖问题(用分治法求解)
// 棋盘覆盖 #include #include int Board[8][8]={0};//定义棋盘并初始化棋盘 void ChessBoard(int tr,int tc,int dr,int ...
最新文章
- golang 字符串拼接方式
- JAVA获取当前系统时间System.currentTimeMillis()
- 非确定性算法_使用最坏情况提高基于MPC的避障算法对参数不确定性的鲁棒性
- .NET之Docker部署详细流程
- linux tomcat 发布servlet,SpringBoot项目使用war包部署至云服务器(Linux+Tomcat)
- sklearn中的train_test_split函数
- exe软件打包工具哪个好_小视频制作软件哪个好?推荐五款超赞小视频制作工具...
- Matlab系列教程_基础知识_数据类型
- vb调用摄像头实现拍照源码_牛逼!终于搞了一个高大上的人脸识别登录玩玩(附源码),出乎意料的简单......
- SQL Server 数据库之数据约束
- houdini 常用
- Sobel 边缘检测 matlab代码实现
- 卡巴斯基安全部队 2012 (KIS 2018) 激活key (9月5日更新)=最新卡巴斯基永久激活码
- UVA12304 2D Geometry 110 in 1!
- 机器学习-训练了一个高效快速识别身份证正面关键信息的模型
- 05_CSS 盒模型
- #include指令引号与尖括号的区别
- 农村大学生的逆袭--025愉快的年夜饭
- 内存不能read written常见原因
- 8个好玩又实用的神奇网站,帮你打开新世界大门!
热门文章
- 最新Java面试题(附答案)
- Excel快速将自己的名字识别为二维码
- python os.environ.set_django os.environ慎用setdefault操作环境变量
- 1977年失踪事件_1977年黄延秋事件,不是首次发生,古籍中的早已多次记录
- CKEditor在线编辑器
- Android 4.3安全機制探討
- ubuntu安装nvidia显卡驱动后黑屏,进不去Ubuntu系统
- 想做一个手机点歌的程序,希望大家进来指点
- 计算机网络自上而下第六版答案,《计算机网络: 自顶向下方法》(第六版) 第一章习题...
- Windows10崩溃,在桌面不断闪烁黑屏