ps:下面是我上网找来后进行修改的,之前会出现结果出错的问题,修改了cnt的赋值之后就可以了,但是!!!这个程序还有个bug没解决,就是对数组元素的中位数有重数的运算不会出错,没有的话就会陷入死循环,问题应该在于分割数组那里,不过等我找到再说吧,也希望大神来指引下我~(已解决)
现在说下算法思路,这个多重数问题其实和书本讲的分治法的一个例子有点类似(二分搜索),找到已排序的数组的中位数,将数组分成两部分,先拿到中位数的重数,然后进行判断,决定是否需要向左递归或是向右递归,之前没有关注到数已经排序的了,所以就一直很疑惑。排序了的数组,重数也是连在一起的,所以从l(左边)开始找,找到开始的,再找结尾的,卒子后第一次cnt =r -l 就是中位数的重数,拿到之后,就可以进行判断,首先判断左边元素数量的是否大于中位数重数,如果有,那就是在下标从0 到 l+1的元素中进行同样的处理(找到中位数,向左或向右),右边元素同理;最后maxcnt就是重数,num就是那个元素
ps:发出这个博客十分钟后修改了向左执行递归的条件就可以了嘿嘿嘿
if(l+1 > maxCnt){
if(l ==1){
return;
}else{
getMaxCnt(mid, maxCnt, arr, l+1);
}
}
以下是源码以及注释
#include <iostream>
using namespace std;template<class T>
/*
*判断数组长度
*/
int getArrayLen(T& array){
return (sizeof(array) / sizeof(array[0]));
}/*
*打印数组
*/
void showArray(int array[],int len)
{
int i;
printf("此数组元素为:");
for(i=0;i<len;i++){
printf("%d",array[i]);
}
printf("\n");
}
/*
*分割数组
*第一次循环拿到中位数的个数,之后就用中位数作为标准进行比较
*/
void split(int arr[],int len,int &l,int &r){
int mid = len/2;
for(l = 0; l<len; ++l){
if(arr[l] == arr[mid])
break;
}for(r = l+1;r<len;++r){
if(arr[r] != arr[mid])
break;
}
}//num表示众数 maxCnt表示重数 注意mid和maxCnt的指针运用
void getMaxCnt(int &mid,int &maxCnt, int arr[],int len){
showArray(arr,len);
int l ,r;
split(arr,len,l,r); //将数组进行切割成两端
int num = len/2;
int cnt = r - l;
printf("num的值为:%d,r的值为:%d,l的值为:%d,cnt的值为:%d,maxcnt的值为:%d,len的值为:%d\n",num,r,l,cnt,maxCnt,len);
if(cnt > maxCnt){
maxCnt = cnt;
mid = arr[num];
}
//l表示左边的个数,左边的个数必须大于中位数的个数,才有进行搜索的意义
if(l+1 > maxCnt){
if(l ==1){
return;
}else{
getMaxCnt(mid, maxCnt, arr, l+1);
}
}//同理,右边的个数将要大于中位数的个数才有继续搜寻的意义,同时右边数组的起始位置进行改变
if(len-r > maxCnt){
getMaxCnt(mid, maxCnt, arr+r, len-r);
}
}int main()
{
int arr[] = {1,1,1,2,3,4,6};
int len = getArrayLen(arr);int maxCnt = 0;
int num = 0;
getMaxCnt(num ,maxCnt, arr, len);
printf("%d %d\n",num,maxCnt);
return 0;
}