练习27, 字典树 于是他错误的点名开始了【字典树/map】

这篇博客介绍了如何使用字典树(Trie)和STL中的map来实现字符串的插入、查找以及计数功能。在C++代码示例中,字典树用于高效地插入字符串并检索出现次数,而STL map则用于存储字符串及其出现次数,实现相同功能但采用了不同的数据结构。这两种方法都在内存管理和查询效率上各有优势。
摘要由CSDN通过智能技术生成

P2580 于是他错误的点名开始了 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

字典树写法:

#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define lint long long
int n,m;

struct Trie{
    int ch[500010][26],cnt,val[500010];
    //val为附加信息
    //ch数组,第二维的大小为26是因为字符串只由小写字母构成,第二维的大小一般是由字符串的组成决定
    //cnt即为节点编号
    Trie(){
        cnt=1;//一开始的时候只有根节点这一个节点
        memset(ch[0],0,sizeof(ch[0]));
        memset(val,0,sizeof(val));
    }
    void insert(char *s,int v){
      //s代表要插入的字符串,v为附加信息
        int u=0,len=strlen(s+1);//u限制该节点的子节点
        for(int i=1;i<=len;i++){
            int c=s[i]-'a';
            if(!ch[u][c]){//如果节点不存在就插入,不然就继续往下遍历
                ch[u][c]=cnt++;//新建节点
            }
            u=ch[u][c];//往下遍历
        }
        val[u]=v;//插入附加信息,一般只在叶子节点插入附加信息,中间的节点一般是没有附加信息的
    }
    int find(char *s){
        //查找这个字符串是否在Trie中出现过,如果出现过,返回它的附加信息
        int u=0,len=strlen(s+1);
        for(int i=1;i<=len;i++){
            int c=s[i]-'a';
            if(!ch[u][c]) return 0; //没有这个节点,返回0,即代表这个字符串没有在Trie中出现过
            u=ch[u][c];//继续向下遍历
        }
        if(val[u]==0) {val[u]++; return 1;} 
        if(val[u]==1) return 2; //第二次返回2
    }
} trie;
int main(){
    cin >> n;
    for(int i=1;i<=n;i++){
        char s[100];
        scanf("%s",s+1);
        trie.insert(s,0);
    }
    cin >> m;
    for(int i=1;i<=m;i++){
        char s[100];
        scanf("%s",s+1);
        int f=trie.find(s);
        if(f==1) {cout << "OK\n"; continue;}
        if(!f) {cout << "WRONG\n"; continue;}
        if(f==2) {cout << "REPEAT\n"; continue;}
    }
    return 0;
}

STL map写法:

#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define lint long long
map<string,int> mp;
int n,m;
int main(){
    cin >> n;
    for(int i=1;i<=n;i++){
        string s;
        cin >> s;
        mp[s]=1;
    }
    cin >>m;
    for(int i=1;i<=m;i++){
        string s;
        cin >> s;
        if(mp[s]==1){printf("OK\n");mp[s]++;continue;}
        if(mp[s]==0){printf("WRONG\n");mp[s]++;continue;}
        if(mp[s]>=1){printf("REPEAT\n");mp[s]++;continue;}
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ILECY

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值