DS哈希查找--Trie树

题目描述

Trie树又称单词查找树,是一种树形结构,如下图所示。

它是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来节约存储空间,最大限度地减少无谓的字符串比较,查询效率比哈希表高。

输入的一组单词,创建Trie树。输入字符串,计算以该字符串为公共前缀的单词数。

(提示:树结点有26个指针,指向单词的下一字母结点。)

输入

测试数据有多组

每组测试数据格式为:

第一行:一行单词,单词全小写字母,且单词不会重复,单词的长度不超过10

第二行:测试公共前缀字符串数量t

后跟t行,每行一个字符串

输出

每组测试数据输出格式为:

第一行:创建的Trie树的层次遍历结果

第2~t+1行:对每行字符串,输出树中以该字符串为公共前缀的单词数。

输入样例

abcd abd bcd efg hig
3
ab
bc
abcde

输出样例

abehbcficddggd
2
1
0

解题思路

       这道题本人结合字典树,深度优先搜索和广度优先搜索的知识进行解答,字典树的建立其实与二叉树的建立相似,只是左右孩子变成了26个孩子,对这棵字典树进行深度优先搜索就是每一个单词,而这道题的第一个要求其实就是进行一次广度优先搜索,然后寻找前缀其实就是对树进行深度优先搜索,搜索到这个前缀后,以前缀的最后一个字母为根节点,深度优先搜索有多少子树,也就是有多少单词以这个词组为前缀,最后实现代码如下:

#include<iostream>
#include<string>
#include<queue>
using namespace std;
int sum;
class Trie {
public:
    bool flag = false;
    Trie* next[26] = { nullptr };
    friend void BFS();

    void insert(string str) {
        Trie* node = this;
        for (int i = 0; i < str.length(); i++) {
            char c = str[i];
            if (node->next[c - 'a'] == nullptr) {
                node->next[c - 'a'] = new Trie();
            }
            node = node->next[c - 'a'];
        }
        node->flag = true;
    }

    int searchStart(string pre) {
        Trie* node = this;
        sum=0;
        for (int i = 0; i < pre.length(); i++) {
            char c = pre[i];
            if (node->next[c - 'a'] == nullptr)  return 0;
            node = node->next[c - 'a'];
        }
        DFS(node);
        return sum;
    }
    void DFS(Trie* Node) {
        Trie* tr = new Trie();
        tr = Node;
        int temp=0;
        for (int i = 0; i < 26; i++) {
            if (tr->next[i])
            {
                DFS(tr->next[i]);
                temp = 1;
            }   
        }
        if (temp == 0) {
            sum++;
            return;
        }
    }
    
};

void BFS(Trie* Tree) {
    queue<Trie*>q;
    q.push(Tree);
    while (!q.empty()) {
        Trie* t = q.front();
        q.pop();
        for (int i = 0; i < 26; i++) {
            if (t->next[i]) {
                cout <<char( 'a' + i);
                q.push(t->next[i]);
            }
        }
    }


}

int main() {
    string arr;
    Trie* tree=new Trie();
    int t;
    while (1) {
        cin >> arr;
        if (arr[0] >= '0' && arr[0] <= '9') {
            t = arr[0] - '0';
            break;
        }
        tree->insert(arr);
    }
    BFS(tree);
    cout << endl;
    while (t--) {
        string test; cin >> test;
        cout << tree->searchStart(test)<<endl;
    }
}

注:代码质量较低,只作解题用,没进行格式化编写

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值