字典树

字典树所有功能
1、查整体单词(查前缀)
2、字符串排序(结合词频,可输出重复字符串)
(放外头可以实现输出前缀)
3、统计词频(前缀频)
字符串词频(cnt数组就是频,放里头是整体词频,放外头就是前缀词频)

1、查整体单词(查前缀)

//放外面就是查整体
//放里头就是查前缀
#include<bits/stdc++.h>
using namespace std;
int T,q,n,t[3000005][65],cnt[3000005],idx;
char s[3000005];
int getnum(char x){
    if(x>='A'&&x<='Z')
        return x-'A';
    else if(x>='a'&&x<='z')
        return x-'a'+26;
    else
        return x-'0'+52;
} 
void insert(char str[]){
    int p=0,len=strlen(str);
    for(int i=0;i<len;i++){
        int c=getnum(str[i]);
        if(!t[p][c])
            t[p][c]=++idx;
        p=t[p][c];
        cnt[p]++;
		//放外面就是搜整体
		//放里头就是查前缀
    }
    //cnt[p]++;
    
}
int find(char str[]){
    int p=0,len=strlen(str);
    for(int i=0;i<len;i++){
        int c=getnum(str[i]);
        if(!t[p][c])
            return 0;
        p=t[p][c];
    }
    return cnt[p];
}



int main(){
    scanf("%d",&T);
    while(T--){
        for(int i=0;i<=idx;i++)
            for(int j=0;j<=122;j++)
                t[i][j]=0;
        for(int i=0;i<=idx;i++)
            cnt[i]=0;
        idx=0;
        scanf("%d%d",&n,&q);
        for(int i=1;i<=n;i++){
            scanf("%s",s);
            insert(s);
        }
        for(int i=1;i<=q;i++){
            scanf("%s",s);
            printf("%d\n",find(s));
        }
    }



//下面是查单词整体的
//int n;
//	scanf("%d",&n); // getchar();
//	while(n--){
//		char op[2];
//		scanf("%s%s",op,s);
//		if(*op=='I') insert(s);
//		else cout<<find(s)<<endl;
//	}

    return 0;
}

2、字符串排序
功能介绍:
1)本代码是定义为大写字母在前的

#include <bits/stdc++.h>
using namespace std;

int T, q, n, t[3000005][65], cnt[3000005], idx;
char s[3000005];

int getnum(char x) {
    if (x >= 'A' && x <= 'Z')
        return x - 'A';
    else if (x >= 'a' && x <= 'z')
        return x - 'a' + 26;
    else
        return x - '0' + 52;
}

void insert(char str[]) {
    int p = 0, len = strlen(str);
    for (int i = 0; i < len; i++) {
        int c = getnum(str[i]);
        if (!t[p][c])
            t[p][c] = ++idx;
        p = t[p][c];
    }
    cnt[p]++;
}

int find(char str[]) {
    int p = 0, len = strlen(str);
    for (int i = 0; i < len; i++) {
        int c = getnum(str[i]);
        if (!t[p][c])
            return 0;
        p = t[p][c];
    }
    return cnt[p];
}

void pr(int node, string& cur) {
    if (cnt[node] > 0) {
        cout << cur << endl;
    }
//可以输出重复字符串 
//    while (cnt[node] > 0) {
//        cout << cur << endl;
//        cnt[node]--;
//    }

    for (int i = 0; i < 65; i++) {
        if (t[node][i] != 0) {
            char ch = ' ';
            if (i < 26) {
                ch = 'A' + i;
            } else if (i < 52) {
                ch = 'a' + i - 26;
            } else {
                ch = '0' + i - 52;
            }

            cur.push_back(ch);
            pr(t[node][i], cur);
            cur.pop_back();
        }
    }
}

int main() 
{
	scanf("%d", &n);
    for (int i = 0; i <= idx; i++)
        for (int j = 0; j <= 122; j++)
            t[i][j] = 0;
    for (int i = 0; i <= idx; i++)
        cnt[i] = 0;
    idx = 0;
    
    for (int i = 1; i <= n; i++) 
	{
        scanf("%s", s);
        insert(s);
    }
    // 输出字典树的先序遍历结果
    string cur = "";
    pr(0, cur);
    
    return 0;
}


/*
9
cap
to
cat
card
two
too
up
boat
boot
boat
boot
cap
card
cat
to
too
two
up

*/
posted @ 2024-04-21 15:09  涤生yang  阅读(28)  评论(0)    收藏  举报