题解 | #查找兄弟单词#

查找兄弟单词

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;
}

alt

全部评论

相关推荐

helloWord大王:这时候hr来个转人工我就真绷不住了
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务