第四版map set 实现章节(P143) 书中提到的 :编写一个程序来找出通过单个字母的替换可以变成至少15个其他的单词的单词。
如: 单词wine 可以变成dine、fine、line、nine、pine、或vine。
单词wine 可以变成wind、wing、wink、wins。
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <iterator>
using namespace std;
/*
* describe:
* 检测两个单词是否在一个字母上
* 如果word1 和word2 具有相同的长度
* 并且只有一个字母不同,返回true
*/
bool oneCharOff(const string & word1, const string & word2)
{
if (word1.length() != word2.length())
return false;
int diffs = 0;
for (size_t i = 0; i < word1.length(); ++i)
{
if (word1[i] != word2[i])
if (++diffs > 1)
return false;
}
return diffs == 1;
}
/*
* describe:
* 计算map对象,其中关键字为单词,值为单词的vector
* vector 中的这些单词只在一个字母上不同于对应的关键字
* 使用一个高效的算法,该算法用到一个map运行的时间为O(N logN)
*/
map<string, vector<string>> computeAdjacentWords(const vector<string> & words)
{
map<string, vector<string>> adjWords;
map<int, vector<string>> wordsByLength;
/*将单词按照它们的长度分组*/
for (auto & str : words)
wordsByLength[str.length()].push_back(str); /* [] 访问的是map<int,vector> int对应的值,返回的对象是vector,故可以调用push_back
*/
/*对每组分别处理*/
for (auto & entry : wordsByLength)
{
const vector<string> & groupsWords = entry.second;
int groupNum = entry.first;
/* 对每组的每一个位置进行处理 */
for (size_t i = 0; i < groupNum; ++i)
{
/*删除特定位置上的字母,算出代表*/
/* 具有相同代表的单词是相邻的;填充map... */
map<string, vector<string>> repToWord;
for (auto & str : groupsWords)
{
string rep = str;
rep.erase(i,1);
repToWord[rep].push_back(str);
}
/*然后查找那些具有多个一个串的map 值*/
for (auto & entry : repToWord)
{
const vector<string> & clique = entry.second;
if(clique.size()>=2)
for(int p=0;p<clique.size();++p)
for (int q = p + 1; q < clique.size(); ++q)
{
adjWords[clique[p]].push_back(clique[q]);
adjWords[clique[q]].push_back(clique[p]);
}
}
}
}
return adjWords;
}
void printMap_str_vec(map<string, vector<string>> & mpSV)
{
auto itr = mpSV.begin();
for (; itr != mpSV.end(); itr++)
{
cout << itr->first << ": ";
for (int i = 0; i < itr->second.size(); i++)
{
cout << itr->second.at(i) << " ";
}
cout << endl;
}
cout << endl;
}
int main()
{
string str = { "word" };
string str1 = { "nord" };
cout << oneCharOff(str, str1) << endl;
/*单词不能重复,如果处理文本单词,最好先用set 去重*/
vector<string> vec = { "ine","dine","wine","nine","mine","vine","pine","line" };
vector<string> vec1 = {"boot","mine","hoot","wak","lot","los","lof","soot","zoo","zoot","wat"};
vector<string> vec2 = {"wine","dine","fine","line","mine","vine",
"wind","wing","wink","wins"};
map<string, vector<string>> mpc, mpc1,mpc2;
mpc = computeAdjacentWords(vec);
mpc1 = computeAdjacentWords(vec1);
mpc2 = computeAdjacentWords(vec2);
printMap_str_vec(mpc);
printMap_str_vec(mpc1);
cout << "\n Test vec2: " << endl;
printMap_str_vec(mpc2);
return 0;
}
Test vec2测试结果: