zoukankan      html  css  js  c++  java
  • LC 966. Vowel Spellchecker

    Given wordlist, we want to implement a spellchecker that converts a query word into a correct word.

    For a given query word, the spell checker handles two categories of spelling mistakes:

    • Capitalization: If the query matches a word in the wordlist (case-insensitive), then the query word is returned with the same case as the case in the wordlist.
      • Example: wordlist = ["yellow"]query = "YellOw"correct = "yellow"
      • Example: wordlist = ["Yellow"]query = "yellow"correct = "Yellow"
      • Example: wordlist = ["yellow"]query = "yellow"correct = "yellow"
    • Vowel Errors: If after replacing the vowels ('a', 'e', 'i', 'o', 'u') of the query word with any vowel individually, it matches a word in the wordlist (case-insensitive), then the query word is returned with the same case as the match in the wordlist.
      • Example: wordlist = ["YellOw"]query = "yollow"correct = "YellOw"
      • Example: wordlist = ["YellOw"]query = "yeellow"correct = "" (no match)
      • Example: wordlist = ["YellOw"]query = "yllw"correct = "" (no match)

    In addition, the spell checker operates under the following precedence rules:

    • When the query exactly matches a word in the wordlist (case-sensitive), you should return the same word back.
    • When the query matches a word up to capitlization, you should return the first such match in the wordlist.
    • When the query matches a word up to vowel errors, you should return the first such match in the wordlist.
    • If the query has no matches in the wordlist, you should return the empty string.

    Given some queries, return a list of words answer, where answer[i] is the correct word for query = queries[i].

     

    Example 1:

    Input: wordlist = ["KiTe","kite","hare","Hare"], queries = ["kite","Kite","KiTe","Hare","HARE","Hear","hear","keti","keet","keto"]
    Output: ["kite","KiTe","KiTe","Hare","hare","","","KiTe","","KiTe"]

     

    Note:

    • 1 <= wordlist.length <= 5000
    • 1 <= queries.length <= 5000
    • 1 <= wordlist[i].length <= 7
    • 1 <= queries[i].length <= 7
    • All strings in wordlist and queries consist only of english letters.

    踩坑踩了一个下午,掉到坑里出不来了。

    Runtime: 96 ms, faster than 100.00% of C++ online submissions for Vowel Spellchecker.

    第一种是我的做法 修改了TrieNode的结构,让它带了一个case_sensitive的标志位。如果带上大小写搜索,

    每次需要判断字符的大小写,这样得到的是第一种准确的搜索。如果不敏感,就全部放在小写的这个节点里。

    为了满足题意,大小写不敏感的可能有多种,那么Trie节点带一个数组比较合适。

    注意:

    1. 本来的字典可能有重复,我去。。。

    2. 需要返回最小的index,那就把所有的求出来以后再求最小的index。

    写了一个下午。

    class TrieNode{
    public:
      string word;
      vector<string> wordlist;
      TrieNode* lowercase[26];
      TrieNode* uppercase[26];
      TrieNode(){
        for(int i=0; i<26; i++) lowercase[i] = nullptr;
        for(int i=0; i<26; i++) uppercase[i] = nullptr;
      }
    };
    
    class Trie{
    public:
      TrieNode* root;
      Trie(const vector<string>& wordlist, bool case_sensitive = true){
        root = new TrieNode();
        BuildTrie(wordlist, case_sensitive);
      }
      void BuildTrie(const vector<string>& wordlist, bool case_sensitive = true){
    
        for(int i=0; i<wordlist.size(); i++){
          TrieNode* tmp = root;
          for(int j=0; j<wordlist[i].size(); j++){
            char tmpchar = wordlist[i][j];
            int idx = 0;
            if(!case_sensitive){
              if(tmpchar >= 'A' && tmpchar <= 'Z'){
                idx = tmpchar - 'A';
              }else idx = tmpchar - 'a';
              if(!tmp->lowercase[idx]) tmp->lowercase[idx] = new TrieNode();
              tmp = tmp->lowercase[idx];
            }else{
              if(tmpchar >= 'A' && tmpchar <= 'Z'){
                idx = tmpchar - 'A';
                if(!tmp->uppercase[idx]) tmp->uppercase[idx] = new TrieNode();
                tmp = tmp->uppercase[idx];
              }else {
                idx = tmpchar - 'a';
                if(!tmp->lowercase[idx]) tmp->lowercase[idx] = new TrieNode();
                tmp = tmp->lowercase[idx];
              }
            }
          }
          if(case_sensitive){
            tmp->word = wordlist[i];
          }else {
            tmp->wordlist.push_back(wordlist[i]);
          }
        }
      }
      bool hasword(string word, string& foundword, bool case_sensitive = true){
        TrieNode* tmp = root;
        locale loc;
        for(int i=0; i<word.size(); i++){
          char tmpchar = word[i];
          int idx = 0;
          if(!case_sensitive){
            tmpchar = tolower(tmpchar, loc);
            idx = tmpchar - 'a';
            if(!tmp->lowercase[idx]) return false;
            tmp = tmp->lowercase[idx];
          }else {
            if(tmpchar >= 'A' && tmpchar <= 'Z') {
              idx = tmpchar - 'A';
              if(!tmp->uppercase[idx]) return false;
              tmp = tmp->uppercase[idx];
            } else {
              idx = tmpchar - 'a';
              if(!tmp->lowercase[idx]) return false;
              tmp = tmp->lowercase[idx];
            }
          }
        }
        if(!case_sensitive) {
          if(!tmp->wordlist.empty()){
            foundword = tmp->wordlist[0];
            return true;
          }
          return false;
        }
        if(!tmp->word.empty()) {
          foundword = tmp->word;
          return true;
        }
        return false;
      }
    };
    
    class Solution {
    public:
      set<char> vset;
      unordered_map<string,int> mp;
      vector<string> spellchecker(vector<string>& wordlist, vector<string>& queries) {
        for(int i=0; i<wordlist.size(); i++){
          mp[wordlist[i]] = i;
        }
        vset.insert('a');vset.insert('e');vset.insert('i');
        vset.insert('o');vset.insert('u');
        vector<string> ret;
        Trie trie_case_sensi = Trie(wordlist);
        Trie trie_not_case_sensi = Trie(wordlist, false);
        for(int i=0; i<queries.size(); i++){
          string foundword;
          vector<string> foundwordvec;
          if(trie_case_sensi.hasword(queries[i],foundword)) {
            ret.push_back(queries[i]);
          }else if(trie_not_case_sensi.hasword(queries[i], foundword, false)){
            ret.push_back(foundword);
          }else {
            dfs(trie_not_case_sensi.root, queries[i], foundwordvec, 0);
            int minidx = wordlist.size();
            for(auto x : foundwordvec) minidx = min(minidx, mp[x]);
            if(minidx == wordlist.size()) ret.push_back("");
            else ret.push_back(wordlist[minidx]);
          }
        }
        return ret;
      }
    
      void dfs(const TrieNode* root,string query, vector<string>& ret, int start){
        if(start == query.size()){
          assert(!root->wordlist.empty());
          ret.push_back(root->wordlist[0]);
          return ;
        }
        std::locale loc;
        char c = tolower(query[start],loc);
        int idx = 0;
        idx = c - 'a';
        if(vset.count(c)){
          for(auto it = vset.begin(); it != vset.end(); it++){
            char vsub = *it;
            int newidx = 0;
            newidx = vsub - 'a';
            if(!root->lowercase[newidx]) continue;
            TrieNode* nextroot = root->lowercase[newidx];
            dfs(nextroot, query, ret, start+1);
          }
        }else{
          if(!root->lowercase[idx]) return ;
          TrieNode* nextroot = root->lowercase[idx];
          dfs(nextroot, query, ret, start+1);
        }
      }
    };

    下面看看网上的大神的解法,很简单,既然aeiou都能互相匹配,那就把aeiou变成#,这样一来不就行了么!真是厉害。

    class Solution {
        public String[] spellchecker(String[] wordlist, String[] queries) {
            Set<String> words = new HashSet<>(Arrays.asList(wordlist));
            HashMap<String, String> cap = new HashMap<>();
            HashMap<String, String> vowel = new HashMap<>();
            for (String w : wordlist) {
                String lower = w.toLowerCase(), devowel = lower.replaceAll("[aeiou]", "#");
                cap.putIfAbsent(lower, w);
                vowel.putIfAbsent(devowel, w);
            }
            for (int i = 0; i < queries.length; ++i) {
                if (words.contains(queries[i])) continue;
                String lower = queries[i].toLowerCase(), devowel = lower.replaceAll("[aeiou]", "#");
                if (cap.containsKey(lower)) {
                    queries[i] = cap.get(lower);
                } else if (vowel.containsKey(devowel)) {
                    queries[i] = vowel.get(devowel);
                } else {
                    queries[i] = "";
                }
            }
            return queries;
        }
    }
  • 相关阅读:
    javascript 中的nextSibling和previousSibling使用注意事项
    inline-block(行内区块元素)的详解和应用
    createElement()结合appendChild()的实例
    JavaScript 的setAttribute兼容性解决
    css 雪碧图 及jquery定位代码
    jquery图片轮播代码
    jquery 的attr()方法解析
    用jquery修改默认的单选框radio或者复选框checkbox选择框样式
    html form <label>标签基础语法结构与使用案例教程(转载)
    CoreText
  • 原文地址:https://www.cnblogs.com/ethanhong/p/10199989.html
Copyright © 2011-2022 走看看