赞
踩
*设置字符串、返回字符串长度和显示内容等功能。能对字符串进行插入、替换、删除、查找和连接等操作。
程序要求:串采用链式存储结构,串结点结构如下:
#define N 4
typedef struct Node
{
char data[N];
struct Node next;
} LianString;
实现(1)中所列的功能
如果链串中的最后一个结点中的字符不足N个,可用’#’补齐
(1)对字符串的操作采用下列菜单形式:
A. 生成字符串
B. 显 示
C. 求字符串长度
D. 字符串插入
E. 字符串替换
F. 字符串删除
G. 字符串查找
H. 字符串的连接
O. 返回
(2) 字符串的输出格式:ABCD->DEFG->123#∧ (当N=4时)
本系统设计了一个字符串类Str,将头结点以及相关操作封装进类里。具体实现了生成字符串,显示字符串,求字符串长度,查找字符串,连接字符串等功能。进入系统后,首先要求用户输入一串字符串以初始化(此时正在调用Str类的构造函数),初始化后进入主页面,用户可以选择对字符串的操作:
A. 重建字符串
B. 显示
C. 求字符串长度
D. 字符串插入
E. 字符串替换
F. 字符串删除
G. 字符串查找
H. 字符串连接
O. 返回
下面依次说明实现思路:
其内容与类的构造函数基本相同,使用getchar()函数,用户每输入一个字符就往结点中传入一个字符(采用头插法),直到用户按下回车键。
较为容易,即设置一工作结点p对链串扫描一遍,扫描过程中输出对应结点的值
类中设置了一个私有变量cnumber,用来存储链串的字符串长度,所以直接返回该值即可
字符串的插入较为麻烦,我采用了逐个输入字符的方式进行插入。首先用户输入要插入的结点数和第几个字符个数,然后通过getchar逐个获取字符,通过依次将结点字符后挪的方式插入,若结点字符需要挪到下一个结点的第一个字符处,采用设置两个char类型的变量暂存数值,并将指针指向下一个结点。依次实现字符串插入的功能。
在字符串的中,设置了两种不同的替换方式,一种是替换单个字符,即将字符串中所有的相同字符替换为其他字符,通过逐个查找的方式将需要选取的字符串挑选出来并赋新值,另一种是选取固定的字符串将其替换为需要替换的字符串。
在字符串的删除中,主要核心思想是算出需要删除的字符串长度,将后面暂时不需要删除的字符串替换到需要删除的字符串处,再把后面无用的字符串结点删掉。这也分两种情况,一种是需要删除的字符个数小于后面剩余的字符个数,另一种则是需要删除的字符个数大于后面剩余的字符个数。
首先通过动态分配内存,建立一个字符数组存入用户输入的字符串,接着定义两个int型变量i和j(初始值均为零),然后逐个向后匹配,若匹配过程中失败,则i回溯至i-j+1,j回溯至0,重新匹配,直到匹配成功或者匹配无法继续进行。
首先检验连接前的链串是否能被4整除,若能,则可以直接接着插入结点(类似于构造函数);若不能,则先在最后一个未填充完毕的结点上赋值,直到填充完毕,再插入新结点(类似于构造函数)
标志flag赋值为0,从而跳出do{} while(flag)的循环,程序结束
这一次的课设,我们选择了实现链串的基本功能,通过对题目的整体分析之后,我们决定首先写好菜单框架,然后按照系统功能模块分工编写代码,最后进行整合。在写的过程中,最为深刻的体会就是,结点内部结构的变化会给外部操作造成一定的困难。本次的每个结点内部可存放四个字符,若一个结点只存放一个字符,许多操作就只需要在结点层面上进行,而不用特殊考虑结点内部的元素。此外,在编程过程中,我主要下以下两个方面遇到了困难。第一是不会确定用户输入的字符串,后来温习了一下内存动态分配的知识以及getchar()函数,结合上网查阅资料,解决了这个问题。第二是getchar()函数的使用问题,起初我并不知道getchar()函数的具体的用法,通过这次课设我才了解到getchar()读取的是缓冲区的字符,并且会读入回车键及Tab键等不可见字符,这就在某些时候需要预先清空缓冲区,通过上网查阅资料,得知fflush(stdin)函数可以清空缓冲区,这解决了有时漏掉字符或因为读取到回车键而跳过while循环的问题。
链表在数据结构中是很基础内容,但同时又十分重要,通过这次课设我对链表的具体实现有了更加清晰的认识。
#include <iostream>
#include <cstring>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<Windows.h>
#include<mmsystem.h>
#pragma comment(lib,"winmm.Lib")
#define N 4
/*设置字符串、返回字符串长度和显示内容等功能。能对字符串进行插入、替换、删除、查找和连接等操作。*/
using namespace std;
typedef struct Node
{
char data[N];
struct Node *next;
}LianString;
class Str{
private:
Node *first;
Node *last;
int cnumber;//字符个数
int nnumber;//结点个数
public:
Str();//建立一个空串
// Str(char d[]);//d代表传入的字符串
~Str();
void newstr();
void PrintList();//显示
int length();
int insert();//插入(i为插入位置,n为字符串长度)
void replace();//替换(a为起始位置,b为终止位置,d[]为用户输入的字符串,n为字符串长度)
void del();//删除(a为起始位置,b为终止位置)
int locate();//查找 d[]为用户输入的字符串,n为字符串长度
void link();//连接(同类对象)
};
void Str::newstr(){
char c;
first = new Node;
first->next = NULL;
Node *p=first;
Node *s;
cnumber=0;
int j = 0;
cout<<"请输入字符串以初始化"<<endl;
fflush(stdin);
while( (c=getchar()) != '\n')//在没有敲回车的前提下进入while循环
{
j=cnumber%4;
if(j==0)
{
s = new Node;//生成结点
s->data[j]=c;
p->next=s;
p=s;
p->next=NULL;
}
else
{
s->data[j]=c;
}
cnumber++;
}
if(j==0)
{
for(int i=1;i<4;i++)
{
s->data[i]='#';
}
}
if(j==1)
{
for(int i=2;i<4;i++)
{
s->data[i]='#';
}
}
if(j==2)
{
for(int i=3;i<4;i++)
{
s->data[i]='#';
}
}
last=s;
//cout<<last->data;
}
int Str::locate(){
cout<<"请输入要查找的字符串"<<endl;
char buffer;
buffer=getc(stdin);
char *str1;
int sz = 1;
char *temp = (char *)malloc(sizeof(char));
while ((buffer = getc(stdin)) != '\n')
{
str1 = (char *)realloc(temp, ++sz*sizeof(char));
temp = str1;
str1[sz - 2] = buffer;
}
str1[sz-1] = '\0';
Node *p;
p=first->next;
int s=strlen(str1);
int i=0;
int j=0;
while(p!=NULL)
{
if(p->data[i%4]==str1[j])
{
if(j==s-1)//待匹配字符串到达终点
{
cout<<"查找成功!"<<endl
<<"匹配串的第一个字符位于第"<<(i-j)/4+1<<"个结点的第"<<(i-j)%4+1<<"个位置处"<<endl;;
break;
}
i++;
j++;
if(i%4==0)
{
p=p->next;
}
}
else
{
i=i-j+1;
if(i>cnumber-j-1)
{
cout<<"查找失败!"<<endl;
return 0;
}
j=0;
int m;
m=i/4;
p=first->next;
for(int n=0;n<m;n++)
{
p=p->next;
}
}
}
free(str1);
}
Str::~Str(){}
Str::Str(){
char c;
first = new Node;
first->next = NULL;
Node *p=first;
Node *s;
cnumber=0;
int j = 0;
cout<<"请输入字符串以初始化"<<endl;
while( (c=getchar()) != '\n') //在没有敲回车的前提下进入while循环
{
j=cnumber%4;
if(j==0)
{
s = new Node;//生成结点
s->data[j]=c;
p->next=s;
p=s;
p->next=NULL;
}
else
{
s->data[j]=c;
}
cnumber++;
}
if(j==0)
{
for(int i=1;i<4;i++)
{
s->data[i]='#';
}
}
if(j==1)
{
for(int i=2;i<4;i++)
{
s->data[i]='#';
}
}
if(j==2)
{
for(int i=3;i<4;i++)
{
s->data[i]='#';
}
}
last=s;
//cout<<last->data;
}
void Str::PrintList()
{
Node *p;
p=first->next;
while(p!=NULL)
{
for(int i=0;i<4;++i)
cout<<p->data[i];
if(p->next!=NULL)
cout<<"->";
p=p->next;
}
cout<<"∧";
}
int Str::length()
{
return cnumber;
}
int Str::insert()
{
int m;
int n;
int temp;
char c;
Node *p,*q;
Node *s;
cout<<"请输入插入的结点位置"<<endl;
cin>>m;
// int temp=this->length();
if(m>0)//C++中的this是指针不是对象 //判断结点位置是否正确
{
cout<<"请输入从结点内部第几个字符开始插入"<<endl;
cin>>n;
temp=n;
if(n>=1&&n<=4)
{
p=first->next;
/*for(int i=0;i<m;i++)
{
p=p->next;
}*/
q=p;
cout<<"请输入要插入的字符串"<<endl;
char y;
char z;
if(m>1){
for(int i=1;i<m;i++){
q=q->next;
y=q->data[n-1];
}
}
else
y=q->data[n-1];
/* cout<<"xxxxxxxxxxxxxxx"<<endl;
cout<<y<<endl;*/
fflush(stdin);
while( (c=getchar()) != '\n')//在没有敲回车的前提下进入while循环
{
if(cnumber%4!=0)
{ //如果最后一个结点长度小于4
q->data[n-1]=c;
while(q)
{
while(temp<4)
{
z=q->data[temp];
q->data[temp]=y;
y=z;
temp++;
}
q=q->next;
temp=0;
}
cnumber++;
}
else
{ //如果大于4,添加新结点
s=new Node;
s->next=NULL;
last->next=s;
last=s;
q->data[n-1]=c;
while(q)
{
while(temp<4)
{
z=q->data[temp];
q->data[temp]=y;
y=z;
temp++;
}
q=q->next;
temp=0;
}
cnumber++;
}
q=p; //插入下一个字符
n++;
if(n>=1&&n<=4){
for(int i=1;i<m;i++)
q=q->next;
y=q->data[n-1];
temp=n;
}
else{
m++;
for(int i=1;i<m;i++)
q=q->next;
y=q->data[0];
n=n%4;
temp=n;
}
}
cout<<"插入成功!"<<endl;
}
else{
cout<<"结点位置输入有误!"<<endl;
return 0;
}
}
else
{
cout<<"结点位置输入有误!"<<endl;
return 0;
}
/* cout<<"XXXXXXXXXXXXX"<<endl;
cout<<cnumber<<endl;*/
if((cnumber%4)!=0){
int x=cnumber%4;
if(x==3)
last->data[3]='#';
else if(x==2){
last->data[3]='#';
last->data[2]='#';
}
else if(x==1){
last->data[3]='#';
last->data[2]='#';
last->data[1]='#';
}
}
}
void Str::del(){
int x1,x2,y1,y2;
int xx=0,yy=0;
Node *p,*q,*s,*t,*h,*o;
p=first->next;
q=p;
s=p;
t=p;
h=p;
o=p;
cout<<"请输入删除初始结点位置:"<<endl;
cin>>x1;
cout<<"请输入删除的初始结点的第几个字符:"<<endl;
cin>>x2;
cout<<"请输入删除终止结点位置:"<<endl;
cin>>y1;
cout<<"请输入删除的终止结点的第几个字符:"<<endl;
cin>>y2;
//if(x1<=(cnumber%4+1) && x2>=1 && x2<=4 && y1<=(cnumber%4+1) && y2>=1 &&y2<=4){
int count=5-x2+y2+(y1-x1-1)*4;
int shengyu=cnumber-(y1-1)*4-y2;
/*cout<<count<<endl;
cout<<shengyu<<endl;*/
for(int i=1;i<x1;i++)//q和s分别指向要删除的开始和结束结点处
q=q->next;
for(int j=1;j<y1;j++)
s=s->next;
if(count>=shengyu){ //如果要删除的字符数大于后面紧挨的字符
int z1=((cnumber-(4*y1-(4-y2)))+(4*x1-(4-x2)-1))/4+1; //替换后剩余没有用的字符的结点数
int z2=((cnumber-(4*y1-(4-y2)))+(4*x1-(4-x2)-1))%4+1; //替换后剩余没有用的字符的结点位数
/*cout<<z1<<endl;
cout<<z2<<endl;*/
while(xx<shengyu){ //将要删除的字符用后面紧挨的字符替换掉
if(x2>4){
q =q->next;
x2=x2%4;
}
if(y2>=4){
s=s->next;
y2=y2%4;
}
q->data[x2-1]=s->data[y2];
x2++;y2++;
/* cout<<x2<<endl;
cout<<y2<<endl;*/
xx++;
}
for(int v=1;v<z1;v++)
h=h->next;
h->next=NULL;
last=h;
while(z2<5){
// cout<<z2<<endl;
h->data[z2-1]='#';
// cout<<"h->data["<<z2-1<<"]="<<h->data[z2-1]<<endl;
z2++;
}
cnumber=cnumber-count;
cout<<"删除成功!"<<endl;
}
else{ //如果要删除的字符数小于后面紧挨的字符
int z1=(cnumber-count)/4+1; //替换后剩余没有用的字符的结点数
int z2=(cnumber-count)%4+1; //替换后剩余没有用的字符的结点位数
cout<<z1<<endl;
cout<<z2<<endl;
while(yy<shengyu){
if(x2>4){
q =q->next;
x2=x2%4;
}
if(y2>=4){
s=s->next;
y2=y2%4;
}
q->data[x2-1]=s->data[y2];
// cout<<"q->data["<<x2-1<<"]="<<q->data[x2-1]<<endl;
x2++;
y2++;
yy++;
}
for(int v=1;v<z1;v++)
o=o->next;
o->next=NULL;
last=o;
while(z2<5){
// cout<<z2<<endl;
o->data[z2-1]='#';
//cout<<"o->data["<<z2-1<<"]="<<o->data[z2-1]<<endl;
z2++;
}
cnumber=cnumber-count;
cout<<"删除成功!"<<endl;
}
}
void Str::replace(){
Node *p,*q;
p=first->next;
q=p;
int x1,x2,y1,y2;
cout<<"请输入你要替换字符串还是单个字符(输入0为单个字符 ,否则为字符串)"<<endl;
char a,x,y;
cin>>a;
if(a=='0'){
cout<<"请输入要替换的字符"<<endl;
cin>>x;
cout<<"请输入替换的字符"<<endl;
cin>>y;
int i=0;
while(q){
if(q->data[i]==x)
q->data[i]=y;
i++;
if(i>=4){
q=q->next;
i=i%4;
}
}
cout<<"替换成功!"<<endl;
}
else{
cout<<"请输入要替换的字符串的起始位置的结点"<<endl;
cin>>x1;
cout<<"请输入要替换的字符串的起始位置的第几个字符"<<endl;
cin>>x2;
cout<<"请输入要替换的字符串的终止位置的结点"<<endl;
cin>>y1;
cout<<"请输入要替换的字符串的终止位置的第几个字符"<<endl;
cin>>y2;
cout<<"请输入想要替换的字符串"<<endl;
int a=y1*4-(4-y2)-(x1*4-(4-x2))+1;
cout<<"您需要输入"<<a<<"个字符"<<endl;
getchar();
char x=getchar();
for(int i=1;i<x1;i++)
q=q->next;
for(int j=0;j<a;j++){
q->data[x2-1]=x;
x2++;
if(x2>4){
q=q->next;
x2=x2%4;
}
x=getchar();
}
}
cout<<"替换成功!"<<endl;
}
void Str::link()
{
Node *p;
Node *s;
char c;
p=last;
int j = 0;
// cout<<cnumber;
fflush(stdin);
if(cnumber%4==0)
{
while( (c=getchar()) != '\n')
{
j=cnumber%4;
if(j==0)
{
s = new Node;//生成结点
s->data[j]=c;
p->next=s;
p=s;
p->next=NULL;
}
else
{
s->data[j]=c;
}
cnumber++;
}
if(j==0)
{
for(int i=1;i<4;i++)
{
s->data[i]='#';
}
}
if(j==1)
{
for(int i=2;i<4;i++)
{
s->data[i]='#';
}
}
if(j==2)
{
for(int i=3;i<4;i++)
{
s->data[i]='#';
}
}
last=s;
}
else //即不满足之前的元素刚好填满
{
int i;
if(cnumber%4==1)
{
i=1;
while((c=getchar())!='\n')
{
p->data[i]=c;
i++;
cnumber++;
if(i>=4)
break;
}
}
else if(cnumber%4==2)
{
i=2;
while((c=getchar())!='\n')
{
p->data[i]=c;
i++;
cnumber++;
if(i>=4)
break;
}
}
else if(cnumber%4==3)
{
i=3;
while((c=getchar())!='\n')
{
p->data[i]=c;
i++;
cnumber++;
if(i>=4)
break;
}
}
if(c!='\n')
{
while( (c=getchar()) != '\n')
{
j=cnumber%4;
if(j==0)
{
s = new Node;//生成结点
s->data[j]=c;
p->next=s;
p=s;
p->next=NULL;
}
else
{
s->data[j]=c;
}
cnumber++;
}
if(j==0)
{
for(int i=1;i<4;i++)
{
s->data[i]='#';
}
}
if(j==1)
{
for(int i=2;i<4;i++)
{
s->data[i]='#';
}
}
if(j==2)
{
for(int i=3;i<4;i++)
{
s->data[i]='#';
}
}
last=s;
}
}
cout<<"链接成功!"<<endl;
}
int main()
{
//PlaySound(".\\我的一个道姑朋友.wav",NULL,SND_ASYNC |SND_NODEFAULT); //播放音乐
Str str;
str.PrintList();
int flag=1;
do
{
char choice;
printf("\n\n---------------------\n");
printf("A.重建字符串.\n");
printf("B.显 示.\n");
printf("C.求字符串长度.\n");
printf("D.字符串插入.\n");
printf("E.字符串替换.\n");
printf("F.字符串删除.\n");
printf("G.字符串查找.\n");
printf("H.字符串的连接.\n");
printf("O.返回.\n");
printf("---------------------\n\n");
printf("请选择你要的操作:");
cin>>choice;
switch(choice)
{
case 'A':
{
str.newstr();
}
break;
case 'B':
printf("该字符串为:");
str.PrintList();
printf("\n");
break;
case 'C':
printf("\n该字符串的长度为:");
cout<<str.length();
printf("\n");
break;
case 'D':
// printf("\n请输入要插入的字符串:");//加上请输入要插入的字符串在哪个节点之后
str.insert();
printf("\n");
break;
case 'E':
// printf("\n请输入要替换的字符串.\n");//加上请输入要将新的字符串插入到哪个节点中
str.replace();
break;
case 'F':
{
//printf("请输入要删除的节点的位置.\n");
str.del();
break;
}
case 'G':
str.locate();
break;
case 'H':
printf("请输入待连接的字符串.\n");
str.link();
break;
case 'O':
flag=0;
break;
default:
break;
}
system("pause");
} while(flag);
return 0;
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。