计算两个字符串最大公有子串

发布时间 - 2026-01-10 22:45:23    点击率:

背景

对算法一直应用的比较少,最近看到一些典型的算法想练练手,想看看到底有多么让人讨厌。其实发现算法都有一定的套路,一般并不是临时凭空想出来的,大都建立在一些已经存在的经典算法知识以及数据结构上。换句话来说,如果某些玩法之前未接触过,那么让你在短时间内临时想出来还是有一定难度的。这有点类似项目经验,如果曾经做过一个CRM系统,下次再碰到它时你就轻松很多,如果你挑战的是一个你从未遇到过的系统,你只能凭已有知识去强吃。

计算两个字符串最大公共子串

这个也是经常遇到到,给出两个任意长度的字符串,输出最大公有字符串,比如输入abcdef,cdef,则输出cdef。

解决方案

采用双层循环,指针移动来记录所有子串,最后取最大长度子串。利用临时队列来存储循环过程中匹配成功的字符元素,从两个字符串首个元素开始匹配。

  • 如果a.charAt(i)=b.charAt(j),标记开始匹配,同时移动两者指针,并将相同字符串压入临时队列中
  • 如果a.charAt(i)!=b.charAt(j),只移动b的指针。如果处于匹配中,则将临时队列存储到结果集中,并清空临时队列。
  • 如果a,b任意一个到了最后一个元素,将临时队列中的值存储到结果集中,并清空临时队列

示意图

从元素0开始比较

字符串A指针不动,B依次向后找至少找到相同的,将相同字符压入临时队列中。

出现第一个匹配元素

当出现匹配元素后,两个字符串均向后移动一个元素再做比较。

匹配出现中断

如果前面已经开始匹配成功,向后出现字符不相同时,终止。

重置索引,循环匹配

字符串B指针向后移动,字符串A的指针重置,递归上面的步骤。

示例代码

下面的示例将所有子串均记录下来,如果只想输出最大子串需要改下逻辑,定义一个最大子串,然后与循环计算的子串相比较,取两者长度最大值即可。

String b="abcdeqwe";
String a="cdeabrwqedeqwe";
int lengthA=a.length();
int lengthB=b.length();
//标识是否开始匹配
boolean match=false;
//循环中用于存储相同字符的临时队列
Queue tmpResult=new ArrayQueue();
//存储所有子串
List<Queue> result=new ArrayList<>();
for(int i=0;i<lengthA;i++){
 int indexA=i;
 for(int j=0;j<lengthB;j++){
  if(a.charAt(indexA)==b.charAt(j)){
   if(!match) {
    match = true;
   }
   tmpResult.add(a.charAt(indexA));
   if(indexA<lengthA-1) {
    indexA++;
   }
  }
  else {
   if(match) {
    result.add(tmpResult);
    //重置条件
    tmpResult=new ArrayQueue();
    indexA=i;
   }
  }
  if(j==lengthB-1||i==lengthA-1){
   if(!tmpResult.isEmpty()){
    result.add(tmpResult);
    //重置条件
    tmpResult=new ArrayQueue();
   }
  }
 }
}
//取最大的子串
Queue stringResult= Collections.max(result, new Ordering<Queue>() {
 @Override
 public int compare(Queue left, Queue right) {
  return Integer.compare(left.size(),right.size());
 }
});

优点

指针移动在循环过程中不会产生多余的临时字符串,如果是substring方案就需要考虑效率了。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!


# 计算  # 字符串  # C语言中计算字符串长度与分割字符串的方法  # C#计算字符串哈希值(MD5、SHA)的方法小结  # Lua中计算、执行字符串中Lua代码的方法  # Shell脚本计算字符串长度和判断字符串为空小技巧  # Lua判断字符串中包含中文字符的方法和计算字符串宽度函数分享  # JavaScript实现计算字符串中出现次数最多的字符和出现的次数  # 利用PHP函数计算中英文字符串长度的方法  # PHP改进计算字符串相似度的函数similar_text()、levenshtein()  # JavaScript indexOf方法入门实例(计算指定字符在字符串中首次出现的位置)  # C#和SQL实现的字符串相似度计算代码分享  # 有一定  # 想出  # 递归  # 清空  # 过程中  # 的是  # 如果你  # 让人  # 第一个  # 你就  # 已有  # 时间内  # 数据结构  # 不动  # 并将  # 做过  # 只想  # 已经开始  # 想看  # 句话 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel如何构建RESTful API_Laravel标准化API接口开发指南  Laravel如何发送系统通知?(Notification渠道示例)  如何在 React 中条件性地遍历数组并渲染元素  如何快速打造个性化非模板自助建站?  如何在 Telegram Web View(iOS)中防止键盘遮挡底部输入框  EditPlus中的正则表达式 实战(2)  Linux系统命令中tree命令详解  美食网站链接制作教程视频,哪个教做美食的网站比较专业点?  深入理解Android中的xmlns:tools属性  Win11怎么关闭专注助手 Win11关闭免打扰模式设置【操作】  如何在万网ECS上快速搭建专属网站?  焦点电影公司作品,电影焦点结局是什么?  laravel怎么在请求结束后执行任务(Terminable Middleware)_laravel Terminable Middleware请求结束任务执行方法  Laravel Facade的原理是什么_深入理解Laravel门面及其工作机制  如何在腾讯云服务器快速搭建个人网站?  Laravel怎么调用外部API_Laravel Http Client客户端使用  Laravel如何获取当前登录用户信息_Laravel Auth门面使用与Session用户读取【技巧】  Laravel怎么使用Blade模板引擎_Laravel模板继承与Component组件复用【手册】  今日头条微视频如何找选题 今日头条微视频找选题技巧【指南】  Java遍历集合的三种方式  Laravel怎么返回JSON格式数据_Laravel API资源Response响应格式化【技巧】  如何用5美元大硬盘VPS安全高效搭建个人网站?  Laravel怎么多语言本地化设置_Laravel语言包翻译与Locale动态切换【手册】  网站制作怎么样才能赚钱,用自己的电脑做服务器架设网站有什么利弊,能赚钱吗?  Linux后台任务运行方法_nohup与&使用技巧【技巧】  电商网站制作价格怎么算,网上拍卖流程以及规则?  Laravel怎么实现验证码功能_Laravel集成验证码库防止机器人注册  如何为不同团队 ID 动态生成多个“认领值班”按钮  宙斯浏览器怎么屏蔽图片浏览 节省手机流量使用设置方法  Python文件流缓冲机制_IO性能解析【教程】  Laravel如何使用Scope本地作用域_Laravel模型常用查询逻辑封装技巧【手册】  家族网站制作贴纸教程视频,用豆子做粘帖画怎么制作?  高端智能建站公司优选:品牌定制与SEO优化一站式服务  Android中Textview和图片同行显示(文字超出用省略号,图片自动靠右边)  javascript中闭包概念与用法深入理解  如何用AI帮你把自己的生活经历写成一个有趣的故事?  浅析上传头像示例及其注意事项  Laravel辅助函数有哪些_Laravel Helpers常用助手函数大全  Laravel如何使用API Resources格式化JSON响应_Laravel数据资源封装与格式化输出  JavaScript中如何操作剪贴板_ClipboardAPI怎么用  Laravel怎么集成Log日志记录_Laravel单文件与每日日志配置及自定义通道【详解】  php增删改查怎么学_零基础入门php数据库操作必知基础【教程】  在centOS 7安装mysql 5.7的详细教程  创业网站制作流程,创业网站可靠吗?  Laravel如何处理CORS跨域请求?(配置示例)  如何为不同团队 ID 动态生成多个独立按钮  BootStrap整体框架之基础布局组件  Win11摄像头无法使用怎么办_Win11相机隐私权限开启教程【详解】  Laravel如何使用Laravel Vite编译前端_Laravel10以上版本前端静态资源管理【教程】  Laravel模型关联查询教程_Laravel Eloquent一对多关联写法