首先想到用map,但是题目说qq和ip是多对多的关系。
output format : $qq ==> [ $ip1 $ip2 ... ] and $ip ==> [ $qq1 $qq2 ... ]
然后想到用两个map,但是程序的效率应该不够理想
然后想到用multimap
typedef multimap<string,int> M;
typedef M::value_type v_t;
这样v_t(qq, ip)和make_pair(qq, ip)的作用是一样的。
另外,map不能有重复的键值对,即如果插入键相同的键值对,则将覆盖掉同键值的键值对。multimap则不会覆盖。似乎multimap中的主键会自动字典排序?但是对此题没有帮助,此题是找到key后按字典序输出key的所有second(不重复)
错误案例1:
M::iterator upp = m2.upper_bound(ip);
M::iterator it;
it = m2.find(ip);
if (it == m2.end()) {
cout << "no ip" << endl;
} else {
cout << ip << " ==> [";
while (it != upp) {
cout << " " << (*it).second;
it++;
}
cout << " ]" << endl;
}
这样输出的结果是
+---------------------------------------------------------------------
001 |192.168.1.45 ==> [ 10258279649 ]
002 |10258279649 ==> [ 192.168.1.45 ]
003 |
+---------------------------------------------------------------------
改正后:使用了较笨的方法(存入字符串数组后排序)
it = m2.find(ip);
if (it == m2.end()) {
cout << "no qq" << endl;
} else {
it = m2.begin();
while (it != m2.end()) {
if ((*it).first == ip) {
temp[k] = (*it).second;
k++;
}
it++;
}
sort(temp);
cout << qq << " ==> [";
print(temp);
}
题外话:数组作为函数参数
void sort(string temp[]) {
……
}
sort(temp);
temp是temp数组的头指针,所以这样是能达到效果的。
标程:
map<string, set<string> > ip2qq;
map<string, set<string> > qq2ip;
int n;
string qq, ip;
cin >> n;
while (n--) {
cin >> qq >> ip;
ip2qq[ip].insert(qq);
qq2ip[qq].insert(ip);
}
把set容器作为map的第二个元素,实现一对多,且set能自动达到去重目的。
map<string, set<string> >::iterator it;
set<string>::iterator its;
cin >> ip;
if (ip2qq.find(ip) == ip2qq.end()) {
cout << "no qq" << endl;
} else {
cout << ip << " ==> [ ";
for (its = ip2qq[ip].begin(); \
its != ip2qq[ip].end(); its++) {
cout << *its << " ";
}
cout << "]" << endl;
}
用指向set的迭代器实现输出相同key的second元素。