【Day7】字符串与字符串匹配

03.02.12 练习题目(第 07 天)

1. 0211. 添加与搜索单词 - 数据结构设计

1.1 题目大意

要求:设计一个数据结构,支持「添加新单词」和「查找字符串是否与任何先前添加的字符串匹配」。

实现词典类 WordDictionary:

  • WordDictionary() 初始化词典对象。
  • void addWord(word)word 添加到数据结构中,之后可以对它进行匹配
  • bool search(word) 如果数据结构中存在字符串与 word 匹配,则返回 True;否则,返回 Falseword 中可能包含一些 .,每个 . 都可以表示任何一个字母。

说明

  • 1 ≤ w o r d . l e n g t h ≤ 25 1 \le word.length \le 25 1word.length25
  • addWord 中的 word 由小写英文字母组成。
  • search 中的 word'.' 或小写英文字母组成。
  • 最多调用 1 0 4 10^4 104addWordsearch

示例

输入:
["WordDictionary","addWord","addWord","addWord","search","search","search","search"]
[[],["bad"],["dad"],["mad"],["pad"],["bad"],[".ad"],["b.."]]
输出:
[null,null,null,null,false,true,true,true]

解释:
WordDictionary wordDictionary = new WordDictionary();
wordDictionary.addWord("bad");
wordDictionary.addWord("dad");
wordDictionary.addWord("mad");
wordDictionary.search("pad"); // 返回 False
wordDictionary.search("bad"); // 返回 True
wordDictionary.search(".ad"); // 返回 True
wordDictionary.search("b.."); // 返回 True

我的答案

class TrieNode {
public:
    std::unordered_map<char, TrieNode*> children;
    bool isEndOfWord;

    TrieNode() : isEndOfWord(false) {}
};

class WordDictionary {
private:
    TrieNode* root;

public:
    WordDictionary() {
        root = new TrieNode();
    }
    
    void addWord(std::string word) {
        TrieNode* current = root;
        for (char ch : word) {
            if (current->children.find(ch) == current->children.end()) {
                current->children[ch] = new TrieNode();
            }
            current = current->children[ch];
        }
        current->isEndOfWord = true;
    }
    
    bool search(std::string word) {
        return searchHelper(word, 0, root);
    }

private:
    bool searchHelper(const std::string& word, int index, TrieNode* node) {
        if (index == word.size()) {
            return node->isEndOfWord;
        }
        
        char ch = word[index];
        if (ch == '.') {
            for (auto& pair : node->children) {
                if (searchHelper(word, index + 1, pair.second)) {
                    return true;
                }
            }
            return false;
        } else {
            if (node->children.find(ch) == node->children.end()) {
                return false;
            }
            return searchHelper(word, index + 1, node->children[ch]);
        }
    }
};

心得

  1. 注意searchHelper函数的返回值,以及search函数的返回值。

2. 0648. 单词替换

2.1 题目大意

描述:给定一个由许多词根组成的字典列表 dictionary,以及一个句子字符串 sentence

要求:将句子中有词根的单词用词根替换掉。如果单词有很多词根,则用最短的词根替换掉他。最后输出替换之后的句子。

说明

  • 1 ≤ d i c t i o n a r y . l e n g t h ≤ 1000 1 \le dictionary.length \le 1000 1dictionary.length1000
  • 1 ≤ d i c t i o n a r y [ i ] . l e n g t h ≤ 100 1 \le dictionary[i].length \le 100 1dictionary[i].length100
  • dictionary[i] 仅由小写字母组成。
  • 1 ≤ s e n t e n c e . l e n g t h ≤ 1 0 6 1 \le sentence.length \le 10^6 1sentence.length106
  • sentence 仅由小写字母和空格组成。
  • sentence 中单词的总量在范围 [ 1 , 1000 ] [1, 1000] [1,1000] 内。
  • sentence 中每个单词的长度在范围 [ 1 , 1000 ] [1, 1000] [1,1000] 内。
  • sentence 中单词之间由一个空格隔开。
  • sentence 没有前导或尾随空格。

示例

输入:dictionary = ["cat","bat","rat"], sentence = "the cattle was rattled by the battery"
输出:"the cat was rat by the bat"


输入:dictionary = ["a","b","c"], sentence = "aadsfasf absbs bbab cadsfafs"
输出:"a a b c"

我的答案

class Solution {
public:
    string replaceWords(vector<string>& dictionary, string sentence) {
        // 对字典进行排序,确保最短的前缀在前
        sort(dictionary.begin(), dictionary.end());

        // 使用istringstream分割句子
        istringstream iss(sentence);
        string word;
        string result = "";

        while (iss >> word) {
            // 查找最短的前缀
            string prefix = findPrefix(dictionary, word);
            if (!prefix.empty()) {
                result += prefix + " ";
            } else {
                result += word + " ";
            }
        }

        // 去掉最后一个多余的空格
        if (!result.empty()) {
            result.pop_back();
        }

        return result;
    }

private:
    string findPrefix(const vector<string>& dictionary, const string& word) {
        for (const string& prefix : dictionary) {
            if (word.substr(0, prefix.size()) == prefix) {
                return prefix;
            }
        }
        return "";
    }
};

心得

  1. 注意findPrefix函数的返回值,以及replaceWords函数的返回值。

3. 0676. 实现一个魔法字典

3.1 题目大意

要求:设计一个使用单词表进行初始化的数据结构。单词表中的单词互不相同。如果给出一个单词,要求判定能否将该单词中的一个字母替换成另一个字母,是的所形成的新单词已经在够构建的单词表中。

实现 MagicDictionary 类:

  • MagicDictionary() 初始化对象。
  • void buildDict(String[] dictionary) 使用字符串数组 dictionary 设定该数据结构,dictionary 中的字符串互不相同。
  • bool search(String searchWord) 给定一个字符串 searchWord,判定能否只将字符串中一个字母换成另一个字母,使得所形成的新字符串能够与字典中的任一字符串匹配。如果可以,返回 True;否则,返回 False

说明

  • 1 ≤ d i c t i o n a r y . l e n g t h ≤ 100 1 \le dictionary.length \le 100 1dictionary.length100
  • 1 ≤ d i c t i o n a r y [ i ] . l e n g t h ≤ 100 1 \le dictionary[i].length \le 100 1dictionary[i].length100
  • dictionary[i] 仅由小写英文字母组成。
  • dictionary 中的所有字符串互不相同。
  • 1 ≤ s e a r c h W o r d . l e n g t h ≤ 100 1 \le searchWord.length \le 100 1searchWord.length100
  • searchWord 仅由小写英文字母组成。
  • buildDict 仅在 search 之前调用一次。
  • 最多调用 100 100 100search

示例

输入
["MagicDictionary", "buildDict", "search", "search", "search", "search"]
[[], [["hello", "leetcode"]], ["hello"], ["hhllo"], ["hell"], ["leetcoded"]]
输出
[null, null, false, true, false, false]

解释
MagicDictionary magicDictionary = new MagicDictionary();
magicDictionary.buildDict(["hello", "leetcode"]);
magicDictionary.search("hello"); // 返回 False
magicDictionary.search("hhllo"); // 将第二个 'h' 替换为 'e' 可以匹配 "hello" ,所以返回 True
magicDictionary.search("hell"); // 返回 False
magicDictionary.search("leetcoded"); // 返回 False

我的答案

class MagicDictionary {
private:
    unordered_set<string> dict;

public:
    MagicDictionary() {
        // 初始化字典
    }
    
    void buildDict(vector<string> dictionary) {
        for (const string& word : dictionary) {
            dict.insert(word);
        }
    }
    
    bool search(string searchWord) {
        for (const string& word : dict) {
            if (isOneCharDifferent(searchWord, word)) {
                return true;
            }
        }
        return false;
    }

private:
    bool isOneCharDifferent(const string& word1, const string& word2) {
        if (word1.size() != word2.size()) {
            return false;
        }
        int diffCount = 0;
        for (size_t i = 0; i < word1.size(); ++i) {
            if (word1[i] != word2[i]) {
                ++diffCount;
                if (diffCount > 1) {
                    return false;
                }
            }
        }
        return diffCount == 1;
    }
};

心得

  1. 字典的建立,可以先用unordered_set,然后用insert插入
  2. 字典的查找,可以先用unordered_set,然后用find查找
  3. 字符串的比较,可以先用string,然后用==比较
  4. 字符串的替换,可以先用string,然后用[]替换
  5. 字符串的插入,可以先用string,然后用+插入
  6. 字符串的删除,可以先用string,然后用substr删除
  • 25
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值