我们假设字典大小为n,需要查询的单词数位m
如果直接拿每次遇到的单词与字典中的每个单词进行比较,时间复杂度O(mn)
如果我们先将字典排好序,并且每个单词也是排好序的,那么每次查询耗时O(logn),总的时间复杂度为O(nlogn+mlogn),在实际的应用中,我们可以先把字典排好序,以后每次查询的时间就是O(logn),如果不排序,每次查询要O(n),在字典较大和查询次数较多时,第二钟方法较好。
由于都是字符串,我们可以用STL提供的容器解决问题。
用string保存单词,用multimap保存字典中每个单词排序前和排序后的映射。主要,这里用了multimap,而不是map,由于字典中可能有几个单词排好序后是同一个单词,这就存在单对多的映射,map只是单对单的映射。
这里还有一个需要注意的地方就是,用multimap存单词映射时,如果关键字相同的话,那么这些值按插入的顺序存储,所以在输出结果的时候,要用一个set保存结果,然后再输出,这其实就是又进行了一次排序。
代码如下
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <set>
using namespace std;
multimap<string, string> ssmap;
multimap<string, string>::iterator ssiter;
void solve(vector<string> &strvec)
{
if (strvec.empty())
return;
size_t size = strvec.size();
for (int i = 0; i < size; i++)
{
string sortstr = strvec[i];
sort(sortstr.begin(), sortstr.end());
ssmap.insert(make_pair(sortstr, strvec[i]));
}
}
int main(void)
{
vector<string> strvector;
string str;
while (cin >> str)
{
if (str == "******")
break;
strvector.push_back(str);
}
solve(strvector);
while (cin >> str)
{
string sortstr = str;
sort(sortstr.begin(), sortstr.end());
ssiter = ssmap.find(sortstr);
if (ssiter == ssmap.end())
cout << ":(" << endl;
else
{
set<string> sset;
for (; ssiter != ssmap.end() && (*ssiter).first == sortstr; ++ssiter)
sset.insert((*ssiter).second);
set<string>::const_iterator ssetciter;
for (ssetciter = sset.begin(); ssetciter != sset.end(); ++ ssetciter)
cout << *ssetciter << " ";
cout << endl;
}
}
return 0;
}