吧一个字典中,有换一个字母还是一个单词并且超过15个的打出来。
#include<map>
#include<string>
#include<vector>
#include<iostream>
using namespace std;
/*
*map应用的简单例子,说明了一些时候map怎么工作
map<string,double>salaries;
salaries["Pat"]=75000; //左边调用operator[],因此插入“Pat”和一个值为0的double到map,同属返回这个double的引用,然后赋值将map中的double改为75000
cout<<salaries["Pat"]<<endl; //这个是可以输出来的
cout<<salaries["Jan"]<<endl; //这个不一定,要看程序,还有,玄学.....
map<string,double>::const_iterator itr;
itr=salaries.find("Chris");
if(itr==salaries.end())
cout<<"Not ..."<<endl;
else
cout<<itr->second<<endl; //如果上面不是const_iterator,那么这里就可以给itr->second赋值了。
*/
/*《数据结构与算法剖析》,这本书里的137页例子,
找出来替换一个字母能形成15个以上单词的单词,
解决办法就是用map,键存这个单词,值是一个vectro,存替换一个字母形成的单词们
*/
//构造了map后,直接检查是不是至少15个,然后打印结果
void printHighChangeables(const map<string,vector<string>> & adjWords,int minWords=15);
void printHighChangeables(const map<string, vector<string>> & adjWords, int minWords = 15)
{
map<string, vector<string>>::const_iterator itr;
for (itr = adjWords.begin(); itr != adjWords.end(); ++itr)
{
const pair<string, vector<string>> &entry = *itr; //pair是一个模板,就是理解成一个对就好了,这里就是这个pair有两个元素,first类型是string,second类型是vector<string>
const vector<string> words = entry.second;
if (words.size() >= minWords)
{
cout << entry.first << "(" << words.size() << "):";
for (int i = 0; i < words.size(); i++)
{
cout << "" << words[i];
}
cout << endl;
}
}
}
//构造map的一个暴力方法,写一个函数,比较两个单词,是不是只有一个字母不一样,之后二层for循环所有的单词,挨个比较,思路比较简单,时间复杂度很心酸
bool oneCharoff(const string & word1, const string & word2)
{
if (word1.length() != word2.length())
{
return false;
}
int diff = 0;
for (int i = 0; i < word1.length(); i++)
{
if (word1[i] != word2[i])
if (++diff > 1)
return false;
}
return diff == 1;
}
//把words形成map
map<string, vector<string>> computeAdjacentWords(const vector<string> & words)
{
map<string, vector<string>> adjWords;
for (int i = 0; i < words.size(); i++)
{
for (int j = i + 1; j < words.size(); j++)
{
if (oneCharoff(words[i], words[j]))
{
adjWords[words[i]].push_back(words[j]);
adjWords[words[j]].push_back(words[i]);
}
}
}
return adjWords;
}
//第二种,还是一个map,但是键变成了单词的长度,然后把相同长度的放在一起,然后跟上面一样的过程,加一个循环每个单词组
map<string, vector<string>> computeAdjacentWords(const vector<string> & words)
{
map<int, vector<string>> KeyLength;
map<string, vector<string>> adjWords;
for (int i = 0; i < words.size(); i++)
{
KeyLength[words[i].length()].push_back(words[i]);
}
map<int, vector<string>>::const_iterator itr;
for (itr = KeyLength.begin(); itr != KeyLength.end(); itr++)
{
const vector<string> & groupsWords = itr->second; //这个刚开始没写,这样会方便点,否则容易看晕......
for (int i = 0; i < groupsWords.size(); i++)
for (int j = i + 1; j < groupsWords.size(); j++)
{
if (oneCharoff((groupsWords)[i], (groupsWords)[j]))
{
adjWords[(groupsWords)[i]].push_back((groupsWords)[j]);
adjWords[(groupsWords)[j]].push_back((groupsWords)[i]);
}
}
}
return adjWords;
}
//这一种会更快,原理是这样的,把每个长度相同的词的集合,按照去掉一个字母一样分(加一个map),比如,wine,wife就分到wie组里,这样就能很快的构造出最后的那个map(adjWords)
map<string, vector<string>> computeAdjacentWords(const vector<string> & words)
{
map<int, vector<string>> KeyLength;
map<string, vector<string>> adjWords;
for (int i = 0; i < words.size(); i++)
{
KeyLength[words[i].length()].push_back(words[i]);
}
map<int, vector<string>>::const_iterator itr;
for (itr = KeyLength.begin(); itr != KeyLength.end(); itr++)
{
const vector<string> & groupsWords = itr->second;
int groupLen = itr->first;
for (int i = 0; i < groupLen; i++)
{
map<string, vector<string>> Same;
for (int j = 0; j < groupsWords.size(); j++)
{
string rep = groupsWords[j];
rep.erase(i, 1);
Same[rep].push_back(groupsWords[j]);
}
map<string, vector<string>>::const_iterator itr2;
for (itr2 = Same.begin(); itr2 != Same.end(); itr2++)
{
const vector<string>& sepreate = itr2->second;
if (sepreate.size() >= 2)
for (int p = 0; p < sepreate.size(); p++)
for (int q = p + 1; q < sepreate.size(); q++)
{
adjWords[sepreate[p]].push_back(sepreate[q]);
adjWords[sepreate[q]].push_back(sepreate[p]);
}
}
}
}
return adjWords;
}