//定长顺序存储
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
#define ERROR 0
#define OK 1
#define NULL 0
#define OVERFLOW -2
#define MAXSTRLEN 40 //用户可以在255内定义最大串长
typedef unsigned char SString[MAXSTRLEN + 1]; //0号单元存放串的长度,即SString[0] = length
//生成一个其值等于chars的串S
int StrAssin(SString S,char *chars)
{
char *c;
int i;
if(S) S[0] = 0;
printf("\ninput your chars:");
chars = (char *)malloc(100 * sizeof(char));
if(!chars){printf("\n--Malloc failed--\n");return(OVERFLOW);}//空间分配失败,错误退出
scanf("%s",chars);
printf("\nyour input:");printf(" %s\n",chars);
for(i = 0,c = chars;*c != NULL;i++,c++);
if(i > MAXSTRLEN) {printf("\n--your input OVER the MAXSTRLEN,StrAssin Failed--\n");return ERROR;}//输入的chars过长
//printf("\nthe length of chars is: %d\n",i);
S[0] = i;
for(i = 1;i <= S[0];i++)
S[i] = chars[i-1];
printf("\nStrAssin String is: ");//输出S
for(i = 1;i <= S[0];i++)
printf("%c",S[i]);
//printf("\nthe length of the String is: %d \n",S[0]);
return OK;
}
//将串S复制到T
void StrCopy(SString T,SString S)
{
int i;
for(i=0;i<=S[0];i++)
T[i]=S[i];
printf("\nthe Copy String is: ");
for(i = 1;i <= T[0];i++)
printf("%c",T[i]);
printf("\n--the Copy String len: %d--\n",T[0]);
}
//串S为空则返回TRUE
int StrEmpty(SString S)
{
if(S[0] == 0)
{
printf("\n--the String is Empty--\n");
return TRUE;
}
else
{
printf("\n--the String is not Empty--\n");
return FALSE;
}
}
//比较串S和串T
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];
}//在相同长度内字符全部相等的话,那就比较两串的长度大小
if(S[0] != T[0]) return S[0] - T[0];
else return 0;
}
//返回串S的长度
int StrLength(SString S)
{
printf("\n--the length of String is: %d--\n",S[0]);
return S[0];
}
//清空串S
void ClearString(SString S)
{
S[0] = 0;//令串长为0即可
}
//将串S1,S2合并到串T
int Concat(SString T,SString S1,SString S2)
{
int i,uncut;
if(S1[0] + S2[0] <= MAXSTRLEN)
{
T[0] = S1[0] + S2[0];
for(i = 1;i <= S1[0];i++)
T[i] = S1[i];
for(i = 1;i <= S2[i];i++)
T[S1[0] + i] = S2[i];
uncut = TRUE;//未截断
}
//S1[0] + S2[0] > MAXSTRLEN有两种情况
else if(S1[0] < MAXSTRLEN)
{
for(i = 1;i <= S1[0];i++)
T[i] = S1[i];
for(i = 1;i <= MAXSTRLEN - S1[0];i++)
T[S1[0] + i] = S2[i];
T[0] = MAXSTRLEN;
uncut = FALSE;//s2被部分截断
}
else
{
for(i = 0;i <= MAXSTRLEN;i++)
T[i] = S1[i];
uncut = FALSE;//S2被完全截断
}
return uncut;
}
//用Sub返回串S的第pos个字符起长度为len的子串
int SubString(SString Sub,SString S,int pos,int len)
{
int i;
if(S[0] == 0){printf("\n--String is empty,can not putout the String--\n");return ERROR;}
if(pos < 1 || pos > S[0] || len < 0 || len > S[0] - pos +1)
{
printf("\n--pos or len is ERROR,can not output the String--\n");
return ERROR;
}
Sub[0] = len;
//输出Sub
//printf("\nThe String Loc pos:%d and len:%d is: ",pos,len);
for(i = 1;i <=len;i++)
{
Sub[i] = S[pos + i - 1];
//printf("%c",Sub[i]);
}
return OK;
}
//在POS前插入子串
int StrInsert(SString S,int pos,SString T)
{
int i;
if(pos < 1 || pos > S[0] + 1)
{
printf("\n--pos is ERROR,can not StrInsert--\n");
return ERROR;
}
if(T[0] + S[0] > MAXSTRLEN){printf("\n--the String you want to Insert is too long--\n");}//S[0] 至多 MAXSTRLEN
//printf("Slen = %d",S[0]);
for(i = S[0];i >= pos;i--)//S中POS以后的字符后移,为插入空出空间(从末尾开始移动,否则会造成字符覆盖丢失)
{
//printf("S[%d] = %c\n",i,S[i]);
S[i + T[0]] = S[i];
}
for(i = 1;i <= T[0];i++)//插入T
S[i + pos -1] = T[i];
S[0] = T[0] + S[0];
return OK;
}
//删除
int StrDelete(SString S,int pos,int len)
{
int i;
if(S[0] == 0){printf("\n--String is empty,can not StrDelete--\n");return ERROR;}
if(pos < 1 || pos > S[0] || len > S[0] - pos + 1 || len < 1)
{
printf("\n--pos or len is ERROR,StrDelete Failed--\n");
return ERROR;
}
for(i = pos;i <= S[0];i++)
S[i] = S[i + len];
S[0] = S[0] - len;
return OK;
}
//比较S和T字符串,返回在S中第POS位序之后的相同字串
int Index(SString S,SString T,int pos)
{
SString Sub;
if(pos < 1 || pos > S[0])
{
printf("\n--pos is ERROR,Index Failed--\n");
return ERROR;
}
while(S[0] - pos + 1 >= T[0])
{
SubString(Sub,S,pos,T[0]);//取于T长度相等的子串
if(!StrCompare(Sub,T))//将子串与T对比
return pos;
else pos++;
}
return 0;
}
//用串V代替S中的所有子串T
int Replace(SString S,SString T,SString V)
{
int i;
int pos = 1;
while(pos)
{
pos = Index(S,T,pos);//定位
if(!pos) return ERROR;//S在POS后找不到与T相等的子串,即完成替换
StrDelete(S,pos,T[0]);//删除S中T
StrInsert(S,pos,V);//用V插入原来T的位置,即完成了替换
pos ++;
}
return OK;
}
//获得next数组(模式串移动的标准)
void get_next(SString T,int next[])
{
int i = 1,j = 0;next[1] = 0;
while(i < T[0])
{
if(j == 0 || T[i] == T[j])
{
++i;
++j;
next[i] = j;
}
else
j = next[j];
}
}
//KMP模式匹配
int Index_KMP(SString S,SString T,int pos,int next[])
{
int i = pos;
int j = 1;//开始从模式串自身的第一位开始匹配
while(i <= S[0] && j <= T[0])
{
if(j == 0 || S[i] == T[j])//主串和模式串当前位序匹配成功,匹配位序后移
{
++i;
++j;
}
else//当前位序匹配不成功,则主串位序不变,模式串移动(以next数组为标度)
j = next[j];
}
if(j > T[0])//模式串的最后一位匹配成功,出了循环后j自增大于T[0],标志匹配已完全
return i - T[0];//返回正确下标
else
return 0;
}
#include "z.H"
void main()
{
int i,pos,len,next[20];
char *chars;
int result;
SString S,T,S1,S2,Sub,V;
/*
//产生串S
printf("\n******StrAssign******\n");
StrAssin(S,chars);
printf("\n***StrAssin completed***\n");
//复制串S
printf("\n********StrCopy*******\n");
StrCopy(T,S);
printf("\n***StrCopy completed***\n");
//判断S是否空
printf("\n********StrEmpty*******\n");
StrEmpty(S);
printf("\n***StrEmpty completed***\n");
//比较S和T
printf("\n******StrCompare******\n");
StrAssin(T,chars);
result = StrCompare(S,T);
if(result > 0) printf("\n--S > T--\n");
else if(result < 0) printf("\n--S < T--\n");
else printf("\n--S = T--\n");
printf("\n***StrCompare complete***\n");
//返回串长
printf("\n********StrLength********\n");
StrLength(S);
printf("\n***StrLength completed***\n");
//将S1和S2连接
printf("\n********Concat********\n");
printf("\nFor S1:");
StrAssin(S1,chars);
printf("For S2:");
StrAssin(S2,chars);
Concat(T,S1,S2);
printf("\n\nAfter concat The String is: ");
for(i = 1;i <= T[0];i++)
printf("%c",T[i]);
printf("\n\n****Concat completed****\n");
//用Sub返回串S的第pos个字符起长度为len的子串
printf("\n********SubString********\n");
printf("\nFor S:");
StrAssin(S,chars);
printf("\ninput the POS:");
scanf("%d",&pos);
printf("\ninput the LEN:");
scanf("%d",&len);
SubString(Sub,S,pos,len);
//输出Sub
printf("\nThe String Loc pos:%d and len:%d is: ",pos,len);
for(i = 1;i <=len;i++){printf("%c",Sub[i]);}
printf("\n****SubString completed****\n");
//在POS前插入子串
printf("\n********StrInsert********\n");
printf("\nFor S:");
StrAssin(S,chars);
printf("\nFor Insert String:");
StrAssin(T,chars);
printf("\ninput your POS:");
scanf("%d",&pos);
StrInsert(S,pos,T);
printf("\nAfter StrIsert:");//输出插入T后的S
for(i = 1;i <= S[0];i++)
printf("%c",S[i]);
printf("\n\n***StrInsert completed***\n");
//删除
printf("\n********StrDelete********\n");
printf("\nFor S:");
StrAssin(S,chars);
printf("\ninput the POS:");
scanf("%d",&pos);
printf("\ninput the LEN:");
scanf("%d",&len);
StrDelete(S,pos,len);
printf("\nAfter StrDelete:");//输出删除后的S
for(i = 1;i <= S[0];i++)
printf("%c",S[i]);
printf("\n\n***StrDelete completed***\n");*/
//比较S和T字符串,返回在S中第POS位序之后的相同字串
printf("\n********Index********\n");
printf("\nFor S:");
StrAssin(S,chars);
printf("\nFor T:");
StrAssin(T,chars);
printf("\ninput your POS:");
scanf("%d",&pos);
get_next(T,next);
result = Index_KMP(S,T,pos,next);
//result = Index(S,T,pos);
printf("Index is: %d",result);
printf("\n****Index completed****\n");
/*
//用串V代替S中的所有子串T
printf("\n********Repalce********\n");
printf("\nFor S:");
StrAssin(S,chars);
printf("\nFor T:");
StrAssin(T,chars);
printf("\nFor V:");
StrAssin(V,chars);
Replace(S,T,V);
printf("\nAfter Replace: ");
for(i = 1;i <= S[0];i++)
printf("%c",S[i]);
printf("\n\n****Repalce completed****\n");*/
}
_____________________________________________________________________________________________________
-____________________________________________________________________________________________________
//堆分配存储表示
#include <stdio.h>
#include <stdlib.h>
#define OVERFLOW -2
#define OK 1
#define ERROR 0
#define NULL 0
#define TRUE 1
#define FALSE 0
typedef struct {
char *ch;
int length;
}HString;
//初始化(产生空串)字符串
void InitString(HString *T)
{
(*T).length=0;
(*T).ch=NULL;
}
//生成字符串
int StrAssign(HString *S,char *chars)
{
int i,n;
char *c;
printf("\n*****StrAssign*****\n");
if((*S).ch) free((*S).ch);
printf("\n--your input : %s--\n",chars);
for(i = 0,c = chars;*c != NULL;++i,++c);//将C做遍历指针,直到C指向空的时候循环退出,i的值即为长度
//{printf("i = %d\n",i);printf("%s\n",c);}
//printf("\n--出了循环后i = %d,即为字符串长度--\n",i);
if(!i){(*S).ch = NULL; (*S).length = 0;}//i为0时
else{
if(!((*S).ch = (char *)malloc(i*sizeof(char))))//空间分配失败,错误退出
{printf("\n--Malloc failed--\n");return OVERFLOW;}
//else空间申请成功,就用S.ch存储函数形参传入的数据chars
for(n = 0;n < i;n++)
{
(*S).ch[n] = chars[n];
(*S).length = i;
}
}
printf("\n***StrAssign Completed***\n");
return OK;
}
//输出从POS开始长度为LEN的字符串
int SubString(HString *Sub,HString *S,int pos,int len)
{
int i,n;
printf("\n*****SubString*****\n");
if((*S).length == 0){printf("\n--String is empty,can not putout the String--\n");return ERROR;}
if(pos < 1 || pos > (*S).length || len < 0 || len > (*S).length - pos +1)
{
printf("\n--pos or len is ERROR,can not output the String--\n");
return ERROR;
}
if((*Sub).ch) free((*Sub).ch);
if(!len){(*Sub).ch = NULL;(*Sub).length = 0;}//输出为空的字串
(*Sub).ch = (char *)malloc(len * sizeof(char));
if(!(*Sub).ch)
{printf("\n--Malloc failed--\n");return OVERFLOW;}
for(i = 0;i <= len-1;i++)
(*Sub).ch[i] = (*S).ch[pos-1+i];
(*Sub).length = len;
//输出Sub
printf("\nThe String Location %d to %d is: \n",pos,pos+len-1);
printf("-----------------------------------------\n");
printf("Sub | ");
for(i = 0;i < len;i++)
printf("%c",(*Sub).ch[i]);
printf("\n\n***SubString Completed***\n");
return OK;
}
//返回字符串长度
int StrLength(HString *S)
{
printf("\n*****StrLength*****\n");
printf("\nthe length of String is: %d\n",(*S).length);
printf("\n***StrLength Completed***\n");
return (*S).length;
}
//比较字符串
int StrCompare(HString *S,HString *T)
{
int i;
printf("\n*****StrCompare*****\n");
printf("\nS | ");
for(i = 0;i < (*S).length;i++)
printf("%c",(*S).ch[i]);
printf("\n---------------------------------\n");
printf("T | ");
for(i = 0;i < (*T).length;i++)
printf("%c",(*T).ch[i]);
printf("\n\nThe result is : ");
for(i = 0;i < (*S).length && i < (*T).length;i++)//在相同的位数以内如果有不相同的字符,则以不同的字符相比较
if((*S).ch[i] != (*T).ch[i])
{
if((*S).ch[i] - (*T).ch[i] > 0)
printf("S > T\n");
else if((*S).ch[i] - (*T).ch[i] < 0)
printf("S < T\n");
printf("\n***StrCompare Complete***\n");
return (*S).ch[i] - (*T).ch[i];
}
//如果在相同的位数以内的所有字符都是相同的,那就比较多出来的字符(即此时以字符串长度的大小来比较)
if((*S).length == (*T).length)
printf("S = T");
else
{
if((*S).length > (*T).length)
printf("S > T");
if((*S).length < (*T).length)
printf("S < T");
}
printf("\n\n***StrCompare Complete***\n");
return ((*S).length - (*T).length);
}
//清空字符串
int ClearString(HString *S)
{
printf("\n*****ClearString*****\n");
if((*S).ch)
{
free((*S).ch);
(*S).ch = NULL;
}
(*S).length = 0;
printf("\n***ClearString Complete***\n");
return OK;
}
//输出字符串
int StrPrint(HString *S)
{
int i;
printf("\n*****StrPrint*****\n");
if((*S).length == 0){printf("\n--String is empty,can not putout the String--\n");return ERROR;}
printf("\nthe String is:");
for(i=0;i<(*S).length;i++)
printf("%c",(*S).ch[i]);
printf("\n");
printf("\n***StrPrint Complete***\n");
return OK;
}
//合并S1和S2字符串
int Contact(HString *T,HString *S1,HString *S2)
{
int i;
printf("\n*****Contact S1 and S2*****\n");
if((*T).ch) free((*T).ch);
/*printf("\nS1 | ");
for(i = 0;i < (*S1).length;i++)
printf("%c",(*S1).ch[i]);
printf("\n---------------------------------\n");
printf("S2 | ");
for(i = 0;i < (*S2).length;i++)
printf("%c",(*S2).ch[i]);*/
if(!((*T).ch = (char *)malloc(((*S1).length + (*S2).length) * sizeof(char))))
{
printf("\n--Malloc failed--\n");
return OVERFLOW;
}
for(i = 0;i < (*S1).length;i++)
(*T).ch[i] = (*S1).ch[i];
(*T).length = (*S1).length + (*S2).length;
for(i = 0;i < (*S2).length; i++)
(*T).ch[(*S1).length + i] = (*S2).ch[i];
//输出合并后的字符串
StrPrint(T);
printf("\n*****Contact Complete*****\n");
return OK;
}
//由串S复制得串T
int StrCopy(HString *T,HString *S)
{
printf("\n*******StrCopy*******\n");
int i;
if((*T).ch)
free((*T).ch); //释放T原有空间
(*T).ch=(char *)malloc((*S).length * sizeof(char)); //分配串空间
if(!(*T).ch) //分配串空间失败
exit(OVERFLOW);
for(i = 0;i < (*S).length;i++) //拷贝串
(*T).ch[i] = (*S).ch[i];
(*T).length = (*S).length;
//输出T
StrPrint(T);
printf("\n*****StrCopy Complete*****\n");
return OK;
}
//比较S和T字符串,返回在S中第POS位序之后的相同字串
int Index(HString *S,HString *T,int pos)
{
printf("\n********Index********\n");
int i;
HString Sub;//直接创建结构体变量,不再使用指针指向
InitString(&Sub);
//要返回的是S的从pos以后的字串(Sub式结构体变量没有指针指向在做函数形参的时候取得是地址)
//再让Sub与T比较
if(pos <= 0 && pos > (*S).length - (*T).length + 1){printf("\n--your pos have made a ERROR--\n");return ERROR;}
if(pos > 0)
{
i = pos;
while(i <= (*S).length - (*T).length + 1)
{
SubString(&Sub,S,i,(*T).length);
if(StrCompare(&Sub,T) != 0) ++i;
else {printf("\n--the Index is : %d--\n",i); return i;}
}
}
printf("\n****Index Complete****\n");
return 0;//找不到符合要求的就返回0
}
//判断是否空串
int StrEmpty(HString *S)
{
printf("\n*******StrEmpty*******\n");
if((*S).length==0 && (*S).ch==NULL)
{printf("\n--String is empty--\n");printf("\n****StrEmpty Complete****\n");return TRUE;}
else
{printf("\n--String is not empty--\n");printf("\n****StrEmpty Complete****\n");return FALSE;}
}
//从串S中删除第pos个字符起长度为len的子串
int StrDelete(HString *S,int pos,int len)
{
int i;
printf("\n*******StrDelete*******\n");
if(len + pos - 1 > (*S).length){printf("\n--your pos or len have made a ERROR--\n");return ERROR;}
for(i=pos-1;i<=(*S).length-len;i++)//i<=(*S).length-len,取等号最后一次前移的是字符串结束标志
(*S).ch[i]=(*S).ch[i+len];
(*S).length -= len;
(*S).ch=(char *)realloc((*S).ch,(*S).length * sizeof(char));
printf("\n****StrDelete Complete****\n");
return OK;
}
int StrInsert(HString *S,int pos,HString *T)
{
int i;
printf("\n********StrInsert********\n");
int len = (*T).length;
if(pos > (*S).length + 1 || pos <= 0){printf("\n--your pos have made a ERROR--\n");return ERROR;}
(*S).ch = (char *)realloc((*S).ch,((*S).length + len) * sizeof(char));
for(i = (*S).length-1;i >= pos-1;--i) // 为插入T而腾出位置
(*S).ch[i + len] = (*S).ch[i];//注意式子的左右两边不能互换:(*S).ch[i] = (*S).ch[i + len] = NULL数据会遗失
for(i = 0;i < len;i++)
(*S).ch[pos-1+i] = (*T).ch[i]; // 插入T
(*S).length += (*T).length;
printf("\n****StrInsert Complete****\n");
return OK;
}
//用V替换主串S中出现的所有与T相等的不重叠的子串
int Replace(HString *S,HString *T,HString *V)
{
printf("\n*******Replace*******\n");
int i=1; //从串S的第一个字符起查找串T
if(StrEmpty(T)) // T是空串
{printf("\n--String is empty--\n");return ERROR;}
do
{
i = Index(S,T,i); // 结果i为从上一个i之后找到的子串T的位置
if(i) // 串S中存在串T
{
StrDelete(S,i,(*T).length); //将从S的第i个字符开始的长度为T.length的字串删除
StrInsert(S,i,V); // 在删除的位置插入串V
i += (*V).length; // 在插入的串V后面继续查找串T
}
}while(i);
printf("\n****Replace Complete****\n");
return OK;
}
#include "N.h"
void main()
{
//遍历下标变量
int pos,len;
//开头申明的是结构体指针,要通过指针访问结构体变量
//必须让结构体指针指向结构体变量
HString *S,*Sub,*T,*S1,*S2,*V;
HString myS,mySub,myT,myS1,myS2,myV;
S = &myS;
Sub = &mySub;
T = &myT;
S1 = &myS1;S2 = &myS2;
V = &myV;
//初始化空串,产生字符串
InitString(S);
InitString(Sub);
InitString(T);
InitString(S1);InitString(S2);
InitString(V);
//录入需要进行操作的字符串
char *chars = (char *)malloc(100*sizeof(char));
printf("\nintput a String for S:\n");
scanf("%s",chars);
//输出从POS位序开始的长度为len的字符串
StrAssign(S,chars);
/*printf("\nStrAssign: intput the POS:\n");
scanf("%d",&pos);
printf("\nStrAssign: intput the len:\n");
scanf("%d",&len);
SubString(Sub,S,pos,len);
//返回字符串长度
StrLength(S);
//比较字符串大小
printf("\nCompare: intput a String for T:\n");
scanf("%s",chars);
StrAssign(T,chars);
StrCompare(S,T);
//清空字符串
StrPrint(S);
ClearString(S);
StrPrint(S);
//合并字符串
printf("\nContact: intput a String for S1:\n");
scanf("%s",chars);
StrAssign(S1,chars);
printf("\nContact: intput a String for S2:\n");
scanf("%s",chars);
StrAssign(S2,chars);
Contact(T,S1,S2);
//字符串复制
StrCopy(T,S);
//将S的第POS以后的字串第一个与T字串相同的位序返回
printf("\n Copy : intput a String for T:\n");
scanf("%s",chars);
StrAssign(T,chars);
printf("\nCopy : input pos : \n");
scanf("%d",&pos);
Index(S,T,pos);
//删除函数
printf("\nDelete: input pos:\n");
scanf("%d",&pos);
printf("\nDelete: input len:\n");
scanf("%d",&len);
StrDelete(S,pos,len);
//输出删除后的S
StrPrint(S);
//插入字串
printf("\nStrInsert: intput a String for T:\n");
scanf("%s",chars);
StrAssign(T,chars);
printf("\n--StrInsert: input pos:--\n");
scanf("%d",&pos);
StrInsert(S,pos,T);
//输出插入T后的S
StrPrint(S);*/
//用V替换主串S中出现的所有与T相等的不重叠的子串
printf("\nReplace: intput a String for T:\n");
scanf("%s",chars);
StrAssign(T,chars);
printf("\nReplace: intput a String for V:\n");
scanf("%s",chars);
StrAssign(V,chars);
Replace(S,T,V);
//输出Repalce后的结果
StrPrint(S);
}