当前位置: 首页 > news >正文

泰安建设网站哪个好单位网站开发费用进什么科目

泰安建设网站哪个好,单位网站开发费用进什么科目,wordpress 修改后台登陆名字,wordpress 钩子问题描述 依依是一个住在海边小镇的女孩,她的朋友们分散在世界的各个角落。他们有一个特殊的传递信息的方式,那就是通过海洋传递瓶中信。每个瓶中信里,都装着一串由小写英文字母组成的信息,代表一个友情的密码。 这个夏天&#…

问题描述

依依是一个住在海边小镇的女孩,她的朋友们分散在世界的各个角落。他们有一个特殊的传递信息的方式,那就是通过海洋传递瓶中信。每个瓶中信里,都装着一串由小写英文字母组成的信息,代表一个友情的密码。

这个夏天,依依在海滩上捡到了 N 个瓶中信,每个瓶中信里都有一条由小写英文字符组成的信息,这些信息分别来自她的 N 个朋友。我们记第 ii 个朋友的信息为 Si,其中 i=1,2,...,N。

为了找出与自己最有缘分的朋友,依依决定比较这些信息的相似度。这里的"相似度"指的是两条信息从头开始,最长能够匹配的字符数量。

注意,依依并不想比较一条信息与它自身的相似度。

现在,依依希望你能帮助她找出对于每条信息 Si,哪条信息与其最相似,即从开头开始,最长能连续匹配的字符的数量是多少。

输入格式

输入的第一行包含一个整数 NN(1≤N≤104)。

接下来的 NN 行,每行包含一个由小写字符构成的字符串 SiSi​,表示小蓝的一个朋友在信封里刻写的信息。保证

输出格式

输出共 N行,对于每条信息Si​,输出一个整数,表示与 Si​ 最接近的信息的最长公共前缀的长度。

样例输入

3
abc
ab
bc

 

样例输出

2
2
0

解题代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
string s[N];//存储n个信息s
int tire[N][27],idx=2,cnt[N];void insert(string a){  //生成一个tire树,把所有s都插入到树中int n=a.length()-1;//在 C++ 的 std::string 中,a[i] 不会自动包含 '\0'。int x=1;for(int i=1;i<=n;i++){if(!tire[x][a[i]-'a']) tire[x][a[i]-'a']=idx++; //如果不存在的话就创建这个节点x=tire[x][a[i]-'a'];  //这个是让x指向当前节点cnt[x]++;//让每个走过当前节点都用cnt记录下来并自加//这个是关键,当cnt[x]>1的时候说明这个节点至少有两个字符串是走过这里的}
}int check(string a){int n=a.length()-1;int x=1;int ans=0;for(int i=1;i<=n;i++){x=tire[x][a[i]-'a'];if(cnt[x]!=1){//当cnt[x]不等于1的时候说明此时的s[i]肯定有一个s的前s[t]和s[i]的前i是相同的ans=i;//当存在s[t]和s[i]相同的时候就让ans=i,i是相同的字符的个数}else break;//如果cnt[x]==1说明没有与之匹配的串了,直接退出返回当前的ans就行}return ans;
}
int main(){int n;cin>>n;for(int i=1;i<=n;i++){cin>>s[i];s[i]='0'+s[i];insert(s[i]);}for(int i=1;i<=n;i++){cout<<check(s[i])<<"\n";}return 0;
}

解题思路:

  1. 字典树(Trie)

    • 使用字典树存储所有字符串的前缀信息。

    • 字典树的每个节点表示一个字符,从根节点到某个节点的路径表示一个前缀。

  2. 统计前缀出现次数

    • 在插入字符串时,记录每个节点被访问的次数(cnt[x]++)。

    • 如果某个节点的 cnt[x] > 1,说明至少有两个字符串共享这个前缀。

  3. 查询最长公共前缀

    • 对于每个字符串,从根节点开始遍历字典树,找到最深的满足 cnt[x] > 1 的节点。

    • 这个节点的深度就是该字符串与其他字符串的最长公共前缀长度。


为什么将 cnt[x]++ 写在 for 循环里面?

在字典树算法中,cnt[x]++ 的作用是记录每个节点被访问的次数。以下是详细解释:


1. cnt[x]++ 的作用

  • cnt[x]:表示从根节点到节点 xx 的路径所表示的前缀被多少个字符串共享。

  • cnt[x]++:每当一个字符串经过节点 x 时,cnt[x] 增加 1。


2. 为什么写在 for 循环里面?

  • 插入字符串时

    • 在插入字符串的过程中,每经过一个节点 x,都需要更新 cnt[x]

    • 这是因为每个节点都代表一个前缀,cnt[x] 记录了有多少个字符串共享这个前缀。

  • 查询最长公共前缀时

    • 在查询过程中,cnt[x] 用于判断当前前缀是否被多个字符串共享。

    • 如果 cnt[x] > 1,说明当前前缀被至少两个字符串共享。


3. 示例分析

假设有以下字符串:

abc
ab
a

插入过程

  1. 插入 abc

    • 经过节点 acnt[a] = 1

    • 经过节点 bcnt[ab] = 1

    • 经过节点 ccnt[abc] = 1

  2. 插入 ab

    • 经过节点 acnt[a] = 2

    • 经过节点 bcnt[ab] = 2

  3. 插入 a

    • 经过节点 acnt[a] = 3

查询过程

  1. 查询 abc

    • 节点 acnt[a] = 3 > 1,匹配长度 = 1。

    • 节点 bcnt[ab] = 2 > 1,匹配长度 = 2。

    • 节点 ccnt[abc] = 1,停止。

    • 最长公共前缀长度 = 2。

  2. 查询 ab

    • 节点 acnt[a] = 3 > 1,匹配长度 = 1。

    • 节点 bcnt[ab] = 2 > 1,匹配长度 = 2。

    • 最长公共前缀长度 = 2。

  3. 查询 a

    • 节点 acnt[a] = 3 > 1,匹配长度 = 1。

    • 最长公共前缀长度 = 1。

代码说明:

第一种实现

void insert(string a) {int n = a.length() - 1;int x = 1;for (int i = 1; i <= n; i++) {if (!tire[x][a[i] - 'a']) tire[x][a[i] - 'a'] = idx++;x = tire[x][a[i] - 'a'];cnt[x]++;}
}

特点:

  1. 字符串下标从 1 开始

    • 字符串 a 的下标从 1 开始,a[0] 被忽略。

    • 这是因为在主函数中,字符串被修改为 s[i] = '0' + s[i],即在字符串前面添加了一个字符 '0',使得有效字符从下标 1 开始。

  2. 循环范围

    • 循环从 i = 1 到 i = n,其中 n = a.length() - 1

    • 这样可以正确处理字符串的有效部分。


第二种实现

void insert(string a) {int x = 1;for (int i = 0; a[i]; i++) {if (!tire[x][a[i] - 'a']) tire[x][a[i] - 'a'] = idx++;x = tire[x][a[i] - 'a'];cnt[x]++;}
}

特点

  1. 字符串下标从 0 开始

    • 字符串 a 的下标从 0 开始,a[0] 是第一个字符。

    • 这与主函数中对字符串的处理方式不一致。

  2. 循环范围

    • 循环从 i = 0 开始,直到 a[i] 为 '\0'(字符串结束符)。

    • 这种写法适用于标准的 C 风格字符串(以 '\0' 结尾),但在 C++ 的 std::string 中,a[i] 不会自动包含 '\0'

为什么不能使用第二种实现?

  1. 字符串下标不一致

    • 在主函数中,字符串被修改为 s[i] = '0' + s[i],即在字符串前面添加了一个字符 '0',使得有效字符从下标 1 开始。

    • 如果使用第二种实现,a[0] 会被错误地当作有效字符处理,导致 Trie 树插入错误。

  2. 循环范围问题

    • 第二种实现假设字符串以 '\0' 结尾,但在 C++ 的 std::string 中,a[i] 不会自动包含 '\0'

    • 如果字符串中没有 '\0',循环会越界访问,导致未定义行为。

  3. 逻辑错误

    • 第二种实现无法正确处理主函数中对字符串的修改(添加了前缀字符 '0')。

    • 这会导致 Trie 树中插入的字符串与实际字符串不一致,影响后续的查询操作。

字典树(Trie)来解决问题,但它们的应用场景具体实现有所不同。以下是详细对比:


题目 1:最长公共前缀问题(依依的瓶中信)

问题描述

  • 给定 N 个字符串,对于每个字符串 Si​,找到与其他字符串的最长公共前缀的长度。

代码特点

  • cnt[x]++ 写在 for 循环里面

    • 在插入字符串时,每经过一个节点 x,都会更新 cnt[x]

    • 目的是记录每个节点被多少个字符串共享,从而在查询时判断当前前缀是否被多个字符串共享。

核心逻辑

  • 插入时

    • 每经过一个节点 x,cnt[x]++,表示当前前缀被一个字符串共享。

  • 查询时

    • 遍历字符串的每个字符,找到最深的满足 cnt[x] > 1 的节点,其深度就是最长公共前缀的长度。


题目 2:判断是否有重复字符串

问题描述

  • 给定 N 个字符串,判断是否存在两个相同的字符串。

代码特点

  • cnt[x]++ 写在 for 循环外面

    • 在插入字符串时,cnt[x]++ 只在字符串的末尾节点执行。

    • 目的是记录每个字符串的末尾节点被访问的次数。

核心逻辑

  • 插入时

    • 在字符串的末尾节点 x,cnt[x]++,表示当前字符串被插入了一次。

  • 查询时

    • 遍历字符串的每个字符,找到末尾节点 x。

    • 如果 cnt[x] > 1,说明当前字符串被插入了多次,即存在重复字符串。


为什么 cnt[x]++ 的位置不同?

题目 1:最长公共前缀问题

  • 目标:统计每个前缀被多少个字符串共享。

  • 实现

    • 在插入时,每经过一个节点 x,cnt[x]++,表示当前前缀被一个字符串共享。

    • 这样可以在查询时,通过 cnt[x] 判断当前前缀是否被多个字符串共享。

题目 2:判断是否有重复字符串

  • 目标:判断是否存在两个相同的字符串。

  • 实现

    • 在插入时,只在字符串的末尾节点 x,cnt[x]++,表示当前字符串被插入了一次。

    • 这样可以在查询时,通过 cnt[x] 判断当前字符串是否被插入了多次。

总结

题目目标cnt[x]++ 位置作用
最长公共前缀问题找到与其他字符串的最长公共前缀for 循环里面记录每个前缀被多少个字符串共享
判断是否有重复字符串判断是否存在两个相同的字符串for 循环外面记录每个字符串的末尾节点被访问的次数

通过调整 cnt[x]++ 的位置,可以灵活地实现不同的功能。

 

 

 

 

http://www.dtcms.com/a/503683.html

相关文章:

  • 【Flume】Flume Learning
  • 和网站设计人员谈价要注意什么那些网站是asp做的
  • 网站视频提取软件app天河做网站设计
  • GPU服务器存储选型指南:SFF与LFF硬盘深度解析与实战策略
  • 学校网站建设介绍吉林网络推广代运营
  • 集合性能基准测试报告:ArrayList vs LinkedList、HashMap vs TreeMap、并发 Map 四兄弟
  • 黄石做网站公司二手商品网站制作
  • c2c网站功能关于网站建设的英文歌
  • k8s(十)Helm详解
  • 建设部执业资格注册中心网站查询免签约收款WordPress
  • 百度推广用户注册单页网站如何优化
  • 数据库--视图、索引
  • 硅基计划5.0 MySQL 叁 E-R关系图联合/多表查询三大连接子查询合并查询
  • 网站设计连接数据库怎么做如何做好网站推广营销
  • Langgraph译文2:多智能体系统
  • 太原云起时网站建设工作室logo设计免费生成
  • 基于Trae/Whisper/FFmpeg与Knowledge Graph MCP技术开发语音生成会议纪要智能应用
  • [嵌入式系统-144]:“智能体机器人”操作系统
  • iis网站开发教程河西区做网站的公司
  • FFmpeg 基本API av_find_input_format函数内部调用流程分析
  • 制作网页的网站2023电商排行榜前十名
  • 【课堂笔记】复变函数-5
  • nas可以做视频网站吗深圳律师网站建设
  • 抑制高电压浪涌芯片LT4356
  • LLMs之RAG之Benchmark:面向真实场景的检索嵌入基准(RTEB)—理论、设计与实践指南
  • 从网址怎么看网站的域名有模板怎么做网站
  • 做建网站的公司wordpress点播主题
  • ES6 箭头函数
  • [FIH][GMS] 2025-04 Google announcement Part1
  • 建站论坛北京有什么网上推广的网站吗