字符串匹配
题目
有一个主串S = {a, b, c, a, c, a, b, d, c}, 模式串T = { a, b, d } ; 请找到模
式串在主串中第一次出现的位置;
提示: 不需要考虑字符串大小写问题, 字符均为小写字母;
a.思路(BF算法)
1. 分别利用计数指针i和j指示主串S和模式T中当前正待比较的字符位置,i初值为pos,j的初值为1
2. 如果2个串均为比较到串尾,即i和j均小于等于S和T的长度时, 则循环执行以下的操作:
* S[i]和T[j]比较,若相等,则i 和 j分别指示串中下一个位置,继续比较后续的字符
* 若不相等,指针后退重新开始匹配. 从主串的下一个字符串(i = i - j + 2)起再重新和模式第一个字符(j = 1)比较
3. 如果j > T.length, 说明模式T中的每个字符串依次和主串S找中的一个连续字符序列相等,则匹配成功,返回和模式T中第一个字符的字符在主串S中的序号(i-T.length)
a.代码实现
#include "string.h"
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#include "time.h"
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 40
typedef int Status;
typedef int ElemType;
typedef char String[MAXSIZE+1];
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;
}
void StrPrint(String T)
{
int i;
for(i=1;i<=T[0];i++)
printf("%c",T[i]);
printf("\n");
}
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];
}
int Index_BF(String S, String T,int pos){
int i = pos;
int j = 1;
while (i <= S[0] && j <= T[0]) {
if (S[i] == T[j]) {
i++;
j++;
}else
{
i = i-j+2;
j = 1;
}}
if (j > T[0]) {
return i - T[0];
}else{
return -1;
}
}
int main(int argc, const char * argv[]) {
printf("字符串模式匹配!\n");
int i,*p;
String s1,s2;
StrAssign(s1, "abcdex");
printf("s1子串为");
StrPrint(s1);
StrAssign(s2, "xe");
printf("s2子串为");
StrPrint(s2);
i = Index_BF(s1, s2, 1);
printf("i = %d\n",i);
return 0;
}
b.思路(RK算法)
1、将主串拆分成若干个子串,并计算出子串的哈希值与模式串的哈希值
2、将子串的哈希值与模式串的哈希值进行比较
3、解决哈希冲突问题
b.代码实现
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define d 26
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;
}
int getMaxValue(int m){
int h = 1;
for(int i = 0;i < m - 1;i++){
h = (h*d);
}
return h;
}
int RK(char *S, char *P)
{
int m = (int) strlen(P);
int n = (int) strlen(S);
printf("主串长度为:%d,子串长度为:%d\n",n,m);
unsigned int A = 0;
unsigned int St = 0;
for(int i = 0; i != m; i++){
A = (d*A + (P[i] - 'a'));
St = (d*St + (S[i] - 'a'));
}
int hValue = getMaxValue(m);
for(int i = 0; i <= n-m; i++){
if(A == St)
if(isMatch(S,i,P,m))
return i+1;
St = ((St - hValue*(S[i]-'a'))*d + (S[i+m]-'a'));
}
return -1;
}
int main()
{
char *buf="abcababcabx";
char *ptrn="abcabx";
printf("主串为%s\n",buf);
printf("子串为%s\n",ptrn);
int index = RK(buf, ptrn);
printf("find index : %d\n",index);
return 1;
}