一:串的基本概念
#include
#include
#include
#include
#include
#define MAX 100
typedef struct string
{
char *ch;
int length;
}Hstring,*Pstring;
int StAssign(Pstring T,char *chars);
int StrLength(Pstring T);
int StringCompare(Pstring T1,Pstring T2);
void StringClear(Pstring T);
Pstring StringConnect(Pstring T1,Pstring T2);
Pstring StringSon(Pstring T,int pos,int len);
void Print(Pstring T);
int KMP(Pstring T,char*S,int*next,int pos);
void GetNext(char*S,int*next);
int main()
{
int next[MAX];
int a,ret,pos,len;
char S[MAX],S1[MAX],S2[MAX],S4[MAX];
Pstring T,T1,T2,T3,T4;
T=(Pstring)malloc(sizeof(Hstring));
T1=(Pstring)malloc(sizeof(Hstring));
T2=(Pstring)malloc(sizeof(Hstring));
T3=(Pstring)malloc(sizeof(Hstring));
T4=(Pstring)malloc(sizeof(Hstring));
while(1)
{
printf("Please choose the choice you want:\n");
printf("1.Establish String \n2.String Length \n3.String Compare \n");
printf("4.String Clear \n5.String Connect \n6.String's Son \n");
printf("7.KMP\n");
scanf("%d",&a);
getchar();
switch(a)
{
case 1:
gets(S);
ret=StAssign(T,S);
if(ret==1)
{
printf("Success!\n");
}
break;
case 2:
ret=StrLength(T);
printf("The string's length is: %d\n",ret);
break;
case 3:
printf("Please input the string 1: ");
gets(S1);
StAssign(T1,S1);
printf("Please input the string 2: ");
gets(S2);
StAssign(T2,S2);
ret=StringCompare(T1,T2);
if(ret>0)
{
printf("The T1 is bigger than T2.\n");
}
else if(ret<0)
{
printf("The T2 is bigger than T1.\n");
}
else
{
printf("The two string is equal.\n");
}
StringClear(T1);
StringClear(T2);
break;
case 4:
StringClear(T);
break;
case 5:
printf("Please input the string 1: ");
gets(S1);
StAssign(T1,S1);
printf("Please input the string 2: ");
gets(S2);
StAssign(T2,S2);
T3=StringConnect(T1,T2);
Print(T1);
Print(T2);
Print(T3);
StringClear(T1);
StringClear(T2);
StringClear(T3);
break;
case 6:
printf("please input the position and the length: ");
scanf(" %d %d",&pos,&len);
T4=StringSon(T,pos,len);
if(T4->length!=0)
{
Print(T4);
StringClear(T4);
}
break;
case 7:
printf("Please input the son string want to search: ");
gets(S4);
printf("Please input the position you want to search: ");
scanf(" %d",&pos);
GetNext(S4,next);
ret=KMP(T,S4,next,pos);
if(ret!=-1)
{
printf("the position is %d",ret);
}
else
{
printf("The position is not existence.\n");
}
free(S4);
break;
default:
exit(0);
}
}
}
int StAssign(Pstring T,char *chars)//创建串
{
char*p=chars;
int i,j;
for(i=0;*p;++p,++i);//计算串有多长
if(i==0)
{
T->length=i;//当串为空时
}
else//当串不为空时
{
T->length=i;
T->ch=(char*)malloc(i*sizeof(char));
}
assert(T->ch);
for(j=0;j<T->length;j++)
{
T->ch[j]=chars[j];
}
return 1;
}
int StrLength(Pstring T)//返回串长度
{
return T->length;
}
int StringCompare(Pstring T1,Pstring T2)//串的比较,T1>T2,返回值大于0
{
int i;
for(i=0;i<T1->length&&i<T2->length;i++)
{
if(T1->ch[i]!=T2->ch[i])//出现字符不同的情况
return T1->ch[i]-T2->ch[i];
}
return T1->length-T2->length;//出现字符相同的情况
}
void StringClear(Pstring T)//清除串的内存
{
if(T->ch)
{
free(T->ch);
}
T->length=0;
}
Pstring StringConnect(Pstring T1,Pstring T2)//将T2连接到T1后面
{
Pstring T;
int i=0,j=0,k;
T->ch=(char*)malloc((T1->length+T2->length)*sizeof(char));
while(T1->ch[i])//存入T1
{
T->ch[i]=T1->ch[i];
i++;
k=i;
}
while(T2->ch[j])//存入T2
{
T->ch[k]=T->ch[j];
j++;
k=i+j;
}
T->length=k;
return T;
}
Pstring StringSon(Pstring T,int pos,int len)//从第pos位置开始复制长度为len子串
{
Pstring T1;
T1=(Pstring)malloc(sizeof(Hstring));
int i,j;
T1->length=0;
if(pos<1||pos>(T->length-len)||len<0)//合法判断
{
printf("Wrong!!!\n");
return T1;
}
else
{
for(i=pos-1,j=0;i<pos+len-1;i++,j++)//复制子串
{
T1->ch[j]=T->ch[i];
}
T1->length=len;
return T1;
}
}
void Print(Pstring T)//打印串
{
int i;
printf("The string is: ");
for(i=0;i<T->length;i++)
{
printf("%c",T->ch[i]);
}
printf("\n");
}
void GetNext(char*S,int*next)//求next的值
{
int i=0,j=-1;//初始化
next[0]=-1;//直接使next【0】=-1,便于后面操作
while(i<strlen(S))//当i小于串长时
{
if(j==-1||S[i]==S[j])//如果位置i无相同的前缀或者i位置和j位置相同时
{
++i;//主模式串左移一位
++j;//副模式串左移一位
next[i]=j;//副模式串上的位置值给主模式串上的i位置的next
}
else
{
j=next[j];//进行回溯判断
}
}
}
int KMP(Pstring T,char*S,int*next,int pos)
{
int i,j=0;
i=pos-1;//i移到pos位置
int len = T->length, l = strlen(S);
while(i<len&&j<l)//T串走完或者S串走完
{
if(j==-1||T->ch[i]==S[j])//判断是否为整串当前位置不匹配或者模式串当前位置和主串匹配
{
++i;
++j;
}
else
{
j=next[j];//回溯寻找前后缀相同的位置
}
}
if(j==strlen(S))
return i-j+1;
else
return -1;
}