问题
有一个数组为{"Liu Yi", "Chen Er", "Zhang San", "Chen Er", "Chen Er", "Li Si", "Li Si", "Wang Wu"},
要求:
(1)把数组中没重复的字符串按原先的先后顺序打印出来
(2)把数组中有重复的字符串,按出现次数从少到多的顺序打印出来,每个字符串只打印一次
思路
把字符串作为key、出现次数作为value,存到map<string, int>中;
再把第一个map中的出现次数作为key、对应的字符串作为value,存到map<int, list<string>>中。
算法的时间复杂度为N。
代码
#include <iostream>
#include <map>
#include <list>
using namespace std;
#define len 8
int main()
{
string s[len] = {"Liu Yi", "Chen Er", "Zhang San", "Chen Er", "Chen Er", "Li Si", "Li Si", "Wang Wu"};
map<string, int> m;
map<int, list<string> > m2;
for(int i = 0; i < len; i++)
{
int cnt = 0;
if(m.count(s[i]) > 0)
{
cnt = m[s[i]];
}
m[s[i]] = ++cnt;
//把重复次数和list<string>存到另一个map中
list<string> li;
if(m2.count(cnt) > 0)
{
// 若key已经存在,则使用key所对应的list,而不是用新生成的list
li = m2[cnt];
}
if(cnt > 1)
{
// 若重复次数从n变为n+1(这里n大于或等于1)
// 要把元素从n所对应的list中移出,放到n+1所对应的list中
list<string> oldList = m2[cnt - 1];
oldList.remove(s[i]);
m2[cnt - 1] = oldList;
}
li.push_back(s[i]);
m2[cnt] = li;
}
map<int, list<string> >::iterator it;
for(it = m2.begin(); it != m2.end(); it++)
{
int cnt2 = it->first;
list<string> list2 = m2[cnt2];
list<string>::iterator it2;
for(it2 = list2.begin(); it2 != list2.end(); it2++)
{
cout << *it2 << endl;
}
}
return 0;
}
运行结果:
Liu Yi
Zhang San
Wang Wu
Li Si
Chen Er
更多内容请关注微信公众号
feicuisenlin_12x12.jpg
网友评论