串的定义,实现和模式匹配

串的相关概念及操作

串的定义

串:是由零个或多个字符组成的有限序列。
空串:不包含任何字符的串称为空串。
子串:串中任意个连续的字符组成的子序列称为该串的子串。
空格串:由一个或多个空格组成的串称为空格串(空格串不是空串,其长度为串中空格字符的个数)。

串的存储结构

定长顺序存储表示

类似于线性表的顺序存储结构,用一组地址连续的存储单元存储串值的字符序列。在串的顺序存储结构中,为每个串变量分配一个固定长度的存储区,即定长数组。

#define MAXSIZE 255      //预定于最大串长为255typedef struct {char ch[MAXSIZE];    //每个分量存储一个字符int length;          //串的实际长度
} SString;

堆分配存储表示

堆分配存储表示仍然以一组地址连续的存储单元存放串值得字符序列,但它们得存储空间是在执行过程中动态分配得到的。

typedef struct{char *ch;  //按串长分配存储去,ch指向串的基地址int length;  //串的长度
}HString;

块链存储表示

由于串的特殊性(每个元素只有一个字符),在具体实现时,每个结点既可以存放一个字符,也可以存放多个字符。
每个结点称为块,整个链表称为块链结构。
在这里插入图片描述

串的相关操作

  • StrAssign(&T, chars): 赋值操作。把串T赋值为 chars
  • Strcopy(&T, S):复制操作。由串S复制得到串T。
  • StrEmpty(S): 判空操作。若S为空串,则返回TRUE,否则返回 FALSE
  • StrCompare(S,T): 比较操作。若S>T,则返回值>0;若S=T,则返回值=0;若S<T,则返回值<0
  • StrEngth(S): 求串长。返回串S的元素个数
  • Substring(&Sub,S,pos,1en):求子串。用Sub返回串S的第pos个字符起长度为len的子串
  • Concat(&T,S1,S2): 串联接。用T返回由S1和S2联接而成的新串。
  • Index(S,T):定位操作。若主串S中存在与串T值相同的子串,则返回它在主串S中第一次出现的位置;否则函数值为0
  • Clearstring(&S):清空操作。将S清为空串 Destroystring(&S): 销毁串。将串S销毁
  • 不同的高级语言对串的基本操作集可以有不同的定义方法。在上述定义的操作中,串赋值StrAssign、串比较 StrCompare、求串长Strength、串联接 Concat及求子串Substring五种操作构成串类型的最小操作子集,即这些操作不可能利用其他串操作来实现;反之,其他串操作(除串清除Clearstring和串销毁 Destroystring外)均可在该最小操作子集上实现。 例如,可利用判等、求串长和求子串等操作实现定位函数 Index(S,T)。

串的模式匹配

简单的模式匹配算法

子串的定位操作通常称为串的模式匹配,它求的是子串(常称模式串)在主串中的位置。这里采用静态顺序存储结构,给出一种不依赖于其他串操作的暴力匹配算法.

算法思想

从主串的第一个字符起,与子串的第一个字符比较,若相等,则继续逐个比较后续字符;若不相等,则从主串的下一个字符起,重新和子串的字符比较,以此类推。
缺点:当某些子串与模式串能部分匹配时,主串的扫描指针经常回溯,导致时间开销大
暴力模式匹配算法的最坏时间复杂度为 O(nm) 其中 n 和 m 分别为主串和子串的长度。

完整代码

#include<stdio.h>
#include<string.h>
#define MAXSIZE 255      //预定于最大串长为255typedef struct{char ch[MAXSIZE];    //每个分量存储一个字符int length;          //串的实际长度
} SString;//初始化串 
void InitString(SString &S, SString &T) {for (int i = 0; i < MAXSIZE; ++i) {S.ch[i] = '\0';T.ch[i] = '\0';}S.length = 0;T.length = 0;
}int Index(SString S, SString T){int i = 0, j = 0;while(i < S.length && j < T.length){if(S.ch[i] == T.ch[j]){++i; ++j;	//继续比较后继字符}else{//指针后退重新开始匹配i = i-j+1;j = 0;}}if(j >= T.length){return i - T.length;}else{return 0;}
}int main(){SString S,T;InitString(S, T);//初始化串 char a[15] = {'h','o','l','l','o','h','e','l','l','o','h','l','l','e','o'};strcpy(S.ch, a);    // a数组复制给S的数组	S.length = 15;for(int i = 0;i < S.length;i++){//打印S的数组printf("%2c", S.ch[i]);}printf("\n");char b[5] = {'h','e','l','l','o'};strcpy(T.ch, b);// b数组复制给S的数组	T.length = 5;for(int i = 0;i < T.length;i++){//打印T的数组printf("%2c", T.ch[i]);}printf("\n");int flag = Index(S, T);printf("%d\n", flag);if(flag){printf("find it and the number is %d\n", flag);}else{printf("cannot find!\n"); } return 0;
} 

KMP算法

求解next数组

//计算next数组 
void Getnext(SString T,  int *next) 
{for(int j = 0; j < 5; j++ ){next[j] = 0;} int i,k;i=0;k=-1;next[0]=-1;while (i<T.length - 1)  /* 此处T[0]表示串T的长度 */{if(k==-1 || T.ch[i]== T.ch[k]) {i++;  k++;  next[i] = k;} else k= next[k];	/* 若字符不相同,则k值回溯 */}for(int j = 0; j < 5; j++ ){printf("%2d", next[j] + 1);} 
}

KMP匹配算法

//KMP算法的匹配过程
int IndexKMP(SString S, SString T, int *next){int i = 0;int j = 0;while(i < S.length && j < T.length){if(j == -1 || S.ch[i] == T.ch[j]){++i; ++j;}else{j = next[j];}}if(j > T.length -1)return i - j + 1;elsereturn 0;
}

KMP完整代码

目标串:a b a b c a b c a c b a b
模式串:a b c a c

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define Maxsize 255typedef struct{char ch[Maxsize];//存放字符 int length;//串的实际长度 
}SString;//初始化
void InitString(SString &S,SString &T){for(int i = 0; i < Maxsize; i++){S.ch[i] = '\0';T.ch[i] = '\0';}S.length = 0;T.length = 0;} //计算next数组 
void Getnext(SString T,  int *next) 
{for(int j = 0; j < 5; j++ ){next[j] = 0;} int i,k;i=0;k=-1;next[0]=-1;while (i<T.length - 1)  /* 此处T[0]表示串T的长度 */{if(k==-1 || T.ch[i]== T.ch[k]) {i++;  k++;  next[i] = k;} else k= next[k];	/* 若字符不相同,则k值回溯 */}for(int j = 0; j < 5; j++ ){printf("%2d", next[j]);} 
}//打印字符数组 
void PrintString(SString S, SString T){for(int i = 0;i < S.length;i++){printf("%2c", S.ch[i]);}printf("\n");for(int i = 0;i < T.length;i++){printf("%2c", T.ch[i]);}printf("\n");
}//KMP算法的匹配过程
int IndexKMP(SString S, SString T, int *next){int i = 0;int j = 0;while(i < S.length && j < T.length){if(j == -1 || S.ch[i] == T.ch[j]){++i; ++j;}else{j = next[j];}}if(j > T.length -1)return i - j + 1;elsereturn 0;
}int main(){SString S, T;InitString(S, T); //初始化 char a[13] = {'a','b','a','b','c','a','b','c','a','c','b','a','b'};char b[5] = {'a','b','c','a','c'};strcpy(S.ch, a);//将a数组中的字符复制到S数组中 S.length = 13;strcpy(T.ch, b);//将b数组中的字符复制到T数组中 T.length = 5;PrintString(S, T);//打印字符串 int *next = (int*)malloc(6*sizeof(int));Getnext(T, next);//求解next数组printf("\n");int index = IndexKMP(S, T, next);//KMP匹配算法 if(index){printf("The same string is %d", index);}else{printf("The same string cannot find");}return 0;
} 

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

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

相关文章

冯诺依曼体系结构/什么是OS?

一、体系结构图 示意图 控制器可以控制其它4个硬件&#xff0c;四个硬件直接可以进行数据传输。 5大硬件 但是这些个体需要用“线”连接。 为什么要有存储器&#xff1f; 如果没有&#xff0c;实际速度则为输入、输出设备的速度。 加上后&#xff0c;变为内存的速度。&#…

SquirrelMail实现Web方式收发邮件_xionglling的博客-CSDN博客

SquirrelMail实现Web方式收发邮件_xionglling的博客-CSDN博客小松鼠实现Web邮件服务SquirrelMail 是一个用PHP开发的Web邮件系统。它内置纯PHP支持的IMAP和SMTP协议&#xff0c;所有页面都遵循 HTML 4.0标准(没有使用任何 JavaScript 代码)&#xff0c;以便最大限度兼容各种多浏…

【程序员必知必会3】你还不懂ClickHouse和Hive的区别?!

ClickHouse和Hive究竟哪些区别 ClickHouse和Hive都是用于大数据处理和分析的分布式存储和计算系统&#xff0c;但它们之间存在一些区别&#xff1a; 架构&#xff1a;ClickHouse采用列式存储和向量化执行引擎&#xff0c;可以实现亚秒级别的数据查询。而Hive采用基于Hadoop的数…

亚马逊云科技通过生成式AI,帮助清华RIOS加速计算和分析的处理效率

近日&#xff0c;硬件创建平台Efabless宣布了其第一届“生成式AI开源芯片设计挑战赛”&#xff08;AI Generated Open-Source Silicon Design Challenge&#xff09;的评选结果。来自清华大学的RISC-V国际开源实验室&#xff08;RIOS Lab&#xff09;团队基于亚马逊云科技云上科…

JLink和ST-Link接口引脚介绍

STM32F1系列&#xff0c;STM8S系列&#xff0c;PY32F003系列都用过好久了&#xff0c;但是对JLink和ST-Link下载器认识&#xff0c;还是很肤浅的。有时候&#xff0c;需要自己接线&#xff0c;却不知道引脚定义&#xff0c;特整理如下&#xff1a; 1、ST-Link ST-Link适合对象…

解决IDEA中java的system.properties乱码问题

在拉了别人的代码到本地后发现system.properties中中文注释都变成了乱码&#xff0c;故记录下解决步骤&#xff0c;供参考&#xff0c;我的系统是mac系统 1、在IDEA中打开设置&#xff0c;IDEA--->Preferences 2、点击Editor-->File Encodings 3、图中三处选择UTF-8&…

智能配电室运维云平台

智能配电室运维云平台依托电易云-智慧电力物联网&#xff0c;是通过物联网技术实现配电设备智能化管理和运维的云服务系统。该平台可以实时监测配电设备的运行状态、能耗情况、故障报警等信息&#xff0c;并通过云计算、大数据等技术进行分析和处理&#xff0c;提供精准的数据支…

传输层—UDP原理详解

目录 前言 1.netstat 2.pidof 3.UDP协议格式 4.UDP的特点 5.面向数据报 6.UDP的缓冲区 7.UDP使用注意事项 8.基于UDP的应用层协议 总结 前言 在之前的文章中为大家介绍了关于网络协议栈第一层就是应用层&#xff0c;包含套接字的使用&#xff0c;在应用层编码实现服务…

nc前端合计行

nc前端合计行 1.无表体和单表体的合计行加法 只要卡片下 如果是只有表头要合计行就只留ShowTotalLine&#xff1b;如果是只有表体要合计行就只留ShowTotalLineTabcodes 2.多表体的合计行加法 表头卡片下和列表下都要 3.档案的合计行加法 重写一下列表模板

cin、cin.getline()、getline()的用法【C++】

一、cin>> 用法1&#xff1a;输入一个数字或字符 #include <iostream> using namespace std; int main () {int a,b;cin>>a>>b;cout<<ab<<endl;return 0; } 用法2&#xff1a;接收一个字符串&#xff0c;遇“空格”、“TAB”、“回车”…

select多选回显问题 (取巧~)

要实现的效果&#xff1a; 实际上select选择框&#xff0c;我想要的是数组对象&#xff0c;但是后端返回来的是个字符串。 以下是解决方法&#xff1a; 以上是一种简单的解决方法~ 也可以自己处理数据或者让后端直接改成想要的格式。

无涯教程-JavaScript - ISOWEEKNUM函数

描述 ISOWEEKNUM函数返回给定日期的年份的ISO周编号。 语法 ISOWEEKNUM (date)争论 Argument描述Required/OptionalDateDate is the date-time code used by Excel for date and time calculation.Required Notes Microsoft Excel将日期存储为连续数字,因此可以在计算中使…

【会议征稿】第五届土木工程、环境资源与能源材料国际学术会议(CCESEM 2023)

第五届土木工程、环境资源与能源材料国际学术会议&#xff08;CCESEM 2023&#xff09; 第五届土木工程、环境资源与能源材料国际学术会议&#xff08;CCESEM 2023&#xff09;&#xff0c;定于2023年10月27日至29日在厦门举行。会议主要围绕“土木工程”、“环境资源”、“能…

15种下载文件的方法文件下载方法汇总超大文件下载

15种下载文件的方法&文件下载方法汇总&超大文件下载 15种下载文件的方法Pentesters经常将文件上传到受感染的盒子以帮助进行权限提升&#xff0c;或者保持在计算机上的存在。本博客将介绍将文件从您的计算机移动到受感染系统的15种不同方法。对于那些在盒子上存在且需要…

Linux xargs命令继续学习

之前学习过Linux xargs&#xff0c;对此非常的不熟悉&#xff0c;下面继续学习一下&#xff1b; xargs 可以将管道或标准输入&#xff08;stdin&#xff09;数据转换成命令行参数&#xff0c;也能够从文件的输出中读取数据&#xff1b; xargs也可以给命令传递参数&#xff1b;…

redis核心数据结构

redis下载地址&#xff1a;Download | Redis linux进入redis目录首先使用make命令进行c的编译&#xff0c;修改redis.conf文件&#xff1a; daemonize yes #后台启动 protected-mode no #关闭保护模式&#xff0c;开启的 # 需要注释掉bind #bind 127.0.0.1&#xff08;bind…

【已解决】Java 后端使用数组流 Array.stream() 将数组格式的 Cookie 转换成字符串格式

&#x1f389;工作中遇到这样一个场景&#xff1a;远程调用某个接口&#xff0c;该接口需要用户的 Cookie 信息进行权限认证&#xff0c;认证通过之后才可以打通并返回数据。 在后端拿到 httpServletRequest 后&#xff0c;调用 getCookies() 方法&#xff0c;返回的是一个 Coo…

车规微控制器的ECC机制及EMU外设

车规微控制器的ECC机制及EMU外设 文章目录 车规微控制器的ECC机制及EMU外设引言ECC的基本原理ECC RAM的访问方式ECC RAM的初始化SRAM ECC错误注入及EMU外设Flash ECC校验参考文献 引言 ECC是微控制器系统中&#xff0c;用于保障信息安全的常用机制&#xff0c;主要是避免存储设…

无涯教程-JavaScript - DAYS360函数

描述 DAYS360函数返回基于360天的年份(十二个月为30天)的两个日期之间的天数,该天数用于会计计算。 语法 DAYS360 (start_date,end_date,[method])争论 Argument描述Required/OptionalStart_dateThe two dates between which you want to know the number of days.Required…

程序员自由创业周记#2:前期准备

感恩 上次公开了创业的决定后&#xff0c;得到了很多亲朋好友和陌生朋友的鼓励或支持&#xff0c;以不同的形式&#xff0c;感动之情溢于言表。这些都会记在心里&#xff0c;大恩不言谢~ 创业方向 笔者是一名资质平平的iOS开发程序猿&#xff0c;创业项目也就是开发App卖&am…