字母重排 stl


我们假设字典大小为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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值