题目背景:
给定一个数组,已知数组大小,其中有已知数字大小范围的一组数字,统计其中出现次数最多的数字及其出现次数
解决方法:空间换时间
(1)申请一块与数字大小范围一致的内存空间(例如数组),数组下标加1与数字值一 一对应,该块空间中存放该数字出现的次数。
遍历测试数组,将每个数字出现的次数映射到申请的数组中,
通过两次遍历记录数组,第一次遍历记录下出现的最大次数max,第二次遍历打印出所有出现max次的数字。
(此处为什么要两次遍历而不一次遍历时同时存储出现的最大次数和相应的下标值呢? 因为可能有不同数字出现同样多的次数,一次遍历时会被覆盖)
数组实现的代码如下:(以少量数据为示意)
int testarray[20]={2,4,5,6,7,7,5,3,4,6,8,6,4,1,7,8,5,3,3,9};
int recordarray[10]={0};
int max=0;
int record=0;
for(int i=0;i<20;i++)
{
int index = testarray[i]-1;
recordarray[index]++;
}
for(int i=0;i<10;i++)
{
if(max<recordarray[i])
{
max=recordarray[i];
record=i+1;
}
}
注意此处留下了一次遍历的代码,实际是有bug的。 应再加for循环修正。
for(int i=0;i<10;i++)
{
if(max==recordarray[i])
{
cout<<i+1<<" "<<max<<endl;
}
}
(2)用map,思想一样,但是(key,value)对以出现数字为key值,以数字出现次数为value值存放信息。
而且map实现的是只存储出现的数字。
(省了内存空间了吗?不见得,它一组用的是两个int空间啊)
但是可以省遍历时间,不用在数字范围内全部遍历一遍
此处主要是学习下map的插入及遍历。
一个map是一个键值对序列,即(key,value)对
map中key值是唯一的
map可以直接存取key所对应的value,支持[]操作符,如map[key]=value
map.insert(…); //往容器插入元素,返回pair<iterator,bool>
直接上代码
map<int,int>M;
for(int i = 0;i<20;i++)
{
pair<map<int,int>::iterator,bool> pairIt=M.insert(pair<int,int>(testarray[i],1));
if(pairIt.second!=true)
{
M[testarray[i]]++;
}
}
for(map<int,int>::iterator it=M.begin();it!=M.end();it++)
{
pair<int,int>pr=*it;
if(pr.second>max)
{
max=pr.second;
}
}
for(map<int,int>::iterator it=M.begin();it!=M.end();it++)
{
pair<int,int>pr=*it;
if(pr.second==max)
{
cout<<"num:"<<pr.first<<","<<"times:"<<max<<endl;
}
}
因为key值唯一,所以插入返回值为假时,说明该数字又出现一次,value值要加一。