数据结构-串(KMP算法)

串的定义

串(string)就是由零个或多个字符串组成的有限序列,又叫字符串。

串的比较

字符串的比较是通过组成字符串的字符之间的编码来进行的,编码即字符在对应字符集中的序号。
常用的有ASCLL编码、Unicode编码。
比较两个串的大小:先比较各字符大小然后比串长度。

串的储存结构

串同样有顺序储存结构和链式储存结构。

朴素的匹配模式

在文本串中查找模式串,朴素的匹配模式就是逐个遍历字符串,时间复杂度O(m*n)。

//在文本串S中查找模式串T
int strStr(String S, String T)//注意,c语言是没有String数据类型的
{
   
	int i = 0;
	int j = 0;
	while(i < sLength && j < tLength)
	{
   
		if(S[i] == T[j])
		{
   
			++i;
			++j;
		}
		else
		{
   
			i = i - j + 1;
			j = 1;
		}
	}
	if()
		return i - tLength;
	else
		return 0;
}

KMP模式匹配算法

用于解决字符串匹配问题。在遇到不相同的字符时,通过使用前缀表(即最长相等前后缀)来回退到下一次遍历开始的位置,无需每次遍历均从头开始。
(前缀是包含首字母但是不包含尾字母的所有字串;后缀相反)
KMP算法可以将时间复杂度由O(n*m)降到O(n + m)。

KMP算法实现

通常使用next数组存放前缀表,next数组可以就是前缀表,但是很多实现都是把前缀表统一减一(或右移一位,初始位置为-1)之后作为next数组。实际上,其实这并不涉及到KMP的原理,而是其具体实现的不同。
计算next数组:(直接存放前缀表)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
KMP算法是一种字符匹配算法,可以在一个主中查找一个模式是否出现。这里提供一个用C语言实现的KMP算法。 首先,需要定义一个函数`get_next`,用于计算模式的next数组。next数组是一个长度为模式长度的整型数组,表示当匹配失败时,模式应该向右移动的位数。 ```c void get_next(char* pattern, int* next) { int i = 0, j = -1; next[0] = -1; while (i < strlen(pattern)) { if (j == -1 || pattern[i] == pattern[j]) { i++; j++; next[i] = j; } else { j = next[j]; } } } ``` 接下来,定义一个函数`kmp`,用于在主中查找模式。函数的参数包括主指针、主长度、模式指针、模式长度和next数组。 ```c int kmp(char* text, int text_len, char* pattern, int pattern_len, int* next) { int i = 0, j = 0; while (i < text_len && j < pattern_len) { if (j == -1 || text[i] == pattern[j]) { i++; j++; } else { j = next[j]; } } if (j == pattern_len) { return i - j; } else { return -1; } } ``` 下面是一个完整的示例代码: ```c #include <stdio.h> #include <string.h> void get_next(char* pattern, int* next) { int i = 0, j = -1; next[0] = -1; while (i < strlen(pattern)) { if (j == -1 || pattern[i] == pattern[j]) { i++; j++; next[i] = j; } else { j = next[j]; } } } int kmp(char* text, int text_len, char* pattern, int pattern_len, int* next) { int i = 0, j = 0; while (i < text_len && j < pattern_len) { if (j == -1 || text[i] == pattern[j]) { i++; j++; } else { j = next[j]; } } if (j == pattern_len) { return i - j; } else { return -1; } } int main() { char text[] = "ABABABABCABAAB"; char pattern[] = "ABABCABAA"; int text_len = strlen(text); int pattern_len = strlen(pattern); int next[pattern_len]; get_next(pattern, next); int pos = kmp(text, text_len, pattern, pattern_len, next); if (pos == -1) { printf("Pattern not found.\n"); } else { printf("Pattern found at position %d.\n", pos); } return 0; } ``` 输出结果为: ``` Pattern found at position 6. ``` 表示在主中找到了模式,并且位置为6。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值