第五次作业 串的模式匹配

| 这个作业属于哪个课程 |https://edu.cnblogs.com/campus/qdu/DS2020 |
| ---- | ---- | ---- |
| 这个作业要求在哪里 |https://edu.cnblogs.com/campus/qdu/DS2020/homework/11392 |
| 这个作业的目标 | 掌握串的模式匹配算法 |
| 学号 | 2018204186 |
一、实验目的
1、了解串的基本概念
2、掌握串的模式匹配算法的实现
二、实验预习
说明以下概念
1、模式匹配:模式匹配是数据结构中字符串的一种基本运算,给定一个子串,要求在某个字符串中找出与该子串相同的所有子串,这就是模式匹配。
2、BF算法:暴力匹配(BF)算法是普通的模式匹配算法,BF算法的思想就是将目标串S的第一个字符与模式串T的第一个字符进行匹配,若相等,则继续比较S的第二个字符和T的第二个字符;若不相等,则比较S的第二个字符和T的第一个字符,依次比较,直到得出最后的匹配结果。
3、KMP算法:KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,因此人们称它为克努特—莫里斯—普拉特操作(简称KMP算法)。KMP算法的核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是通过一个next()函数实现,函数本身包含了模式串的局部匹配信息。
三、实验内容和要求
1、阅读并运行下面程序,根据输入写出运行结果。

#include<stdio.h>
#include<string.h>
#define MAXSIZE 100
typedef struct{
    char data[MAXSIZE];
    int length;
}SqString;

int strCompare(SqString *s1,SqString *s2); /*串的比较*/
void show_strCompare();
void strSub(SqString *s,int start,int sublen,SqString *sub); 
/*求子串*/
void show_subString();

int strCompare(SqString *s1,SqString *s2){
    int i;
    for(i=0;i<s1->length&&i<s2->length;i++)
        if(s1->data[i]!=s2->data[i])
            return s1->data[i]-s2->data[i];
    return s1->length-s2->length;
}
void show_strCompare(){
    SqString s1,s2;
    int k;
    printf("\n***show Compare***\n");
    printf("input string s1:");
    gets(s1.data);
    s1.length=strlen(s1.data);
    printf("input string s2:");
    gets(s2.data);
    s2.length=strlen(s2.data);
    if((k=strCompare(&s1,&s2))==0)
        printf("s1=s2\n");
    else if(k<0)
        printf("s1<s2\n");
    else
        printf("s1>s2\n");
    printf("\n***show over***\n");
}

void strSub(SqString *s,int start,int sublen,SqString *sub){
    int i;
    if(start<1||start>s->length||sublen>s->length-start+1){
        sub->length=0;
    }
    for(i=0;i<sublen;i++)
        sub->data[i]=s->data[start+i-1];
    sub->length=sublen;
}
void show_subString(){
    SqString s,sub;
    int start,sublen,i;
    printf("\n***show subString***\n");
    printf("input string s:");
    gets(s.data);
    s.length=strlen(s.data);
    printf("input start:");
    scanf("%d",&start);
    printf("input sublen:");
    scanf("%d",&sublen);
    strSub(&s,start,sublen,&sub);
    if(sub.length==0)
        printf("ERROR!\n");
    else{
        printf("subString is :");
        for(i=0;i<sublen;i++)
            printf("%c",sub.data[i]);
    }
    printf("\n***show over***\n");
}

int main(){
    int n;
    do {
        printf("\n---String---\n");
        printf("1. strCompare\n");
        printf("2. subString\n");
        printf("0. EXIT\n");
        printf("\ninput choice:");
        scanf("%d",&n);
        getchar();
        switch(n){
            case 1:show_strCompare();break;
            case 2:show_subString();break;
            default:n=0;break;
        }
    }while(n);
    return 0;
}

运行程序
运行结果:

2、实现串的模式匹配算法。补充下面程序,实现串的BF和KMP算法。
kmp算法


int indexKMP(SString S, SString T, int pos, int next[]){
	int i = pos, j = 1;
	while(i <= S[0] && j <= T[0]){
		if(j == 0 || S[i] == T[j]){
			i++;  
			j++;
		}else{
			j = next[j];
		}
	}
	if(j > T[0]){
		return i - T[0];
	}else
		return 0;
}


 

void getNextVal(SString T, int next[]){
	next[1] = 0;
	int i = 1, j = 0;
	while(i < T[0]){
		if(j == 0 || T[i] == T[j]){
			i++;  
			j++;
			if(T[i] == T[j])
				next[i] = next[j];
			else
				next[i] = j;
		}else{
			j = next[j];
		}
	}	
}
void init(SString &S, char str[]){
	int i = 0;
	while(str[i]!='\0'){
		S[i+1] = str[i];
		i++;
	}
	S[i+1] = '\0';
	S[0] = i;
}
 
void printStr(SString Str){
	for(int i = 1; i <= Str[0]; i++){
		printf("%c", Str[i]);
	}
	printf("\n");
}

int main(){
	SString S ;
	init(S, "abcaabbabcabaacbacba");
	printStr(S);
 
	SString T;
	init(T, "abcabaa");
	printStr(T);
 

 
	int next[6] = {0};
	getNextVal(T, next);
	
	printf("next[]:");
	for(int k = 1; k <= T[0]; k++)
		printf("%d ", next[k]);
	printf("\n");
 
	int index = indexKMP(S, T, 1, next);
	printf("index is %d\n", index);
}

运行结果:
abcaabbabcabaacbacba
abcabaa
next[]:0 1 1 0 1 3 7
index is 8
bf算法:

#include<stdio.h>

#define MAXSTRLEN 50  
typedef unsigned char SString[MAXSTRLEN + 1];
 

int indexBF(SString S, SString T, int pos){
	int i = pos, 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 0;
}
 
void init(SString &S, char str[]){
	int i = 0;
	while(str[i]!='\0'){
		S[i+1] = str[i];
		i++;
	}
	S[i+1] = '\0';
	S[0] = i;
}
 
void printStr(SString Str){
	for(int i = 1; i <= Str[0]; i++){
		printf("%c", Str[i]);
	}
	printf("\n");
}
int main(){
	SString S ;
	init(S, "abcaabbabcabaacbacba");
	printStr(S);
 
	SString T;
	init(T, "abcabaa");
	printStr(T);
 
	int index = indexBF(S, T, 1);
	printf("index is %d\n", index);
}

运行结果:
abcaabbabcabaacbacba
abcabaa
index is 8

posted @ 2020-11-01 15:51  懵柠未迟  阅读(234)  评论(0)    收藏  举报