对比两个字符串相等_字符串匹配问题

b309e5e07fb81b1db1dffa30d8718ca3.png

0.题目

在一个主串S={a, b, c, c, b, c, a, b, d}, 模式串T={a, b, d};请找出模式串在主串中第一次出现的位置
提示: 不需要考虑字符串大小写问题,字符均为小写字母

4a550b5dc1831a88cb9b8cf82e50d4e3.png
第一次在7的位置匹配上

1.BF算法

Brute-Force算法,简称为 BF算法,是一种简单朴素的模式匹配算法,常用于在一个主串 S 内查找一个子串 T 的出现位置。

核心思想与操作是:

  1. 对于给定的主串 S 与子串 P ,主串 S 的长度为 N,子串 T 的长度为 M ;
  2. 首先,将 S[1] 和 T[1] 进行比较;
  3. 若相等,则再比较 S[2] 和 T[2] ,一直到 T[M] 为止;
  4. 若 S[1] 和 T[1] 不等,则 T 向右移动一个字符的位置,再依次进行比较

假设主串 S="abcababca";模式串T = "abcdex"

开始比较

a3d3956612497a433c18132115e8344e.png
对比a

a418d8770d027c095118c6dfb55e008d.png
对比b

de53375630229f02d542225f768441b9.png
对比c

664bdf1be9582e3b54aa342c1e3aecf4.png
匹配不上,开始回溯

28fc04db5215465af6fd1ce7247210b9.png
只要匹配不上就开始回溯

字符串数组约定: 0位放字符串数组的长度

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0#define MAXSIZE 40    /* 存储空间初始分配量 */
typedef int Status;   /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int ElemType; /* ElemType类型根据实际情况而定,这里假设为int */
typedef char String[MAXSIZE+1]; /*  0号单元存放串的长度 *//* 生成一个其值等于chars的串T */
Status StrAssign(String T,char *chars)
{int i;if(strlen(chars)>MAXSIZE)return ERROR;else{T[0]=strlen(chars);for(i=1;i<=T[0];i++)T[i]=*(chars+i-1);return OK;}
}Status ClearString(String S)
{S[0]=0;/*  令串长为零 */return OK;
}/*  输出字符串T。 */
void StrPrint(String T)
{int i;for(i=1;i<=T[0];i++)printf("%c",T[i]);printf("n");
}/*  输出Next数组值。 */
void NextPrint(int next[],int length)
{int i;for(i=1;i<=length;i++)printf("%d",next[i]);printf("n");
}/* 返回串的元素个数 */
int StrLength(String S)
{return S[0];
}

思路:

  1. 分别利用计数指针i和j指示主串S和模式T中当前正待比较的字符位置,i初值为pos,j的初值为1;
  2. 如果2个串均为比较到串尾,即i和j均小于等于S和T的长度时, 则循环执行以下的操作:
    1. S[i]和T[j]比较,若相等,则i 和 j分别指示串中下一个位置,继续比较后续的字符;
    2. 若不相等,指针后退重新开始匹配. 从主串的下一个字符串(i = i - j + 2)起再重新和模式第一个字符(j = 1)比较;
  3. 如果j > T.length, 说明模式T中的每个字符串依次和主串S找中的一个连续字符序列相等,则匹配成功,返回和模式T中第一个字符的字符在主串S中的序号(i-T.length);否则匹配失败,返回0;
int Index_BF(String S, String T,int pos){//i用于主串S中当前位置下标值,若pos不为1,则从pos位置开始匹配int i = pos;//j用于子串T中当前位置下标值int j = 1;//若i小于S的长度并且j小于T的长度时,循环继续while (i <= S[0] && j <= T[0]) {//比较的2个字母相等,则继续比较if (S[i] == T[j]) {i++;j++;}else{//不相等,则指针后退重新匹配//i 退回到上次匹配的首位的下一位;//加1,因为是子串的首位是1开始计算;//再加1的元素,从上次匹配的首位的下一位;i = i-j+2;//j 退回到子串T的首位j = 1;}}//如果j>T[0],则找到了匹配模式if (j > T[0]) {//i母串遍历的位置 - 模式字符串长度 = index 位置return  i - T[0];}else{return -1;}
}

2.RK算法

08d6dc1e6213921a68fe29b74a8938f7.png

1.思想:把需要对比的字符串转换成相应的哈希值

字母转换成哈希值,将当前的字母-'a'得到的数字

比如:

a - a = 0;
b - a = 1;
c - a = 2;
d - a = 3;
e - a = 4;

2.小写字母之间存在进制,即26进制

例如:

"cba" = 'c'*26*26 + 'b'*26 + 'a' *1= (c - a)*26^2 + (b - a)*26^1 + (a - a) *26^0= 2 * 26^2 + 1 * 26 + 0 * 1= 1352 + 26 + 0= 1378

代码:

//d 表示进制
#define d 26//4.为了杜绝哈希冲突. 当前发现模式串和子串的HashValue 是一样的时候.还是需要二次确认2个字符串是否相等.
int isMatch(char *S, int i, char *P, int m)
{int is, ip;for(is=i, ip=0; is != m && ip != m; is++, ip++)if(S[is] != P[ip])return 0;return 1;
}//3.算出最d进制下的最高位
//d^(m-1)位的值;
int getMaxValue(int m){int h = 1;for(int i = 0;i < m - 1;i++){h = (h*d);}return h;
}/** 字符串匹配的RK算法* Author:Rabin & Karp* 若成功匹配返回主串中的偏移,否则返回-1*/
int RK(char *S, char *P)
{//1. n:主串长度, m:子串长度int m  = (int) strlen(P);int n  = (int) strlen(S);printf("主串长度为:%d,子串长度为:%dn",n,m);//A.模式串的哈希值; St.主串分解子串的哈希值;unsigned int A   = 0;unsigned int St  = 0;//2.求得子串与主串中0~m字符串的哈希值[计算子串与主串0-m的哈希值]//循环[0,m)获取模式串A的HashValue以及主串第一个[0,m)的HashValue//此时主串:"abcaadddabceeffccdd" 它的[0,2)是ab//此时模式串:"cc"//cc = 2 * 26^1 + 2 *26 ^0 = 52+2 = 54;//ab = 0 * 26^1 + 1 *26^0 = 0+1 = 1;for(int i = 0; i != m; i++){//第一次 A = 0*26+2;//第二次 A = 2*26+2;A = (d*A + (P[i] - 'a'));//第一次 st = 0*26+0//第二次 st = 0*26+1St = (d*St + (S[i] - 'a'));}//3. 获取d^m-1值(因为经常要用d^m-1进制值)int hValue = getMaxValue(m);//4.遍历[0,n-m], 判断模式串HashValue A是否和其他子串的HashValue 一致.//不一致则继续求得下一个HashValue//如果一致则进行二次确认判断,2个字符串是否真正相等.反正哈希值冲突导致错误//注意细节://① 在进入循环时,就已经得到子串的哈希值以及主串的[0,m)的哈希值,可以直接进行第一轮比较;//② 哈希值相等后,再次用字符串进行比较.防止哈希值冲突;//③ 如果不相等,利用在循环之前已经计算好的st[0] 来计算后面的st[1];//④ 在对比过程,并不是一次性把所有的主串子串都求解好Hash值. 而是是借助s[i]来求解s[i+1] . 简单说就是一边比较哈希值,一边计算哈希值;for(int i = 0; i <= n-m; i++){if(A == St)if(isMatch(S,i,P,m))//加1原因,从1开始数return i+1;St = ((St - hValue*(S[i]-'a'))*d + (S[i+m]-'a'));}return -1;
}

使用并打印:

char *buf="abcababcabx";
char *ptrn="cabab";
printf("主串为%sn",buf);
printf("子串为%sn",ptrn);int index = RK(buf, ptrn);
printf("find index : %dn",index);

0a9578de5ead9dc2ea73bc5d2c6507c1.png
打印

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/501952.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

eclipse 导入maven项目_解决Eclipse导入JAVA WEB项目错误的问题

蓝字关注远浩老师一、 本文问题在开发中不可避免地要涉及导入项目。Eclipse作为常用开发工具&#xff0c;导入JAVA WEB项目文件也很方便&#xff0c;但是我们经常发现导入完的项目有红色的叉来做错误提醒&#xff0c;甚至一些代码也出现错误提示的红线&#xff0c;如下图。 为了…

并发执行变成串行_大神浅谈数据库并发控制 锁和 MVCC

在学习几年编程之后&#xff0c;你会发现所有的问题都没有简单、快捷的解决方案&#xff0c;很多问题都需要权衡和妥协&#xff0c;而本文介绍的就是数据库在并发性能和可串行化之间做的权衡和妥协 - 并发控制机制。&#xfffc;如果数据库中的所有事务都是串行执行的&#xff…

docker 部署_Nginx K8s + Docker 部署 ,虚拟机部署教程。

Nginx K8s Docker 部署 &#xff0c;虚拟机部署教程&#xff01;Linux 虚拟机 部署1、下载nginx:http://nginx.org/download/2、选择一个版本进行下载&#xff1a;wget http://nginx.org/download/nginx-1.14.0.tar.gz3、解压&#xff1a;tar -xvf nginx-1.14.0.tar.gz4、安装…

双机热备_双机热备软件哪个好?双机热备软件推荐

服务器维护和管理是企业健康稳定运营的一项重要工作&#xff0c;而双机热备可以提供服务器的高可用性。但是成熟好用的双机热备软件有哪些呢&#xff1f;下面就给大家推荐几款。微软MSCSMSCS&#xff08;Microsoft Cluster Service&#xff09;实际上是微软自带的&#xff0c;不…

Json和Xml

一、前言 学习心得&#xff1a;C# 入门经典第8版书中的第21章《Json和Xml》 二、Xml的介绍 Xml的含义&#xff1a; 可标记性语言&#xff0c;它将数据以一种特别简单文本格式储存。让所有人和几乎所有的计算机都能理解。 XML文件示例&#xff1a; <?xml version"1.…

ec20驱动_物联网基础:移远EC20固件升级

使用移远 QFlash_V4.14 工具升级移远 EC20 4G模块固件1 准备工作 1.1 EC20 USB驱动安装安装过程参考移远官方手册&#xff1a;《Quectel_LTE&5G_Windows_USB_Driver_安装指导_V1.0.pdf》&#xff0c;有详细USB安装指导&#xff0c;该手册及驱动文件可以去移远官方下载或后续…

的微波感知_上海交大彭志科教授团队研发:微波微动监测与智能感知技术

上海9月18日电(葛俊俊) 准确监测方舱医院大量感染患者的生命状况&#xff0c;精确“诊断”大桥工程结构是否存在安全隐患&#xff0c;随时随地获取独居老人在家的健康体征……上海交通大学彭志科教授团队研发的基于微波感知的微动监测与环境智能前瞻技术&#xff0c;像一种神奇…

小米笔记本引导修复_知识帖,笔记本电脑不能开机?你可以试试这些办法

大家经常遇到电脑开机不能进入系统的时候是不是特别难受,朝歌后面几篇文章会讲讲一些常见的电脑问题和解决办法啦 前面有一个系列的文章都是在组装电脑的问题,大家感兴趣的可以关注了去主页看看呀 在现在的日常生活里,笔记本电脑对于很多人来说会比台式机重要的多,因为笔记…

java同步锁synchronized_synchronized、锁、多线程同步的原理是咋样的?

先综述个结论&#xff1a;一般说的synchronized用来做多线程同步功能&#xff0c;其实synchronized只是提供多线程互斥&#xff0c;而对象的wait()和notify()方法才提供线程的同步功能。一般说synchronized是加锁&#xff0c;或者说是加对象锁&#xff0c;其实对象锁只是synchr…

python追加_如何在Python中追加文件?

慕田峪7331174 您需要在附加模式下打开文件&#xff0c;方法是将“a”或“ab”设置为模式。见open&#xff08;&#xff09;。使用“a”模式打开时&#xff0c;写入位置将始终位于文件末尾&#xff08;附加&#xff09;。您可以使用“a ”打开以允许读取&#xff0c;向后搜索和…

系统相机裁剪比例_拍不出好照片,你缺的不是好手机而是相机设置的秘笈

玩转手机摄影&#xff0c;每天分享原创的手机摄影教程&#xff0c;手机相机功能、人像、风光、夜景、创意拍摄技巧&#xff0c;还有后期调色、修图等教程&#xff0c;欢迎感兴趣的朋友点击右上角&#xff0c;关注我们&#xff01;--------------------------------------------…

任意点 曲线距离_中级数学11-曲线函数

距离、中点、圆抛物线椭圆双曲线非线性方程曲线本章介绍曲线及其性质。这里应用两圆锥体构成的推覆体与一个平面相交的截面&#xff0c;形成的曲线。从左到右截面&#xff1a;圆、抛物线、椭圆、双曲线距离、中点、圆应用勾股定理可求出三角形各边的长度。同样在直角坐标系中&a…

opencv 边缘平滑_基于OpenCV的车道检测实现(一)

无人驾驶的话题日趋起热&#xff0c;而车道线检测对于无人驾驶的路径规划来讲特别重要。要遵守交通规则&#xff0c;首先的要求便是对车道线检测&#xff0c;而且通过检测车道线可以进一步的检测地面指示标志、进行前碰撞预警策略设计等。早早就对OpenCV感兴趣&#xff0c;但迟…

字符串equal_Java String:字符串常量池

作者&#xff1a;Seven_Nee来自&#xff1a;https://segmentfault.com/a/1190000009888357作为最基础的引用数据类型&#xff0c;Java 设计者为 String 提供了字符串常量池以提高其性能&#xff0c;那么字符串常量池的具体原理是什么&#xff0c;我们带着以下三个问题&#xff…

cubemx串口的发送与接收_串口收发模块设计

串口收发模块设计作者&#xff1a;巩文宏 公众号&#xff1a;数字积木 该串口收发模块有串口发送模块&#xff0c;串口接收模块&#xff0c;波特率生成模块&#xff0c;发送数据fifo模块&#xff0c;接收数据的fifo模块组成。 默认配置下&#xff0c;要求输入的参考时钟为50MHz…

字段类型 sqoop_数据迁移工具Sqoop

熬过去&#xff0c;出众。熬不过&#xff0c;出局。这是最真实的人生&#xff0c;人都是熬过来的。Sqoop 是一个用来将Hadoop和关系型数据库中的数据相互转移的工具&#xff0c;它是Hadoop环境下连接关系数据库与Hadoop存储系统的桥梁&#xff0c;支持多种关系型数据源和Hive、…

git 删除tag_git使用教程9pycharm 使用 tag 打标签

前言当我们的代码完成了第一阶段的需求&#xff0c;版本稳定后&#xff0c;希望能出个稳定版本。于是在 commit 后需要打个 tag 标签&#xff0c;也就是我们平常说的版本号&#xff0c;如v1.0版本本篇讲解如何使用 pycharm 打 tag 标签&#xff0c;并推送到 github 上&#xff…

模块 python_Python入门基础:模块基础

模块是一个文件(.py文件)&#xff0c;包含变量&#xff0c;类定义语句和与特定任务相关的功能。预先装有Python的Python模块称为标准库模块。创建我们的模块我们将创建一个名为tempConversion.py的模块&#xff0c;该模块将值从F转换为C&#xff0c;反之亦然。# tempConversion…

hash地址_深入浅出一致性Hash原理

一、前言在解决分布式系统中负载均衡的问题时候可以使用Hash算法让固定的一部分请求落到同一台服务器上&#xff0c;这样每台服务器固定处理一部分请求&#xff08;并维护这些请求的信息&#xff09;&#xff0c;起到负载均衡的作用。但是普通的余数hash&#xff08;hash(比如用…

go语言io reader_Go语言中的io.Reader和io.Writer以及它们的实现

在使用Go语言的过程中&#xff0c;无论你是实现web应用程序&#xff0c;还是控制台输入输出&#xff0c;又或者是网络操作&#xff0c;不可避免的会遇到IO操作&#xff0c;使用到io.Reader和io.Writer接口。也也许对这两个接口和相关的一些接口很熟悉了&#xff0c;但是你脑海里…