题解 | #查找兄弟单词#
查找兄弟单词
http://www.nowcoder.com/practice/03ba8aeeef73400ca7a37a5f3370fe68
语文阅读理解题了属于是。应该是我最长了,暂时不优化了,有注释非常好懂,看看吧。
#include<iostream>
#include<map>
#include<string>
#include<vector>
#include<unordered_map>
using namespace std;
vector<vector<string>> preHandler(string& s);//预处理输入数据
pair<int, string> findTheKOrderBro(vector<string>& word, string& bro, int k);//从预处理后的输入数据中生成兄弟单词
bool isBro(unordered_map<char, int>& m1, string s2);//判断一个单词是否是bro的兄弟单词,辅助findTheKOrderBro()函数
inline void display(pair<int, string>& ans);//展示处理结果
//主函数
int main() {
string s;//存储原始输入
while (getline(cin, s)) {//循环处理多组输入
vector<vector<string>> inputS(preHandler(s));//数据预处理
//计算兄弟单词个数,得到题目要求的第K个单词
pair<int, string> ans(findTheKOrderBro(inputS[0], inputS[1][0], inputS[2][0][0] - '0'));
display(ans);//展示最终结果
}
}
//预处理输入数据,s为原始输入数据
vector<vector<string>> preHandler(string& s) {
int m = s.size();//串长
int i = m - 1;//计数器,用于确定题目里说的str
/***确定str,这里重命名为bro*******************/
while (s[i] != ' ') --i;
--i;
string bro;
while (s[i] != ' ') {
bro = s[i] + bro;
--i;
}
/***得到与bro长度相等但不等于bro的单词*********/
int n = bro.size();//str串长
vector<string> input;//存储预处理后的剩余单词
string temp;//临时遍历存单词
for (int i = 2; i < m; ++i) {
if (s[i] != ' ') temp += s[i];
else {
if (temp.size() == n && temp != bro) input.push_back(temp);
temp.clear();
}
}
/***得到题目要求的k****************************/
int k = s[m - 1] - '0';
return { input,{bro},{to_string(k)} };
}
//生成兄弟单词集,计算兄弟单词数量,得到题目要求的第K个兄弟单词
pair<int, string> findTheKOrderBro(vector<string>& word, string& bro, int k) {
/*word为预处理之后的输入数据,bro为题目中的str,k同理*/
int n = word.size();
int m = bro.size();
unordered_map<char, int> m1;/*m1是bro单词的哈希表,里边存储了bro单词中出现的字符及次数*/
map<string, int> temp;//兄弟单词集,同时也利用了map的字典序排序功能
for (const auto& s : bro) ++m1[s];//填充m1
int count = 0;//兄弟单词数
for (const auto& w : word) {//逐个遍历word填充temp,计算兄弟单词数
if (isBro(m1, w)) {++temp[w]; ++count;}
}
string outbro;//题目要求的第K个兄弟单词
//遍历前K个兄弟单词,找到题目要求的第K个兄弟单词
for (auto it = temp.begin(); it != temp.end(); ++it) {
bool isBreak = false;
for (int i = 0; i < it->second; ++i) {
--k;
if (k == 0) {outbro = it->first; isBreak = true; break;}
}
if(isBreak) break;
}
//返回兄弟单词数,和题目要求的第K个兄弟单词
return { count,outbro };
}
//使用哈希表判断一个单词是不是bro的兄弟单词
bool isBro(unordered_map<char, int>& m1, string s2) {
/*m1是bro单词的哈希表,里边存储了bro单词中出现的字符及次数*/
unordered_map<char, int> m2;//m2存储当前处理单词s2的字符及次数
for (const auto& s : s2) ++m2[s];
for (auto it = m1.begin(); it != m1.end(); ++it) {//两相比对,不一样就返回假
if (!m2.count(it->first) || m2[it->first] != it->second) return false;
}
return true;//都一样返回真
}
inline void display(pair<int, string>& ans) {
cout <<ans.first << endl;
if (ans.second.size() > 0) cout << ans.second << endl;
}