NC124 字典树的实现

可以当字段树模板使用。

描述

字典树又称为前缀树或者Trie树,是处理字符串常用的数据结构。

假设组成所有单词的字符仅是‘a’~‘z’,请实现字典树的结构,并包含以下四个主要的功能。

1. void insert(String word):添加word,可重复添加;
2. void delete(String word):删除word,如果word添加过多次,仅删除一次;
3. boolean search(String word):查询word是否在字典树中出现过(完整的出现过,前缀式不算);
4. int prefixNumber(String pre):返回以字符串pre作为前缀的单词数量。

现在给定一个m,表示有m次操作,每次操作都为以上四种操作之一。每次操作会给定一个整数op和一个字符串word,op代表一个操作码,如果op为1,则代表添加word,op为2则代表删除word,op为3则代表查询word是否在字典树中,op为4代表返回以word为前缀的单词数量(数据保证不会删除不存在的word)。

对于每次操作,如果op为3时,如果word在字典树中,请输出“YES”,否则输出“NO”;如果op为4时,请输出返回以word为前缀的单词数量,其它情况不输出。

[["1","qwer"],["1","qwe"],["3","qwer"],["4","q"],["2","qwer"],["3","qwer"],["4","q"]]

["YES","2","NO","1"]
 

struct TrieNode {
    int word_cnt;
    int prefix_cnt;
    bool end;
    TrieNode* next[26] = {NULL};

    TrieNode() {
        word_cnt = 0;//单词个数
        prefix_cnt = 0;
        end = false;//字符串结束位置
        for (int i = 0; i < 26; i++) {
            next[i] = NULL;
        }
    }
};
class Solution {
  public:
    /**
     *
     * @param operators string字符串vector<vector<>> the ops
     * @return string字符串vector
     */
    TrieNode* phead = new TrieNode();
    void insert(string word) {
        TrieNode* p = phead;

        for (char ch : word) {
            if (!p->next[ch - 'a']) {
                p->next[ch - 'a'] = new TrieNode();
            }
            p = p->next[ch - 'a'];
            p->prefix_cnt++;
        }
        p->word_cnt++;
        p->end = true;
    }
    void Delete(string word) {
        TrieNode* p = phead;
        for (char ch : word) {
            if (!p->next[ch - 'a']) {
                return;
            }
            p = p->next[ch - 'a'];
            p->prefix_cnt--;
        }
        if (p->word_cnt > 1 && p->end) {
            p->word_cnt--;
        } else {
            p->word_cnt--;
            p->end = false;
        }
    }
    string search(string s) {
        TrieNode* p = phead;
        for (char ch : s) {
            if (!p->next[ch - 'a']) return "NO";
            p = p->next[ch - 'a'];
        }
        if (p->end) return "YES";
        return "NO";
    }
    int prefixNumber(string s) {
        TrieNode* p = phead;
        for (char ch : s) {
            if (!p->next[ch - 'a']) return 0;
            p = p->next[ch - 'a'];
        }
        return p->prefix_cnt;
    }
    vector<string> trieU(vector<vector<string> >& operators) {
        // write code here
        // write code here
        vector<string> ans;
        for (auto op : operators) {
            string num = op[0], word = op[1];
            if (num == "1") insert(word);
            else if (num == "2") Delete(word);
            else if (num == "3") {
                ans.push_back(search(word));
            } else if (num == "4") {
                int cnt = prefixNumber(word);
                ans.push_back(to_string(cnt));
            }
        }
        return ans;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值