洛谷--前缀统计c语言

题目如下

代码如下

复制代码
#include<stdio.h>
int son[1000010][26]={0};
int cnt[1000010]={0};
char str[1000010]={0}; 
  int idx=0;
void insert(char *str){
int p=0;
for(int i=0;str[i];i++){
    int u=str[i]-'a';
    if(!son[p][u]) son[p][u]=++idx;
    p=son[p][u];
}
cnt[p]++;
}
int query(char *str){
int p=0,sum=0;
for(int i=0;str[i];i++){
    int u=str[i]-'a';
    p=son[p][u];
    if(p==0) return sum;
    if(cnt[p]) sum+=cnt[p];
}
return sum;
}
int main(){
int end;
int m,n;
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++){
    scanf("%s",str);
    insert(str);
}
for(int i=0;i<m;i++){
    scanf("%s",str);
    end=query(str);
    printf("%d\n",end);
}
return 0;
}

这道题目用到的是字典树trie树,这个树的主要操作有两个,一个是插入,一个是访问,这里我重点讲一下访问。

可能会有人问为什么先让p=son[p][u]再去进行判断,而不是先进行sum+=cnt[p],进行完后再进行p=son[p][u],我举个例子。

假设m和n都是1,之后我们先输入abc,再输入abc,根据题目的意思其实就是判断a是不是abc的前缀,根据我们的插入操作将a插入进去,插入结束后p为1,那cnt[3]就加1,这时cnt[3]就为1,这时再回到我们的询问函数上,如果先sum+=cnt[p],那么加完后sum还是0(因为cnt[0]为0),p=0,之后进行p=son[p][u],这时p=1,进行下一轮循环(这时str[i]等于b),继续进行sum+=cnt[p],这时sum还是0,p=1,之后进行p=son[p][u],这时p=2,继续下一轮(这时srt[i]等于c),sum+=cnt[p],sum还是0,p=2,之后进行p=son[p][u],p=3,这时结束循环,因为str[4]为'\0',但是sum还是0,正常来讲sum应该为1,问题就出在我前面那两步的顺序上,如果交换顺序那么当我们插入的字符串和我们要询问的字符串相等的时候,就比如前面那种(都输入abc时)就会出现错误,少加1次。所以我们才要让p=son[p][u]。

前面讲的可能很乱,我再总结一下原因,不管我们输入几个字符,cnt[0]永远是0,因为就算我们一开始只输入一个字符,这时son[p][u]=++idx,这时son[p][u]已经为1了(idx一开始初始化为0),那么我们再让p=son[p][u],那么p这时为1,最后结束循环,cnt[p],也就是cnt[1]++,所以cnt[0]永远是0,那么我们询问操作时,一开始p=0,根本不需要管cnt[0],直接让p=son[p][u]就可以了。

这里我再说一下为什么p==0时直接返回,因为如果p=0了,那么说明我们str数组中的这个字符没有出现在我们树的这条路径上出现过,直接返回就可以了。

(讲的不清不楚的,各位只能将就一下了,抱歉)

相关推荐
你可以叫我仔哥呀4 分钟前
Java程序员学从0学AI(七)
java·开发语言·人工智能·ai·spring ai
姜不吃葱6 分钟前
【力扣热题100】哈希——两数之和
算法·leetcode·哈希算法·力扣热题100
符生落华12 分钟前
c语言:插入排序,二维数组
c语言
AI4Sci.15 分钟前
在云服务器上基于lora微调Qwen2.5-VL-7b-Instruct模型(下)
人工智能·算法·机器学习·大模型·lora微调·大模型本地部署·qwen2.5-vl-7b
一只小风华~17 分钟前
JavaScript:数组常用操作方法的总结表格
前端·javascript·数据结构·vue.js·算法
TiAmo zhang41 分钟前
深度学习与图像处理 | 基于PaddlePaddle的梯度下降算法实现(线性回归投资预测)
图像处理·深度学习·算法
望获linux1 小时前
【Linux基础知识系列】第六十四篇 - 了解Linux的硬件架构
linux·运维·服务器·开发语言·数据库·操作系统·嵌入式软件
一匹电信狗1 小时前
【C++】手搓一个STL风格的vector容器
c语言·数据结构·c++·算法·leetcode·stl·visual studio
生信探索1 小时前
SeuratExtend 可视化教程(1):单细胞分析的高颜值绘图指南
算法
小小小白的编程日记1 小时前
C语言中的数据结构--栈和队列(2)
c语言·数据结构