1. 串的存储结构
1.1 串的顺序存储
从下标为1的数组分量开始存储
当0号单元存放串的当前长度时,可以定义:(后续基本操作都使用此定义)
typedef char SString[MAXSIZE+1];
但0号单位闲置不用时,可以定义:
typedef struct{
char ch[MAXSIZE+1];
int length;
}SString;
还有堆(Heap)式顺序存储结构
typedef struct{
char *ch;
int length;
}HString;
1.2 串的链式存储
块链结构:
#define CHUNKSIZE 80
typedef struct Chunk{
char ch[CHUNKSIZE];
struct Chunk *next;
}Chunk;
typedef struct{
Chunk *head,*tail;
int length;
}LString;
2. 串的基本操作
2.1 分配StrAssign(T,*chars)
生成一个其值等于chars的串T(chars是字符串常量),如StrAssign(s1,"abcd")
Status StrAssign(SString T,char *chars)
{
int i;
if(strlen(chars)>MAXSIZE)
return ERROR;
else
{
T[0]=strlen(chars);
for(i=1;i<=T[0];i++)
T[i]=*(chars+i-1);
return OK;
}
}
2.2 复制StrCopy(T,S)
由串S复制得串T
Status StrCopy(SString T,SString S)
{
int i;
for(i=0;i<=S[0];i++)
T[i]=S[i];
return OK;
}
2.3 判断是否为空StrEmpty(S)
Status StrEmpty(SString S)
{
if(S[0]==0)
return TRUE;
else
return FALSE;
}
2.4 比较大小StrCompare(S,T)
返回长度差。若S>T,则返回值>0;若S=T,则返回值=0;若S<T,则返回值<0
int StrCompare(SString S,SString T)
{
int i;
for(i=1;i<=S[0]&&i<=T[0];++i)
if(S[i]!=T[i])
return S[i]-T[i];
return S[0]-T[0];
}
2.5 求串长StrLength(S)
int StrLength(SString S)
{
return S[0];
}
2.6 清空ClearString(S)
Status ClearString(SString S)
{
S[0]=0;
return OK;
}
2.7 字符串连接Concat(T,S1,S2)
用T返回S1和S2联接而成的新串。若未截断S2,则返回TRUE,否则FALSE
Status Concat(SString T,SString S1,SString S2)
{
int i;
if(S1[0]+S2[0]<=MAXSIZE)
{
for(i=1;i<=S1[0];i++)
T[i]=S1[i];
for(i=1;i<=S2[0];i++)
T[S1[0]+i]=S2[i];
T[0]=S1[0]+S2[0];
return TRUE;
}
else
{
for(i=1;i<=S1[0];i++)
T[i]=S1[i];
for(i=1;i<=MAXSIZE-S1[0];i++)
T[S1[0]+i]=S2[i];
T[0]=MAXSIZE;
return FALSE;
}
}
2.8 取子串SubString(Sub,S,pos,len)
用Sub返回串S的第pos个字符起长度为len的子串
Status SubString(SString Sub,SString S,int pos,int len)
{
int i;
if(pos<1||pos>S[0]||len<0||len>S[0]-pos+1)
return ERROR;
for(i=1;i<=len;i++)
Sub[i]=S[pos+i-1];
Sub[0]=len;
return OK;
}
2.9 子串的定位Index(S, T, pos) ,又称为串的模式匹配算法
返回子串T在主串S中第pos个字符之后的位置。若不存在,则函数返回值为0。其中,T非空,1≤pos≤StrLength(S)
BF算法:
方法一:
int Index(SString S, SString T, int pos)
{
int i = pos;
int 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;
}
方法二:
int Index(SString S, SString T, int pos)
{
int n,m,i;
SString sub;
if (pos > 0)
{
n = StrLength(S);
m = StrLength(T);
i = pos;
while (i <= n-m+1)
{
SubString (sub, S, i, m);
if (StrCompare(sub,T) != 0)
++i;
else
return i;
}
}
return 0;
}
KMP算法
void get_next(String T, int *next)
{
int i,k;
i=1;
k=0;
next[1]=0;
while (i<T[0])
{
if(k==0 || T[i]== T[k])
{
++i;
++k;
next[i] = k;
}
else
k= next[k];
}
}
int Index_KMP(String S, String T, int pos)
{
int i = pos;
int j = 1;
int next[255];
get_next(T, next);
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;
}
2.10 插入StrInsert(S,pos,T)
在串S的第pos个字符之前插入串T。完全插入返回TRUE,部分插入返回FALSE。其中1≤pos≤StrLength(S)+1
Status StrInsert(SString S,int pos,SString T)
{
int i,j;
j=pos;
if(pos<1||pos>S[0]+1)
return ERROR;
if(S[0]+T[0]<=MAXSIZE)
{
for(i=S[0];i>=pos;i--)
S[i+T[0]]=S[i];
for(i=pos;i<pos+T[0];i++)
S[i]=T[i-pos+1];
S[0]=S[0]+T[0];
return TRUE;
}
else
{
for(i=pos+T[0];i<=MAXSIZE;i++,j++)
S[i]=S[j];
for(i=pos;i<pos+T[0];i++)
S[i]=T[i-pos+1];
S[0]=MAXSIZE;
return FALSE;
}
}
2.11 删除子串StrDelete(S,pos,len)
从串S中删除第pos个字符起长度为len的子串。其中1≤pos≤StrLength(S)-len+1
Status StrDelete(SString S,int pos,int len)
{
int i;
if(pos<1||pos>S[0]-len+1||len<0)
return ERROR;
for(i=pos+len;i<=S[0];i++)
S[i-len]=S[i];
S[0]-=len;
return OK;
}
2.12 替换Replace(S,T,V)
用V替换主串S中出现的所有与T相等的不重叠的子串
Status Replace(SString S,SString T,SString V)
{
int i=1;
if(StrEmpty(T))
return ERROR;
do
{
i=Index(S,T,i);
if(i)
{
StrDelete(S,i,StrLength(T));
StrInsert(S,i,V);
i+=StrLength(V);
}
}while(i);
return OK;
}
2.13 打印StrPrint(T)
void StrPrint(SString T)
{
int i;
for(i=1;i<=T[0];i++)
printf("%c",T[i]);
printf("\n");
}
3. 串的综合实例
#include<stdio.h>
#include<string.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 40
typedef int Status;
typedef char SString[MAXSIZE+1];
Status ClearString(SString S)
{
S[0]=0;
return OK;
}
Status StrAssign(SString T,char *chars)
{
int i;
if(strlen(chars)>MAXSIZE)
return ERROR;
else
{
T[0]=strlen(chars);
for(i=1;i<=T[0];i++)
T[i]=*(chars+i-1);
return OK;
}
}
Status StrCopy(SString T,SString S)
{
int i;
for(i=0;i<=S[0];i++)
T[i]=S[i];
return OK;
}
Status StrEmpty(SString S)
{
if(S[0]==0)
return TRUE;
else
return FALSE;
}
int StrCompare(SString S,SString T)
{
return S[0]-T[0];
}
int StrLength(SString S)
{
return S[0];
}
void StrPrint(SString S)
{
int i;
for(i=1;i<=S[0];i++)
printf("%c",S[i]);
printf("\n");
}
void menu()
{
printf(" ********串的功能菜单******** \n");
printf(" 1.赋值(已有串T和S) ");printf("2.复制\n");
printf(" 3.判断是否为空串 ");printf("4.比较长度\n");
printf(" 5.求串长 ");printf("6.清空\n");
printf(" 7.打印 ");printf("8.退出\n");
}
int main()
{
int i,choice=0;
char chars[MAXSIZE+1];
SString S,T;
ClearString(S);
ClearString(T);
menu();
while(choice!=8)
{
printf("请选择功能:\n");
scanf("%d",&choice);
switch(choice)
{
case 1:
printf("1.给串S赋值\n");
printf("2.给串T赋值\n");
printf("请输入1或2\n");
scanf("%d",&i);
printf("请输入要赋的值:\n");
getchar();
scanf("%s",chars);
if(i==1){
StrAssign(S,chars);
printf("串S赋值完成!\n");
}
else if(i==2){
StrAssign(T,chars);
printf("串T赋值完成!\n");
}
else
printf("序号错误,请输入正确的序号");
break;
case 2:
printf("1.由串S复制得串T\n");
printf("2.由串T复制得串S\n");
printf("请输入1或2\n");
scanf("%d",&i);
if(i==1){
StrCopy(T,S);
printf("复制完成!\n");
}
else if(i==2){
StrCopy(S,T);
printf("复制完成!\n");
}
else
printf("序号错误,请输入正确的序号");
break;
case 3:
if(StrEmpty(S)){
printf("S是空串\n");
}
else{
printf("S不是空串\n");
}
if(StrEmpty(T)){
printf("T是空串\n");
}
else{
printf("T不是空串\n");
}
break;
case 4:
printf("S和T的长度差为%d\n",StrCompare(S,T));
break;
case 5:
printf("串S长为%d\n",StrLength(S));
printf("串T长为%d\n",StrLength(T));
break;
case 6:
printf("1.清空串S\n");
printf("2.清空串T\n");
printf("请输入1或2\n");
scanf("%d",&i);
if(i==1){
ClearString(S);
printf("S已清空!\n");
}
else if(i==2){
ClearString(T);
printf("T已清空!\n");
}
else
printf("序号错误,请输入正确的序号");
break;
case 7:
printf("串S为:");
StrPrint(S);
printf("串T为:");
StrPrint(T);
break;
case 8:
printf("******************END**********************\n");
break;
}
}
return 0;
}
运行截图:
补充:C语言库文件string.h中常用的基本字符串函数
char s1[]="I am a student";
char s2[20]="teacher";
char s3[]="student";
char s4[20],*p;
串长strlen
int strlen(char *str),如strlen(s1) == 14
复制strcpy
char *strcpy(char *str1,char *str2)
strcpy(s4,s2);
printf("%s\n",s4);
比较strcmp
int strcmp(char *str1,char *str2),如strcmp(s2,s3)
字符定位strchr
char *strchr(char *str,char ch)
p = strchr(s1,'s');
printf("%s\n",p);
子串查找strstr
char *strstr(char *s1,char *s2)
p = strstr(s1,s3);
printf("%s\n",p);
连接strcat
char *strcat(char *s1, char *s2)
strcat(s2,s3);
printf("%s\n",s2);
|