问题描述:
给定含有 n 个元素的多重集合 S,每个元素在 S 中出现的次数称为该元素的重数。多重集 S 中重数最大的元素称为众数。例如,S={1,2,2,2,3,5}。多重集 S 的众数是 2,其重数为 3。
编程任务:
对于给定的由 n 个自然数组成的多重集 S,编程计算 S 的众数及其重数。
数据输入:
输入数据由文件名为 input.txt 的文本文件提供。
文件的第 1 行多重集 S 中元素个数 n;接下来的 n 行中,每行有一个自然数。
结果输出:
程序运行结束时,将计算结果输出到文件 output.txt 中。输出文件有 2 行,第 1 行给
出众数,第 2 行是重数。
输入文件示例
input.txt
6
1
2
2
2
3
5
输出文件示例
output.txt
2
3
思路:
- 排序
- 二分法 找出 middle的个数
- 递归找左边数 middle的个数,和右边数middle的个数
- 找众数以及个数
代码:
#include <iostream>
#include <algorithm>
#include <vector>
#include <math.h>
using namespace std;
class File
{
public :
vector<int> getNum (string path)
{
FILE *f=fopen(path.c_str(),"r");
vector<int> ve;
int num;
while(fscanf(f,"%d",&num)!=EOF)
{
ve.push_back(num);
}
fclose(f);
return ve;
}
vector<int> answer(string path)
{
FILE *f=fopen(path.c_str(),"r");
vector<int> ve;
int num;
while(fscanf(f,"%d",&num)!=EOF)
{
ve.push_back(num);
}
fclose(f);
return ve;
}
bool compare(vector<int>ve,int a[],int N)
{
for(int i=0; i<N; i++)
{
if(a[i]!=ve[i])
return false;
}
return true;
}
};
void func(vector<int> ve,int l,int r,int &count,int &number)
{
if(l>r)
return ;
int ll=0,rr=0;
int mid=(l+r)/2;
while((mid-ll>=l)&&(ve[mid-ll]==ve[mid]))
{
ll++;
}
while((mid+rr<=r)&&(ve[mid+rr]==ve[mid]))
{
rr++;
}
int c=ll+rr-1;
if(count<=c)
{
count=c;
number=ve[mid];
}
if(mid-ll+1>=count)
func(ve,mid+rr,r,count,number);
if(r-mid-rr+1>=count)
func(ve,l,mid-ll,count,number);
}
int main()
{
File f;
bool temp=true;
int count;
for(int k=1;k<=10;k++)
{
vector<int> ve=f.getNum("F:\\算法\\实验组2-分治-实验包\\prog21\\test\\mode"+to_string(k)+".in");
int n=ve[0];
sort(ve.begin()+1,ve.end());
count=0;
int number=0;
func(ve,1,n-2,count,number);
int an[2];
an[0]=number;
an[1]=count;
vector<int> ve2;
ve2=f.answer("F:\\算法\\实验组2-分治-实验包\\prog21\\answer\\mode"+to_string(k)+".out");
bool flag=true;
flag=f.compare(ve2,an,2);
if(!flag)
{
cout << "第" << k << "个测试用例未通过" << endl;
temp=false;
}
else
cout << "第" << k << "个测试用例通过" << endl;
ve.clear();
ve2.clear();
}
if(temp)
cout << "测试用例全部通过" << endl;
}