纯C语言基于堆式串实现KMP算法

       终于看懂KMP算法了!

       头文件HString.h:

/*HString.h*/

#ifndef HSTRING_H_INCLUDED
#define HSTRING_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#define DefaultSize 30

typedef struct
{
	char *ch;						/*顺序串的存储数组*/
	int maxSize;					/*字符串存储数组的最大长度*/
	int n;							/*顺序串的实际长度*/
} HString;





#endif  /*HSTRING_H_INCLUDED*/

       头文件KMP.h:

/*KMP.h*/

#ifndef KMP_H_INCLUDED
#define KMP_H_INCLUDED
#include "HString.h"

void GetNext ( HString *P, int next[] );
int FastFind ( HString *T, HString *P, int next[ ] );

#endif /* KMP_H_INCLUDED*/

    源文件HString.c: 

/*HString.c*/

#include "HString.h"

HString *initStr ( HString *s )/*串初始化*/
{
	s->ch = ( char *) malloc ( ( DefaultSize+1 )*sizeof ( char ) );	/*动态分配*/
	s->ch[0] = '\0';
	s->maxSize = DefaultSize;
	s->n = 0;			/*串s的最大容量和当前长度*/
	return s;
}

void createStr ( HString *s, char *init )/*从字符数组init构造串s*/
{
	s->maxSize = DefaultSize;
	s->ch = ( char *) malloc (( DefaultSize+1 )*sizeof ( char ));
	s->n = strlen ( init );
	strcpy ( s->ch, init );
}

void copyStr ( HString *s, HString *t )/*把串t复制给串s*/
{
	s->maxSize = DefaultSize;
	s->ch = ( char *) malloc ( ( DefaultSize+1 )*sizeof ( char ) );
	s->n = t->n;
	strcpy ( s->ch, t->ch );
}


HString *subStr ( HString *s, int pos, int len )/*在串s中连续取从pos开始的len个字符,
构成子串返回。若提取失败则函数返回NULL*/
{

	HString *tmp = ( HString * )malloc( sizeof(HString) );
	tmp->ch = ( char *) malloc ( ( DefaultSize+1 )*sizeof ( char ) );
	tmp->maxSize = DefaultSize;
	if ( pos < 0 || len < 0 || pos+len-1 >= s->maxSize )		/*参数不合理,返回空串*/
    {
        tmp->n = 0;
        tmp->ch[0] = '\0';
    }
	else
    {
		if ( pos+len-1 >= s->n )
            len = s->n-pos;			/*若提取个数超出串尾,修改个数*/
		for ( int i = 0, j = pos; i < len; i++, j++)
            tmp->ch[i] = s->ch[j];
	   	tmp->n = len;
        tmp->ch[len] = '\0';
	}
	return tmp;
}

void concat ( HString *s, HString *t )
{
/*将串t复制到串s后,串t不变。若完全连接成功,函数返回true;若部分连接成功,或
连接不成功,函数返回false*/
	if ( s->n+t->n <= s->maxSize )/*原空间可容纳连接后的串*/
    {
		for ( int i = 0; i < t->n; i++ )
            s->ch[s->n+i] = t->ch[i];
		s->n = s->n+t->n;
        s->ch[s->n] = '\0';
	}
	else
    {										/*原空间容不下连接后的串*/
		char *tmp = s->ch;
        s->maxSize = s->n+t->n;			/*暂存原串数组,算新串数组大小*/
		s->ch = ( char* ) malloc ( ( s->maxSize+1 )*sizeof ( char ) );
	   	strcpy ( s->ch, tmp );
	   	strcat ( s->ch, t->ch );			/*复制原串s数组, 连接串t数组*/
		s->n = s->n+t->n;
		free ( tmp );
	}
}

char getChar ( HString *s, int i )/*提取串s的第i个字符*/
{
	if ( i < 0 || i >= s->n )
    {
        printf ( "字符串下标超界!\n" );
        return '\0';
    }
	return s->ch[i];
}

void printStr ( HString *s )
{
	printf ("打印串长度s->n=%d, 最大长度=%d\n", s->n, s->maxSize);
	for ( int i = 0; i < s->n; i++ )
		if ( s->ch[i] == '\0' )
            break;
		else
            printf ( "%c", s->ch[i] );
	printf("\n");
}

       源文件KMP.c:

/*KMP.c*/

#include "KMP.h"

void GetNext ( HString *P, int next[] )
{
/*对模式串P, 计算next失配函数*/
	int j = 0, k = -1;
	next[0] = -1;
	while ( j < P->n )/*计算next[j]*/
    {
		while ( k >= 0 && P->ch[j] != P->ch[k] )
            k = next[k];
		j++;
        k++;
		if ( P->ch[j] == P->ch[k] )
            next[j] = next[k];
		else
			next[j] = k;
	}
}

int FastFind ( HString *T, HString *P, int next[ ] )
{
/*在目标串T中寻找模式串P的匹配位置。若找到,则函数返回P在T中开始字符
下标,否则函数返回-1。数组nex存放P的失配函数next[j]值。*/
	int j = 0, i = 0;				/*串P与串T的扫描指针*/
	while ( j < P->n && i < T->n )      /*对两串扫描*/
    {
		printf ( "i=%d, j=%d\n", i, j );
 		if ( j == -1 || P->ch[j] == T->ch[i] )
 		{
 		    j++;  /*对应字符匹配,比对位置加一*/
            i++;
        }
 		else
            j = next[j];								/*第j位失配,找下一对齐位置*/
	}
	if ( j < P->n )
        return -1;							/*j未比完失配,匹配失败*/
	else
        return i-P->n;								/*匹配成功*/
}

       源文件test.c:

/*test.c*/

/*
	Name:  纯C语言基于堆式串实现KMP算法
	Copyright:  2018
	Author:  刁肥宅
	Contact Author:  2046195761(QQ)、[email protected](Email)
	Date:  10/08/18 17:52
	Description:  呜啦啦!唯爱小桃子~
*/


#include "KMP.h"

int main()
{
    char A[] = {'H','e','f','e','i','U','n','i','v','e','r','s','i',
	't','y','O','f','T','e','c','h','n','o','l','o','g','y','\0'};
    char B[] = {'U','n','i','v','e','r','s','i','t','y','\0'};
    HString *S1 = ( HString * )malloc( sizeof(HString) ),*S2 = ( HString * )malloc( sizeof( HString ) );
    int Fail[DefaultSize];
    int i,d;
    for( i = 0;i < DefaultSize;i ++ )
        Fail[i] = 0;

    printf("Name:  纯C语言基于堆式串实现KMP算法\n");
    printf("Copyright:  2018\nAuthor:  刁肥宅\n");
    printf("Contact Author:  2046195761(QQ)、[email protected](Email)\n");
    printf("Date:  10/08/18 17:52\nDescription:  呜啦啦!唯爱小桃子~\n\n");

    createStr( S1,A );
    printStr( S1 );

    createStr( S2,B );
    printStr( S2 );

    GetNext ( S2, Fail );
	for ( i = 0; i < S2->n; i++ )
		printf ( "%d ", Fail[i] );
	printf("\n");

	d = FastFind ( S1, S2, Fail );

    if( d == -1 )
        printf("匹配位置失败!\n");
    else
        printf("匹配位置为%d\n",d);
    Sleep(1000 * 60);
    return 0;
}

       晒一晒我美腻的小桃子:

图1  明眸皓齿、端丽冠绝的小桃子

       程序运行截图如下:

图2  刁肥宅手笔:KMP算法C程序运行截图

猜你喜欢

转载自blog.csdn.net/u25th_engineer/article/details/81567751
今日推荐