吧一個字典中,有換一個字母還是一個單詞並且超過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;
}