串的基本操作和KMP算法(优化版求nextval数组)模式匹配 数据结构完整C代码

数据结构 串的基本操作和KMP算法匹配 C语言版

串的创建,赋值,复制,判空,比较,求子串,串连接,输出,以及求nextval数组和用kmp算法进行匹配

C代码

#include<stdio.h>
#include<string.h>

typedef int Status;
#define Maxsize 255

typedef char String[Maxsize+1]; // 0号单元存放串的长度

Status Strassign(String T,char *chars);							//串赋值
Status Strcopy(String T,String S);								//串复制
Status StrEmpty(String T);										//判断串空
int StrCompare(String T,String S);								//判断串相等
int StrLength(String T);										//求串长
Status Substring(String Sub,String S,int pos,int len);			//求子串
Status Concat(String S,String S1,String S2);					//串连接								
void StrPrint(String T);										//输出串
void getnextval(String T,int nextval[]);                        //改良版求nextval值
int index_kmp(String S,String T,int nextval[]);					//用kmp算法求定位

Status Strassign(String T,char *chars)
{
	if(strlen(chars)>Maxsize){
     return 0;
	}
    else{
      T[0]=strlen(chars);
      for(int i=1;i<=T[0];i++){
         T[i]=*(chars+i-1);
	  }
    }
    return 1;
}

Status Strcopy(String T,String S)		 // 由串S复制得串T
 {
	 for(int i=1;i<=S[0];i++){
		T[i]=S[i];
		T[0]=S[0];
	 }
	 printf("复制成功!\n");
	  return 1;
 }

Status StrEmpty(String T)				// 若S为空串,则返回TRUE,否则返回FALSE
{ 
   if(T[0]==0)
     return 1;
   else
     return 0;
 }


Status StrCompare(String T,String S)// 操作结果: 若S>T,则返回值>0;若S=T,则返回值=0;若S<T,则返回值<0
 { 
	// 初始条件: 串S和T存在  
	for(int i=1;i<=S[0]&&i<=T[0];++i){
		if(S[i]!=T[i]){
			return T[i]-S[i];
		}
	}
   return T[0]-S[0];
 }

int StrLength(String T)// 返回串的元素个数
 { 
   return T[0];
 }

Status Substring(String Sub,String S,int pos,int len) // 用Sub返回串S的第pos个字符起长度为len的子串。
{
	if(pos<1||pos>S[0]||len<0||len>S[0]-pos+1){
		return 0;
	}
	for(int i=1;i<=len;i++){
		Sub[i]=S[pos+i-1];
		Sub[0]=len;
	}
	return 1;
}

Status Concat(String S,String S1,String S2)
{
	if(S1[0]+S2[0]>Maxsize){
		printf("存储空间满了!");
		return 0;
	}
	else{
		for(int i=1;i<=S1[0];i++){
         S[i]=S1[i];
		}
		for(int j=1;j<=S2[0];j++){
		 S[S1[0]+j]=S2[j];
    	 S[0]=S1[0]+S2[0];
		}
	}
     return 1;
}

void getnextval(String T,int nextval[])   
{
	int i=1 ,j=0;
	nextval[1]=0;
	while(i<T[0]){
		if(j==0 || T[i]==T[j]){  // 继续比较后继字符
			++i;
			++j;
			if(T[i]!=T[j]){      
				nextval[i]=j;    //j赋值给nextval[i]
			}
			else{
				nextval[i]=nextval[j];
			}
		}
		else{
			j=nextval[j];        //如果不相等,将j回溯到nextval[j]位置		
		}
	}
}

int index_kmp(String S,String T,int nextval[])
{
	int i=1,j=1;
	while(i<=S[0] && j<=T[0]){
		if(j==0 || S[i]==T[j]){  // 继续比较后继字符
			++i;
			++j;
		}
		else{                   // 模式串向右移动
			j=nextval[j];
		}
	}
	if(j>T[0]){                // 匹配成功
		return i-T[0];         //返回匹配点
	}
    else{
		return 0;
	}
}

void StrPrint(String T)
{
	for(int i=1;i<=T[0];i++){
		printf("%c",T[i]);
	}
	printf("\n");
}




int main()
{
	int i,j,a,L;
	int nextval[255];
	char s;
	String T,S,s1,s2,sub,X,X1;
	printf("\n\n\n");
	printf("\n\t\t\t\t\t\t1.创建串T");
	printf("\n\t\t\t\t\t\t2.复制串T到s1");
	printf("\n\t\t\t\t\t\t3.判断串T与s2");
	printf("\n\t\t\t\t\t\t4.求T的子串sub");
	printf("\n\t\t\t\t\t\t5.连接s1和s2到S");
	printf("\n\t\t\t\t\t\t6.kmp匹配");
	printf("\n\t\t\t\t\t\t7.退出\n\n");
	while(1)
	{
		printf("\n请选择您想选择的操作:  ");
		int k;
		scanf("%d",&k);
		switch(k)
			{	
				case 1: 
				    Strassign(T,"chuan");
				    printf("串T为: ");
				    StrPrint(T);
					printf("长度为: %d \n",StrLength(T));
					break;
				case 2:
					Strcopy(s1,T);
					printf("串s1为: ");
				    StrPrint(s1);
					printf("长度为: %d \n",StrLength(s1));
					break;
				case 3:
					Strassign(s2,"chuang");
				    printf("串s2为: ");
				    StrPrint(s2);
					printf("长度为: %d \n",StrLength(s2));
					i=StrCompare(T,s2);
					if(i>0)
						s='>';
					else if(i==0)
						s='=';
					else
						s='<';
					printf("串T %c 串s2\n",s);
					break;
				case 4:
					printf("求串T的子串,请输入起始位置: ");
					scanf("%d", &i);
					printf("请输入子串的长度: ");
					scanf("%d", &j);
					Substring(sub,T,i,j);
				    printf("串sub为: ");
				    StrPrint(sub);
					printf("长度为: %d \n",StrLength(sub));
					break;
				case 5:
					Concat(S,s1,s2);
					printf("串S为: ");
				    StrPrint(S);
					printf("长度为: %d \n",StrLength(S));
					break;
				case 6: 
					Strassign(X,"you");
					Strassign(X1,"Fall in love with you, I will be out of the woods");
					printf("主串X1为: ");
				    StrPrint(X1);
					printf("子串X为: ");
				    StrPrint(X);
					getnextval(X,nextval);
					a=index_kmp(X1,X,nextval);
					if(a)
						printf("主串和子串在第%d个字符处首次匹配\n",a);
					else
						printf("主串和子串匹配不成功\n");
					break;
				case 7:
					return 0;
			}
	}
}



代码运行图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值