找回密码
 中文实名注册
搜索
查看: 89|回复: 0

字典树

[复制链接]

748

主题

417

回帖

2万

积分

管理员

积分
21531
发表于 2025-10-12 19:37:26 | 显示全部楼层 |阅读模式
[C++] 纯文本查看 复制代码
#include <iostream>
#include <cstring>   // for memset
#include <string>

using namespace std;

const int maxn = 100;
const int maxc = 26;

struct Trie {
    int ch[maxn][maxc];
    int tot;        // 当前最大的节点索引(根为 0)
    int cnt[maxn];

    void init() {
        tot = 0;                     // 根节点为 0
        // 将所有边初始化为 -1,计数初始化为 0
        memset(ch, -1, sizeof(ch));
        memset(cnt, 0, sizeof(cnt));
    }

    // 接受 const char*,或者可以重载接受 std::string
    void insert(const char *str) {
        int p = 0;
        for (int i = 0; str[i]; ++i) {
            int c = str[i] - 'a';
            if (c < 0 || c >= maxc) {
                // 忽略非小写字母(也可以处理或抛出错误)
                continue;
            }
            if (ch[p][c] == -1) {
                // 创建新节点,编号为 ++tot
                ch[p][c] = ++tot;
                cout<<tot<<endl;
            }
            p = ch[p][c];
        }
        cnt[p]++;
    }

    int find(const char *str) const {  // 返回字符串 str 的出现次数
        int p = 0;
        for (int i = 0; str[i]; ++i) {
            int c = str[i] - 'a';
            if (c < 0 || c >= maxc) return 0;
            if (ch[p][c] == -1) {
                return 0;
            }
            p = ch[p][c];
        }
        return cnt[p];
    }

    void erase(const char *str) {
        int p = 0;
        for (int i = 0; str[i]; ++i) {
            int c = str[i] - 'a';
            if (c < 0 || c >= maxc) return;
            if (ch[p][c] == -1) {
                return;
            }
            p = ch[p][c];
        }
        if (cnt[p] > 0) {
            --cnt[p];
        }
    }

    void print() {
        // 打印从 0 到 tot 的每个节点的 26 条边
        for (int i = 0; i <= tot; ++i) {
            cout << "node " << i << ": ";
            for (int j = 0; j < maxc; ++j) {
                cout << ch[i][j] << (j + 1 == maxc ? "" : " ");
            }
            cout<<"      " << cnt[i]<< endl;
        }
    }
};

int main() {
    Trie name;
    name.init();

    // 使用字面量时传入 const char* 不会有警告
    name.insert("barty");
    name.insert("bar");
    name.insert("islands");
    name.print();

    cout << "islands: " << name.find("islands") << endl;
    cout << "bar: " << name.find("bar") << endl;

    // 示例删除
    name.erase("bar");
    cout << "bar after erase: " << name.find("bar") << endl;

    return 0;
}

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 中文实名注册

本版积分规则

快速回复 返回顶部 返回列表