程序设计串的基本操作.docx
《程序设计串的基本操作.docx》由会员分享,可在线阅读,更多相关《程序设计串的基本操作.docx(22页珍藏版)》请在冰豆网上搜索。
程序设计串的基本操作
武汉工业学院
数学与计算机学院
数据结构课程设计
设计题目:
串的基本操作
专业计算机与信息工程
班级1007班
学号********
姓名*******
指导教师*******
2011年9月3日
目录
一.题目及需求分析……………………………
二.概要设计……………………………………
三.详细设计……………………………………
四.调试分析……………………………………
五.用户手册……………………………………
六.测试结果……………………………………
七.附录程序清单………………………………
八.思考与小结…………………………………
一.需求分析
1.用堆分配存储表示实现Hstring串类型的最小操作子集。
2.实现串抽象类型的其余基本操作(如联接、删除等),且不能使用c语言
本身提供的串函数,必须自己构造新的函数实现串的基本操作。
3.本演示系统是一个命令解释程序,循环往复的处理用户输入的每一条命令,
直至终止程序的命令为止。
4.参数的合法性必须严格检查,要严格按照命令的输入格式进行输入,否则
程序可能无法正确执行指令。
二、概要设计
实现串的抽象数据类型和实现其基本操作,程序中将涉及下列抽象数据类型:
1.定义串的基本主结构
ADTString{
数据对象:
D={ai|ai∈charcaterset,i=1,2,…,n,n>=0}
数据关系:
R1={|ai-1,ai∈D,i=1,2,…,n}
基本操作:
StrCompare(HStringS,HStringT)
初始条件:
S和T是已存在的Hstring类型。
操作结果:
比较其值,显示结果“UNEQUAL”或“EQUAL”。
StrLength(HStringS)
初始条件:
S是已存在的Hstring类型。
操作结果:
返回该串的长度。
Concat(HStringS1,HStringS2)
初始条件:
S1和S2是已存在的Hstring类型。
操作结果:
由S1和S2联接成新串。
Index(HStringS,HStringt)
初始条件:
S和T是已存在的Hstring类型。
操作结果:
显示第二个串在第一个串中首次出现的起始位置。
Replace(HStringM,HStringt,HStringv)
初始条件:
M、t和v是已存在的Hstring类型。
操作结果:
将第一个串中所有出现的第二个串用第三个串替换,显示结果串的内部名和串值,原串不变。
SubString(HStringS,intpos,intlen)
初始条件:
S是已存在的Hstring类型。
操作结果:
如果参数合法,则显示子串的内部名和串值。
Strprint(HStringS)
初始条件:
S是已存在的Hstring类型。
操作结果:
显示串S的内部名和串值。
getin(intn)
初始条件:
处理命令串S1,
操作结果:
把串值存入串头表中
Insert(intn)
初始条件:
要给指定的串赋值,n为指定的串的内部名
操作结果:
为指定内部名的串赋值
show()
初始条件:
要求查看输入格式
操作结果:
输出各种命令的输入格式
}ADTString
2详细设计
#include//标准的输入输出流头文件
#include
usingnamespacestd;//标识符的可见范围
typedefstruct
{
char*ch;//若是非空串,则按串长分配存储区,否则ch为NULL
intlength;//串长度
}HString;
HStringA,B,C,D,E,F,G,H;
voidInitString(HString*S)//初始化串
{
S->ch=NULL;
S->length=0;
}
voidShow()//显示串的基本情况
{
cout<<"串的使用情况:
"<if(A.ch==NULL)
cout<<"A标识串未使用."<else
cout<<"A串的内容是“"<if(B.ch==NULL)
cout<<"B标识串未使用."<else
cout<<"B串的内容是“"<if(C.ch==NULL)
cout<<"C标识串未使用."<else
cout<<"C串的内容是“"<if(D.ch==NULL)
cout<<"D标识串未使用."<else
cout<<"D串的内容是“"<if(E.ch==NULL)
cout<<"E标识串未使用."<else
cout<<"E串的内容是“"<if(F.ch==NULL)
cout<<"F标识串未使用."<else
cout<<"F串的内容是“"<if(G.ch==NULL)
cout<<"G标识串未使用."<else
cout<<"G串的内容是“"<if(H.ch==NULL)
cout<<"H标识串未使用."<else
cout<<"H串的内容是“"<}
intmain()
{
InitString(&A);
InitString(&B);
InitString(&C);
InitString(&D);
InitString(&E);
InitString(&F);
InitString(&G);
InitString(&H);//初始化操作
voidstrassign();//赋值
voidequality();//判断相等
voidconcat();//联接
voidstrleng();//求串长
voidsubstring();//求子串
voidindex();//子串定位
voidreplace();//串替换
voidstrdelete();//串删除
voidquit();//退出程序
chari,ch;
inta=1,b=1;
while(b)
{
Show();
cout<<"请选择你要进行的操作:
A、赋值E、判相等C、联接L、求长度S、求子串I、子串定位R、串替换P、显示D、删除Q、退出"<while(a)
{
fflush(stdin);//清空输入流,避免缓冲区内残存读取函数无法取走的内容
cin>>i;
switch(i)
{
case'A':
case'a':
strassign();a=0;break;
case'E':
case'e':
equality();a=0;break;
case'C':
case'c':
concat();a=0;break;
case'L':
case'l':
strleng();a=0;break;
case'S':
case's':
substring();a=0;break;
case'I':
case'i':
index();a=0;break;
case'R':
case'r':
replace();a=0;break;
case'P':
case'p':
Show();a=0;break;
case'D':
case'd':
strdelete();a=0;break;
case'Q':
case'q':
quit();a=0;break;
default:
cout<<"输入错误,请重新输入:
";
}
}
b=0;
cout<<"还要继续吗?
(y/n):
";
fflush(stdin);//清空输入流
cin>>ch;
if(ch=='y'||ch=='Y')
{
a=1;
b=1;
system("cls");//清屏
}
}
return0;
}
HString*Chuanzhizhen()//把每一次你要操作的字符串的地址传递给一个字符串指针
{
HString*s;
charch;
inta=1;
while(a)
{
fflush(stdin);//清空输入流
cin>>ch;
switch(ch)//把小写字母转化成大写字母
{
case'A':
case'a':
s=&A;a=0;break;
case'B':
case'b':
s=&B;a=0;break;
case'C':
case'c':
s=&C;a=0;break;
case'D':
case'd':
s=&D;a=0;break;
case'E':
case'e':
s=&E;a=0;break;
case'F':
case'f':
s=&F;a=0;break;
case'G':
case'g':
s=&G;a=0;break;
case'H':
case'h':
s=&H;a=0;break;
default:
cout<<"输入错误,请重新输入要给与赋值的串标示:
";
}
}
returns;
}
voidstrassign()//赋值操作
{
HString*s;//用一个指向串的指针来操作串
inti=0;
charstr[100],*c;
cout<<"请输入要给与赋值的串标示:
";
s=Chuanzhizhen();//调用函数
if(s->ch)//如果本身有值,则删除
free(s->ch);
cout<<"请输入你要赋值的字符串的值:
";
fflush(stdin);//清空输入流
gets(str);
c=str;
while(*c)//取值操作
{
i++;
c++;
}//求出输入字符串的长
if(!
i)//如果没有输入
{
s->ch=NULL;
s->length=0;
}
else
{
s->ch=(char*)malloc(sizeof(char)*i+1);
for(intj=0;j
{
s->ch[j]=str[j];
}
s->ch[i]='\0';
s->length=i;
}
}
voidequality()//判断相等操作
{
HString*s1,*s2;//同样用指向串的指针来操作串
cout<<"请输入第一个串标识:
";
s1=Chuanzhizhen();
cout<<"请输入第二个串标识:
";
s2=Chuanzhizhen();
if(s1->ch==NULL&&s2->ch==NULL)
{
cout<<"EQUAL(相等),字符串都是空串"<}
elseif(s1->ch&&s2->ch)//字符串都不是空串
{
if(s1->length!
=s2->length)
{
cout<<"UNEQUAL(不相等)"<}
else
{
for(inti=0;ilength;i++)
{
if(s1->ch[i]!
=s2->ch[i])
{
cout<<"UNEQUAL(不相等)"<return;
}
}
cout<<"EQUAL(相等)"<}
}
else
{
cout<<"UNEQUAL(不相等)"<}
}
voidconcat()//串连接操作
{
HString*s1,*s2,*s3;
cout<<"请输入第一个串的串标识:
";
s1=Chuanzhizhen();
cout<<"请输入第二个串的串标识:
";
s2=Chuanzhizhen();
cout<<"请输入连接之后想要存入串的串标识:
";
s3=Chuanzhizhen();
if(s1->length==0&&s2->length==0)//两个都是空串
{
if(s3->ch)//如果s3有值的话,把s3清空
{
free(s3);
s3->ch=NULL;
s3->length=0;
}
}
else//至少有一个不是空串
{
inti=0;
if(s3->ch)
free(s3);
s3->ch=(char*)malloc(sizeof(char)*(s1->length+s2->length)+1);
for(i=0;ilength;i++)
{
s3->ch[i]=s1->ch[i];
}
for(intj=0;jlength;j++)
{
s3->ch[i+j]=s2->ch[j];
}
s3->ch[i+j]='\0';
s3->length=s1->length+s2->length;
}
}
voidstrleng()//求串长
{
HString*s;
cout<<"请输入串的标识:
";
s=Chuanzhizhen();
cout<<"串的长度为:
"<length<}
voidsubstring()//求子串
{
HString*s;
inti1=0,i2=0,a=1,m=0;//用m来标识字串的长度
cout<<"请输入串的标识:
";
s=Chuanzhizhen();
while(a)
{
cout<<"请输入起始位置(从1开始):
";
cin>>i1;
cout<<"请输入结束位置:
";
cin>>i2;
if(i1<0||i2<0||i1>i2||i1>s->length)
{
cout<<"输入参数不合法,请重新输入."<}
else
{
a=0;
charch1[100];
if(i2>s->length)
{
i2=s->length;
}
for(inti=i1-1;i{
ch1[i-i1+1]=s->ch[i];//因为数组ch要从0号位置开始赋值,所以用ch[i-i1+1]
m++;
}
ch1[m]='\0';
cout<<"字串为:
"<"<}
}
}
voidindex()//子串定位
{
HString*s;
intm=0,i=0,j=0,n,k=0;//m用来标记输入子串的长度,n用来标记子串在主串中的第一个位置
boolfind=true;//用来标识,是否在主串中找到第一个和子串中的相等的字母,true表示没找到
charch[100],*c;
cout<<"请输入主串的标识:
";
s=Chuanzhizhen();
cout<<"请输入你要查找的子串:
";
fflush(stdin);//清空输入流
gets(ch);
c=ch;
while(*c)
{
m++;
c++;
}
for(i=0;i{
find=true;
for(j;jlength&&find;j++)//主串的循环遍历
{
if(s->ch[j]==ch[i])//如果相等就跳出该层循环(主串的循环遍历),并记下这个初始位置
{
n=j+1;
find=false;
k++;//用k来标识是否进行了这个循环体
}
else//否则,就从头开始遍历子串,从下一位置遍历主串
{
i=0;
if(k!
=0)
{
j=n-k;//如果子串和主串的前面一部分相等,后一部分不相等,则让主串从第一个相等的字符的后一个字符开始遍历
k=0;//例如主串:
aabbaabbaca,子串bbac,当遍历主串到第三个位置的时候,发现第一个和子串相等的字符,但遍历到第6个位置时,不相等了,此时从主串的第4个位置开始遍历
}
}
}
}
if(i==m&&find==false)
cout<<"子串在主串的位置:
"<else
cout<<"不存在该子串."<}
voidreplace()//串替换
{
HString*s;
intm=0,i=0,j=0,n=0,k=0,p=0,ch2length=0,d=0,f=0;//p用来记录数组ch3中有多少个字符,f用来记录下一次开始遍历主串的起始位置
boolfind=true;
boolxiangdeng=false,jinru=false;
charch1[100],ch2[100],ch3[200],*c,*c1;
cout<<"请输入主串的串标识:
";
s=Chuanzhizhen();
cout<<"请输入主串中的子串(被替换掉的):
";
fflush(stdin);//清空输入流
gets(ch1);
c=ch1;
while(*c)
{
m++;
c++;
}//求子串的长度
cout<<"请输入主串中的子串要被替换成的串:
";
fflush(stdin);//清空输入流
gets(ch2);
c1=ch2;
while(*c1)
{
ch2length++;
c1++;
}//求ch2字符串的长度
for(i=0;ilength;i++)//主串作为外层循环遍历,和字串定位的查找不一样
{
find=true;
for(j;j{
if(s->ch[i]==ch1[j])
{
n=i;//记录相等的字符的位置
k++;//n,k两个变量来确定子串在主串中的位置,k用来记录遍历了多少个相等的字符
find=false;//为了退出该循环而设置的变量
xiangdeng=true;
}
else
{
j=-1;
d++;//用来记录遍历了多少个不相等的字符
find=false;
xiangdeng=false;
if(k!
=0)
{
i=n-k+1;
k=0;
}
}
}
if(j==m&&xiangdeng)//如果j==m则把替换的子串,复制到数组ch3中,并把子串之前的字符串也复制过去,这时候主串的遍历要从主串中该子串之后开始
{
for(inta1=f;a1{
ch3[p]=s->ch[a1];
p++;
}
for(intw=0;w{
ch3[p+w]=ch2[w];
}
p+=ch2length;
f=i+1;
j=0;
d=0;
k=0;
jinru=true;
}
}
for(inta1=f;a1{
ch3[p]=s->ch[a1];
p++;
}
ch3[p]='\0';
if(!
jinru)
{
cout<<"不存在子串"<}
else
{
cout<<"替换后的字符串为:
"<}
}
voidstrdelete()//串删除
{
HString*s;
cout<<"请输入你要删除的串的标识:
";
s=Chuanzhizhen();
if(s->ch)
{
free(s->ch);
}
s->ch=NULL;
s->length=0;
}
voidquit()//退出程序
{
cout<<"退出程序"<exit
(1);
}
函数的调用关系图(只列出部分)
四、调试分析
五、用户手册
1.本程序的运行环境为MicrosoftVisualc++
2.进入程序后,用户可根据文字提示进行操作,本程序有两种命令输入格式
3.本程序支持内部名操作,如在联接串的时候,可以先输入C,然后按提示输入内部名,即可完成操作。
或者可以直接输入C'hello''nicetomeetyou',结果串为'hellonicetomeetyou';其它的函数也可以进行类似操作。
5.本程序是命令解释程序,循环往复地处理用户键入的每一条指令,直至终止程序的命令为止(本程序退出指令为Q)。
六、测试结果
下面是运行程序的操作流程(从运行窗口复制的):
project.exe
注释:
上图为测试数据的运行效果图,可见运行结果正确。
1.比较串相等时,因为要比较的两个串都已存入串头表中。
因此,