#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define OK 1
#define OVERFLOW 0
#define ERROR 0
typedef struct
{
//串的堆分配存储表示
char *ch;
int curLen;
} HString;
//1.初始化字符串T
int initString (HString *T)
{
(*T).ch=NULL;
(*T).curLen=0;
return OK;
}
//2.串赋值函数
int strAssign (HString *T, char *chars)
{
//生成一个值等于 串常量chars的串T并用指针返回,*chars为指针(数组名)
int i,j;
if ((*T).ch) free((*T).ch);
i=strlen (chars);
if (!i)
{
//若chars为空串,生成空串的堆分配存储表示
(*T).ch=NULL;
(*T).curLen=0;
}
else
{
//chars不为空串
if(!((*T).ch=(char *)malloc(i*sizeof(char))));
for (j=0; j<i; j++)
(*T).ch[j]=chars[j];
(*T).curLen=i;
}
return OK;
}
//3.求串长函数
int StrLength(HString S)
{
return S.curLen;
}
//4.求子串函数
int substring(HString *Sub, HString *S, int pos, int len)
{
//串Sub返回串S的第pos个字符起长度为len的子串
int i;
if (pos<0||pos>S->curLen||len<0||len>S->curLen-pos)
{
//若位置或长度不合法,退出
printf ("输入不合法\n");
exit(OVERFLOW);
}
else
{
if (Sub->ch) free(Sub->ch);
if (!len)
{
Sub->ch=NULL;
Sub->curLen=0;
}
else //若长度len不为0yo
{
Sub->ch= (char* )malloc(len*sizeof(char));
for (i=0; i<len; i++)
{
//从串 s的第pos个字符开始依次复制其后长度为len的字符串到串Sub中
Sub->ch[i]=S->ch[pos-1+i];
Sub->curLen=len;//修改串Sub的串长
}
}
}
return OK;
}
//5.子串定位函数
int Index(HString *ob1, HString *ob2, int pos)
{
//判断从第pos个字符起,ob2 是否为ob1的子串
//若是返回ob2在obl中的起始位置,否则返回-1
int i,j;
if (pos<0||pos>ob1->curLen)
{
//若输入的数值 pos不在obl的串长范围内
printf("输入有误\n");
exit(ERROR);
}
for (i=pos-1; i<=StrLength(*ob1)-StrLength(*ob2); i++)
{
//从 obl的第pos个字符起查找子串ob2
j=0;
while (j<StrLength(*ob2))
//j控制查找位置,逐个字符查找,直到超出子串串长
{
if (ob1->ch[i+j]==ob2->ch[j])
j++;
else break;
}
if (j==StrLength(*ob2))
return i;
}
return -1;
}
//6.串替换函数
void Replace(HString *ob1, HString *ob2,HString *ob3)
{
//将原串ob1的所有子串ob2都替换为插入串ob3
int i,j,k,h,l,m,n,b, len, len2;
char *p, *q;
printf("原串: ");
for (i=0; i<ob1->curLen; i++)
printf ("%c",ob1->ch[i]);
printf ("\n 子串: ");
for (j=0; j<ob2->curLen; j++)
printf ("%c",ob2->ch[j]);
printf("\n");
printf("插入串: ");
for (k=0; k<ob3->curLen; k++)
printf ("%c",ob3->ch[k]);
printf ("\n");
len=StrLength(*ob2);
while (Index (ob1,ob2,0) !=-1)
{
len2=StrLength (*ob3)+StrLength (*ob1) -StrLength (*ob2);
i=Index (ob1,ob2,0);
p= (char*) malloc (sizeof (char)* (StrLength(*ob1)-i-len+1));
q= (char* )malloc (sizeof (char)* len2);
for (j=i+len; j<StrLength(*ob1); j++)
p[j]=ob1->ch[j];
for (k=0; k<i; k++)
q[k]=ob1->ch[k];
for (m=i; m<i+StrLength(*ob3); m++)
q[m]=ob3->ch[m-i];
b=i+len;
for (n=i+StrLength(*ob3); n<len2; n++)
{
//将不用替换的后部分存入数组q
q[n]=p[b];
b++;
}
ob1->curLen=len2;
for (l=0; 1<len2; l++)
ob1->ch[1]=q[1];
}
printf("新串: ");
for (h=0; h<ob1->curLen; h++)
printf ("%c",ob1->ch[h]);
}
//7.串比较函数
int Compare(HString s1, HString s2)
{
//若 s1<s2则返回值<0;若s1=s2 则返回值=0;若s1>s2 则返回值>0
int i;
for (i=0; i<s1.curLen && i<s2.curLen; ++i)
if (s1.ch[i] != s2.ch[i])
return (s1.ch[i]-s2.ch[i]);
return (s1.curLen-s2.curLen);
}
//8.主函数
int main()
{
printf("请选择将要进行的操作: \n\n");
printf("1. 赋值 格式为: A 串值 回车\n");
printf("2. 求长度 格式为: L 串值 回车\n");
printf("3. 求子串 格式为: S 串值 数1 数2 回车\n");
printf("4. 子串定位 格式为: I 串值1 串值2 数1 回车\n");
printf("5. 替换 格式为: R 串值1 串值2 串值3 回车\n");
printf("6. 判相等 格式为: C 串值1 串值2 回车\n");
printf("7. 退出 格式为: Q 回车\n\n");
while(1)
{
int i;
char c;
printf("输入要进行的操作(全部用大写):");
scanf ("%c",&c);
if(c=='Q') break;
switch(c)
{
//用switch 语句对输入的大写字母进行多向选
case'A':
{
char cnew[50];
HString str;
initString(&str);
scanf("%s",cnew);
strAssign(&str,cnew);
printf("字符串为:");
for(i=0; i<str.curLen; i++)
printf("%c",str.ch[i]);
printf("\n");
break;
}
case 'L':
{
char cnew[50];
HString str;
printf("求串长操作。请输入一个字符串:\n");
scanf("%s",cnew) ;
initString(&str);
strAssign(&str, cnew);
printf("长度为:%d\n",StrLength(str));
}
case 'S':
{
char cnew[50];
int pos,len,i;
HString sub,str;
printf("求子串操作。\n");
printf("请输入主串、子串的起始位置及长度,用空格隔开: \n");
scanf("%s %d %d", cnew, &pos, &len);
initString(&sub);
initString(&str);
strAssign(&str, cnew);
substring(&sub, &str, pos, len);
printf("子串为:");
for(i=0; i<sub.curLen; i++)
printf ("%c",sub.ch[i]);
printf("\n");
break;
}
case 'C':
{
char c1[50];
char c2[50];
HString s1,s2;
scanf("%s %s", c1,c2);
initString(&s1);
initString(&s2);
strAssign(&s1,c1);
strAssign(&s2,c2);
if (Compare(s1,s2) < 0)
printf("判断的结果:串1<串2\n");
else if (Compare(s1,s2)==0)
printf ("判断的结果:串1=串2\n");
else printf("判断的结果:串 1>串2\n");
break;
}
case 'I':
{
char c1[50];
char c2[50];
int pos;
int result=0;
HString str1;
HString str2;
printf("串替换。请输入主串、子串、新子串,用空格隔开:\n");
scanf("%s %s %d", c1,c2, &pos);
initString(&str1);
initString(&str2);
strAssign(&str1,c1);
strAssign(&str2,c2);
result=Index(&str1, &str2, pos)+1; //调用子串定位函数
if (result==0)
printf("从第%d个字符起,串2不是串1的子串。\n",pos);
else printf(" 子串在原串的位置:%d\n", result);
break;
}
case 'R':
{
char c1[50],c2[50],c3[50];
HString str1,str2,str3;
printf("串替换。请输入主串、子串、新子串,用空格隔开:\n");
scanf("%s %s %s", c1,c2,c3);
initString(&str1);//初始化串str1
initString(&str2);//初始化串str2
initString(&str3);//初始化串str3
strAssign(&str1,c1);
strAssign(&str2,c2);
strAssign(&str3,c3);
Replace(&str1, &str2, &str3);//调用替换函数
printf("\n");
break;
}
}
}
return 0;
}