数据结构 串的基本操作和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;
}
}
}