首页 > 其他分享 >数据结构---字符串

数据结构---字符串

时间:2023-09-28 22:46:15浏览次数:32  
标签:int len next --- prefix 字符串 plen 数据结构 ptr

数据结构---字符串

串的定义

串是由零个或多个字符顺序排列组成的有限序列

空串

长度为零的串

空白串

由一个或多个空格组成的串

字符串匹配问题

朴素模式匹配

模式匹配的查找过程 (Find):

给定两个字符串变量S和P,其中目标S有n个字符,模式P有m个字符,m<=n。从S的给定位置(通常为S的第一个字符)开始,搜索模式P,如果找到,返回模式P的第一个字符在S中的位置;如果没找到(即S中没有P),则返回-1 。

以下为 StringMatching( S, P ) 的 C++ 代码, S为目标串, P为模式串, 返回S中首个P子串的位置

int StringMatching(string S, string P)
{
	unsigned int i = 0;
	while(i <= S.size() - P.size())
	{
		unsigned int j = 0;
        //字符匹配成功 && j没有越界
		while(S[i] == P[j] && j < P.size())
		{
			i = i + 1;
			j = j + 1;
		}
		if(j == P.size())
		{
            //返回坐标
			return i - j;	
		} 
        //坐标后移
		i = i - j + 1;
	}
	return -1;
}

朴素模式匹配算法时间复杂度

最好:m 最坏: m(n-m+1) = O(nm)

平均时间复杂度: O(n*m)

KMP算法

时间复杂度: O(m+n)

KMP算法充分利用了目标字符串ptr的性质(比如里面部分字符串的重复性,即使不存在重复字段,在比较时,实现最大的移动量).

计算长度为m的next数组

next数组的含义就是存放一个固定字符串的最长前缀和最长后缀相等的长度

下面是求解next数组的 C++ 代码:

int* cal_next(char* ptr, int plen)
{
	int* next = new int[plen];
    next[0] = -1;
    int prefix_len = -1;
    int i = 1;
    while(i < plen)
    {
        if(ptr[i] == ptr[prefix_len + 1])
        {
            prefix_len = prefix_len + 1;
            next[i] = prefix_len;
            i = i + 1;
        }
        else
        {
            if(prefix_len > -1)
            {
                prefix_len = next[prefix_len];
            }
            else
            {
                next[i] = -1;
                i = i + 1;
            }
        }
    }
	return next;
}

//或者下面的也可以求next数组,原理一样, 就是不一样的代码而已
int* cal_next(char* ptr, int plen)
{
    int* next = new int[plen];
    next[0] = -1;
    int k = -1;
	for(int i = 1; i < plen; i++)
    {
        while(k > -1 && ptr[k+1] != ptr[i])
        {
            k = next[k];
        }
        if(ptr[k+1] == ptr[i])
        {
            k = k + 1;
        }
        next[i] = k;
    }
   	return next;
}

下面是KMP的 C++ 实现代码, 同样给出两种形式的代码:

int KMP(char* str, char* ptr, int slen, int plen)
{
    int* next = cal_next(ptr, plen);
    int j = -1;
    int i = 0;
    while(i < slen)
    {
  		if(ptr[j+1] == str[i])
        {
            i = i + 1;
            j = j + 1;
        }
        else
        {
            if(j > -1)
            {
                j = next[j];
            }
            else
            {
                i = i + 1;
            }
        }
        if(j == plen - 1)
        {
            return i-j;
        }
    }
    return -1;
}


int KMP(char* str, char* ptr, int slen, int plen)
{
	int* next = cal_next(ptr, plen);
    int j = -1;
    for(int i = 0; i < slen; i++)
    {
        while(j > -1 && ptr[j+1] != str[i])
        {
            j = next[j];
        }
        if(ptr[j+1] == str[i])
        {
            j = j + 1;
        }
        if(j == plen - 1)
        {
            return i-j;
        }
    }
   	return -1;
}

标签:int,len,next,---,prefix,字符串,plen,数据结构,ptr
From: https://www.cnblogs.com/Dorcnf/p/17736611.html

相关文章

  • 洛谷 P7075 [CSP-S2020] 儒略日
    P7075[CSP-S2020]儒略日1.题目描述为了简便计算,天文学家们使用儒略日(Julianday)来表达时间。所谓儒略日,其定义为从公元前4713年1月1日正午12点到此后某一时刻间所经过的天数,不满一天者用小数表达。若利用这一天文学历法,则每一个时刻都将被均匀的映射到数轴上,从而得以......
  • npm install 报-4048错误
    报错原因:有缓存权限不够 有三种解决方法:第一种:找到.npmrc文件并删除在C:\Users\自己用户的文件夹\下找到.npmrc文件并删除注意:这个文件是隐藏的,需要显示隐藏才能看见第二种方法:直接用命令清理在控制台上输出 npmcacheclean--force 一样可以删除第三种方法:......
  • 字符串排序算法+快速排序
    #include<stdio.h>#include<stdlib.h>#include<memory>#include<vector>#include<string>usingnamespacestd;voidswap(int*a,int*b){inttemp=*a;*a=*b;*b=temp;}voidquicksort(int*arr,intsta......
  • [LeetCode] 2251. 花期内花的数目 - 二分查找/有序数组
    Problem:2251.花期内花的数目思路看题目应该是一道比较经典的差分,本来准备拿差分数组做的,后来搂了一眼题解,发现用二分的方法更简单解题方法此题有一种很简便的方法,第i个人到达时间为people[i],所以我们不难找到在这个时间之前花期已经开始的花的数量,即v1=start<=people[i]......
  • python中实现按照固定位数拆分字符串
     001、[root@pc1test2]#lstest.py[root@pc1test2]#cattest.py##测试程序#!/usr/bin/envpython3#-*-coding:utf-8-*-importrestr1="abcdefghijklmn"print(str1)list1=re.findall(".{3}",str1)##按照每3位生成列表print(&qu......
  • CSP-J/S 2023 游记
    \(9.16\)初赛。\(9:00\)就到了振万教学楼,休息了一下,准备去\(5\)楼考场。\(9:05\)到了考场门口,发现教室里面已经开了空调,但xxs们都不进去,6。于是我第一个进了考场。\(9:30\)总算看到试题卷了,好像除了第\(4,10\)题都很简单。\(10:20\)做完了卷子,开始检查。\(11:30\)......
  • Aveva Marine VBNET 编程系列-修改程序快捷键
    修改HullDesign程序的主题以及菜单项的快捷键 引用的dll文件下面的是代码和快捷键配置文件:https://files.cnblogs.com/files/NanShengBlogs/AMShortCut.HullDesign.zip?t=1695908179&download=trueImportsAveva.ApplicationFramework.PresentationImportsAveva.Applic......
  • Python 中的字符串基础与应用
    在Python中,字符串可以用单引号或双引号括起来。'hello'与"hello"是相同的。您可以使用print()函数显示字符串文字:示例:print("Hello")print('Hello')将字符串分配给变量是通过变量名后跟等号和字符串完成的:示例a="Hello"print(a)多行字符串您可以使用三个引号将多......
  • CSS 基础 4 - CSS 常用单位
    CSS基础4-CSS常用单位px:基础单位em:相对当前父容器的系数,可以累乘rem:相对根<html>的系数,方便计算vw/vh:viewportwidth/height,整个浏览器的大小,取值范围1-100如100vh,占满高度,如果出现滚动条,是因为body预设的padding和margin如30%宽度的侧边栏:height:100vh;......
  • 【AntDesign】封装全局异常处理-全局拦截器
    场景本文前端用的是阿里的Ant-Design框架,其他框架也有全局拦截器,思路是相同,具体实现自行百度下吧因为每次都需要调接口,都需要单独处理异常情况(code!=0),因此前端需要对后端返回的通用响应进行统一处理,比如业务异常提示从response取出code,根据code中集中处理错误,比如提示用......