数据结构的重要行不言而喻,简单介绍我在这部分遇到的一些问题,希望对大家有少许帮助。
首先实现的多个操作:
代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define OK 1
#define ERROR -1
#define OVERFLOW -3
#define BIG 2
#define EQUAL 0
#define LITTLE -2
typedef int Status;
typedef struct
{
char *ch;
int length;
}HString;
//功能
void menu()
{
printf("\t\t***************串的堆实现*********************\n");
printf("\t\t\t1 求字符串的长度\n");
printf("\t\t\t2 从主串中提取一个子串\n");
printf("\t\t\t3 比较两个字符串的大小\n");
printf("\t\t\t4 求一个子串在主串中的位置\n");
printf("\t\t\t5 将两个字符串连接成一个新的字符串\n");
printf("\t\t\t0 退出系统\n");
printf("\t\t***************顺序栈实现*********************\n");
}
//初始化字符串
Status StrAssign(HString &T,char * chars)
{
int len=0;
char *c;
if(T.ch)
free(T.ch);
//len=(int)strlen(chars)-1;
for(c = chars; *c; ++c)
len++;
if(!len)
{
T.ch=NULL;
T.length=0;
}
else
{
if(!(T.ch=(char *)malloc(len*sizeof(char))))
exit(OVERFLOW);
for(int j=0;j<len;j++)
{
T.ch[j]=chars[j];
}
T.length=len;
}
return OK;
}
//清空函数
Status ClearString(HString &S)
{
if(S.ch)
{
free(S.ch);
S.ch=NULL;
}
S.length=0;
return OK;
}
//求长度
int StrLength(HString S)
{
return S.length;
}
//求子串(第pos个位置,长度为len的子串,SubS拿来装子串)
Status SubString(HString S,HString &SubS,int pos,int len)
{
if(pos<1 || pos>S.length || len<0 || len>S.length-pos+1)
return ERROR;
if(SubS.ch)
free(SubS.ch);
if(len==0)
{
SubS.ch=NULL;
SubS.length=0;
}
else
{
SubS.ch=(char*)malloc(len*sizeof(char));
for(int i=0;i<len;i++)
{
SubS.ch[i]=S.ch[pos-1];
pos++;
}
SubS.length=len;
}
return OK;
}
/*比较也可以写成这个(避免我的警告)
//功能:对2个字符串str1和str2逐一进行比较,如果对应位置相等,
// 继续比较下一个字符,否则返回对应位置字符的ASCII的差值
int StrCompare(HString str1, HString str2)
{
int i;
for(i = 0;(i < str1.length && i < str2.length); i++) //2个字符串存在从第一个开始的若干相等字符串,则比较
{
if(str1.str[i]!=str2.str[i])
return(str1.str[i] - str2.str[i]);
}
return (str1.length-str2.length); //当上面比较完都没发现不同字符时,此时比较串长
}
*/
//比较两个字串的大小(应该可以优化)
int StrCompare(HString S,HString H)
{
int time;
time=0;
if(S.length>H.length)
return BIG;
if(S.length<H.length)
return LITTLE;
if(S.length==H.length)
{
for(int i=0;i<S.length;i++)
{
if(S.ch[i]>H.ch[i])
return BIG;
if(S.ch[i]<H.ch[i])
return LITTLE;
if(S.ch[i]==H.ch[i])
time++;
}
if(time==S.length)
return EQUAL;
}
}
//求一个字符串在主串中的位置(要引用上面求子串的函数,书上用pos的意义是从第几个位置起(有多个截取后相等情况时)
int SubStringLocation(HString S,HString T)
{
int i=0;
HString SubS;//用来截取的子串串
SubS.ch=NULL;
SubS.length=0;
while(i<S.length-T.length+1)//截取位置起的后面一截
{
SubString(S,SubS,i,T.length); //这里注意3个串别写混了
if(StrCompare(T,SubS)!=EQUAL)
{
i++;
if(i==S.length-T.length+1-1) //防止123456aaafffg fffffff
return ERROR;
}
else
return i; //如果有多个子串,存入数组中输出数组即可
}
}
//连接两个字符串为一个字符串
Status StringCat(HString &T,HString S,HString S2)
{
if(T.ch)
free(T.ch);
if(!(T.ch=(char *)malloc((S.length+S2.length)*sizeof(char))))
exit(OVERFLOW);
for(int i=0;i<S.length;i++)
{
T.ch[i]=S.ch[i];
}
T.length=S.length+S2.length;
for( i=S.length;i<T.length;i++)
{
T.ch[i]=S2.ch[i-S.length];//注意别写漏掉i-S.length
}
return OK;
}
int main()
{
int choice,pos=0,len=0;
HString S,T,Str;
S.ch=NULL;
S.length=0;
T.ch=NULL; //注意必须先初始化,不然没有值输出
T.length=0;//注意必须先初始化
Str.ch=NULL;
Str.length=0;
char s[100],s1[100];
while(1)
{
menu();
printf("请输入要选择的功能:\n");
scanf("%d",&choice);
switch(choice)
{
case 1:
{
printf("请输入一个字符串:\n");
scanf("%s",s);
if(StrAssign(T,s))
printf("字符串长度为:%d\n",StrLength(T));
printf("请按回车继续!\n");
getchar();getchar();
system("cls");break;
}
case 2:
{
printf("请输入主串:\n");
scanf("%s",s);
if(StrAssign(S,s))
{
printf("请输入提取子串的位置pos,以及长度len:");
scanf("%d%d",&pos,&len);
ClearString(T);//注意释放,防止再次输入
if(SubString(S,T,pos,len)==OK) //这里为什么要写OK才行?
{
for(int i=0;i<T.length;i++)
{
printf("%c",*(T.ch+i));//指针
}
printf("\n");
}
else
printf("输入的位置或长度有误!\n");
}
printf("请按回车继续!\n");
getchar();getchar();
system("cls");break;
}
case 3:
{
printf("请输入两个字符串s和s1:\n");
scanf("%s%s",s,s1);
if(StrAssign(S,s) && StrAssign(T,s1))
{
if(StrCompare(S,T)==BIG)
printf("字符串s:%s更大",s);
if(StrCompare(S,T)==EQUAL)
printf("字符串s:%s与字符串s1: %s相等",s,s1);
if(StrCompare(S,T)==LITTLE)
printf("字符串s1:%s更大",s1);
}
printf("请按回车继续:\n");
getchar();getchar();
system("cls");break;
}
case 4:
{
printf("请输入主串s:\n");
scanf("%s",s);
if(StrAssign(S,s))
{
printf("请输入字串s1:\n");
scanf("%s",s1);
if(StrAssign(T,s1))
{
if(SubStringLocation(S,T)!=ERROR)
printf("子串s1在主串s中按从左往右计数的位置(只计算出第相同子串一个位置)为:%d\n",SubStringLocation(S,T));
else
printf("主串中没有该子串!\n");
}
}
printf("请按回车继续!\n");
getchar();getchar();
system("cls");break;
}
case 5:
{
printf("请输入第一个字符串s:\n");
scanf("%s",s);
if(StrAssign(S,s))
{
printf("请输入第二个字符串s1:\n");
scanf("%s",s1);
if(StrAssign(T,s1))
{
if(StringCat(Str,S,T))
{
for(int i=0;i<Str.length;i++)
printf("%c",*(Str.ch+i));
}
printf("\n");
}
}
printf("请按回车继续!\n");
getchar();getchar();
system("cls");break;
}
case 0:printf("成功退出系统!\n");exit(0);break;
default:printf("输入有误!\n");exit(0);break;
}
}
return 0;
}
综合程序是需要不断改进的,下面说说我遇到的问题吧:
1.
这以上3中常见串问题 大家需要注意。
代码中大多数注释都有,若有错误望大家不吝指教,祝大家编程愉快,谢谢!。