【数据结构 严蔚敏版】 串的定长分配存储 基本操作
2018-12-22 22:02
543 查看
定长顺序存储表示法
存储结构:
使用字符串数组作为存储,定义字符串数组长度为MAXSTRLEN+1(0位置用来存放字符串长度)
操作方法:
字符串赋值
通过将控制台输入的字符串赋值给串S1(从1开始存储),如果字符串长度超过限制,则截取越界前的数据存入。S1[0]位置存放字符串长度
字符串拷贝
对字符串遍历逐个拷贝(判断长度,仅拷贝长度范围内的)
字符串判空
判断字符串0位置是否为0
返回字符串长度
返回字符串0位置的值
打印字符串
在字符串长度范围内遍历并打印
清空字符串
字符串长度S[0]置为0
字符串联接
判断联接的两个字符串长度之和,如果长度之和在界限范围内,则字符串2接到字符串1后。
如果长度之和超过界限,进行截断。先存入字符串1,字符串1存入剩下的位置存字符串2。(如果字符串1本身就是界限长度,则留给字符串2的位置为空,不存入字符串2)
索引子串位置
定义两个临时变量 i 和 j 存放指向子串和主串的位置。操作如图所示
插入子串
如果插入子串长度会越界,则把原来的尾部挤出字符串范围,先从字符串尾部开始遍历后挪,当控制要插入的位置后将要插入的子串赋值给空位。
删除子串
判断输入的位置和长度,将删除的字符串后面的字符往前挪。
————————————————————————————————————————————
//文件名:串操作----定长分配存储实现 //描述:类似于线性表中的顺序存储结构,用一组地址连续的存储单元存储串值的字符序列。在串的定长分配存储结构中,按照预定义的大小,给每个串变量分配一个固定长度的存储区. //时间:11.18 //作者:知非2320417326 #include<iostream> #include<stdlib.h> #include<string.h> #include<stdio.h> using namespace std; #define True 1 #define False 0 #define Ok 1 #define Error 0 #define MaxSize 255 //用户可以在255内定义最大串长 typedef char SString[MaxSize+1];//0号单元存储该串的长度 typedef int Status; Status StrAssign(SString &T,char *chars);//生成一个其值等于chars的串T Status StrCopy(SString T,SString &S);//串的复制 bool StrEmpty(SString S);//判断是否为空 int StrCompare(SString S,SString T);//串的比较:若S>T,则返回值>0,若S=T,则返回值=0;若S<T,则返回值<0 int StrLength(SString S);//求串长 Status ClearString(SString &S);//清空 Status Concat(SString &T,SString S1,SString S2);//连接串:用T返回一个有S1,S2连接而成的新的串 Status SubString(SString &Sub,SString S,int pos,int len);//用Sub返回串S的第 pos 个字符起长度为 len 的子串 int Index(SString S,SString T,int pos);//若主串S中存在和串S中T值相同的子串,则返回他在主串S中第 pos 个字符之后第一次出现的位置,否则函数值·为0 Status Replace(SString S,SString T,SString V); //用 V 来替换主串中出现的所有与T相等的不重叠的子串 Status StrInsert(SString S,int pos,SString T);//在串S的第 Pos 个字符前插入串T,完全插入返回TRUE,部分插入返回FALSE Status StrDelete(SString S,int pos,int len);//冲串S中删除第 pos 个字符长度为 len 的子串。 void StrPrint(SString T); Status SStringCmp(SString T,SString S); //生成一个其值等于chars的串T Status StrAssign(SString &T,char *chars){ int i; if(strlen(chars)>MaxSize){//是否越界 return Error; } else{ T[0]=strlen(chars);// for(i=1;i<=T[0];i++) T[i]=*(chars+i-1); return Ok; } } //串的复制 Status StrCopy(SString T,SString &S){ int i = 0; while(T[i] !='\0'){ S[i] = T[i]; i++; } S[i+1] ='\0'; return Ok; } //判断是否为空 bool StrEmpty(SString S){ return (S[0]==0?True:False); } //串的比较:若S>T,则返回值>0,若S=T,则返回值=0;若S<T,则返回值<0 int StrCompare(SString S,SString T){ return S[0]/2-T[0]/2; } //求串长 int StrLength(SString S){ return S[0]/2; } //清空串 Status ClearString(SString &S){ S[0]=0; S[1]='\0'; return Ok; } //连接串:用T返回一个有S1,S2连接而成的新的串 Status Concat(SString &T,SString S1,SString S2){ int i,uncut; if(S1[0]+S2[0] <= MaxSize){//未截断 for(i=1;i<=S1[0];i++) T[i]=S1[i];//书上算法4.2,T[1..S1[0]] = S1[1..S1[0]] for(i=1;i<=S2[0];i++) T[S1[0]+i]=S2[i];//书上算法4.2,T[S1[0]+1..S1[0]+S2[0]] = S2[1..S2[0]] T[0]=S1[0]+S2[0]; uncut = True; } else if(S1[0] < MaxSize){//截断 for(i=1;i<=S1[0];i++) T[i]=S1[i];//书上算法4.2,T[1..S1[0]] = S1[1..S1[0]] for(i=1;i<=MaxSize-S1[0];i++) T[S1[0]+i]=S2[i];//书上算法4.2,T[S1[0]+1..MaxSize = S2[1..MaxSize- S1[0]] T[0]=MaxSize; uncut = False; } else{//仅仅取S1 for(i=0;i<=MaxSize;i++) T[i]=S1[i];//书上算法4.2,T[1..MaxSize = S1[1..MzxSize] uncut = False; } return uncut; } //用Sub返回串S的第 pos 个字符起长度为 len 的子串 //Status SubString(SString &Sub,SString S,int pos,int len) //{ // int i; // if(pos<1||pos>S[0]||len<0||len>S[0]-pos+1) // return Error; // for(i=1;i<=len;i++) // Sub[i]=S[pos+i-1];//shushang算法4.3 SUB[1..len] = S[pos..pos+len-1] // Sub[0]=len; // return Ok; //} Status SubString(SString &Sub,SString S,int pos,int len) { int i; if(pos<1||pos>S[0]||len<0||len>S[0]-pos+1) return Error; for(i=1;i<=len*2;i++) Sub[i]=S[pos*2-1+i-1];//shushang算法4.3 SUB[1..len] = S[pos..pos+len-1] Sub[0]=len*2; return Ok; } //若主串S中存在和串S中T值相同的子串,则返回他在主串S中第 pos 个字符之后第一次出现的位置,否则函数值·为0 int Index(SString S,SString T,int pos){ SString su[6]; int i,t=0; if(pos > 0) i = pos; for(i=pos;t<=0;i++){ SubString(su[i],S,i,T[0]/2); t =SStringCmp(su[i],T); } if(i>0){ return i-1; } return i; return 0;//S中不存在与T相等的子串 } Status SStringCmp(SString T,SString S){ int i; for(i=0;i<=T[0]/2||i<=S[0]/2;){ if(T[i]==S[i]) i++; else return Error; } return Ok; } //用 V 来替换主串中出现的所有与T相等的不重叠的子串 //Status Replace(SString S,SString T,SString V) //{ // int i=1,k; // 从串S的第一个字符起查找串T // if(StrEmpty(T)) // T是空串 // return Error; // do // { // i=Index(S,T,i); // 结果i为从上一个i之后找到的子串T的位置 // if(i) // 串S中存在串T // { // StrDelete(S,i,StrLength(T)); // 删除该串T // k=StrInsert(S,i,V); // 在原串T的位置插入串V // if(!k) // 不能完全插入 // return Error; // i+=StrLength(V); // 在插入的串V后面继续查找串T // } // }while(i); // return Ok; //} Status Replace(SString S,SString T,SString V) { int i=1,m,k,n,j=0; // 从串S的第一个字符起查找串T j=StrLength(V); if(StrEmpty(T)) // T是空串 return Error; else{ m=Index(S,T,1); n = m; for(i=m*2-1,k=1;i<n*2-1+j*2;k++,i++){ S[i]=V[k]; } S[0]=S[0]; } return Ok; } //在串S的第 Pos 个字符前插入串T,完全插入返回TRUE,部分插入返回FALSE Status StrInsert(SString S,int pos,SString T) { int i,j,k,m,e; SString s; StrCopy(S,s); if(pos<1||pos>S[0]+1) return Error; pos = pos -1; j = pos*2+1;//插入的起始值 k = j+StrLength(T)*2;//将原字符串挪到后面的起始值 if(S[0]+T[0]<=MaxSize) { // 完全插入 for(j;k<StrLength(S)*2+StrLength(T)*2+1;j++,k++){ S[k]=s[j]; } for(i=pos*2+1,m=1;m<=StrLength(T)*2;i++,m++) S[i]=T[m]; S[0]+=T[0]; return True; } else { // 部分插入 for(i=MaxSize;i>=pos+T[0];i--) S[i]=S[i-T[0]]; for(i=pos;i<pos+T[0]&&i<=MaxSize;i++) S[i]=T[i-pos+1]; S[0]=MaxSize; return False; } } //冲串S中删除第 pos 个字符长度为 len 的子串。 Status StrDelete(SString S,int pos,int len) { int i,j,k; SString s; StrCopy(S,s); j = pos*2-1;//插入的起始值 k = j+len*2;//将原字符串挪到后面的起始值 if(pos<1||pos>S[0]-len+1||len<0) return Error; for(j;s[k]!='\0';j++,k++) S[j]=s[k]; S[0]=S[0]-len*2; return Ok; } void StrPrint(SString T) { // 输出字符串T。另加 int i; for(i=1;i<=T[0];i++) cout<<T[i]; cout<<endl; } //销毁 //菜单 void Menu() { cout<<" 串 操作 "<<endl; cout<<" 1710252291 知非0802 "<<endl; cout<<"**************************************************************************"<<endl; cout<<"**************************************************************************"<<endl; cout<<"********* 功能列表 *********"<<endl; cout<<"********* 1.生成一个串T *********"<<endl; cout<<"********* 2.复制该串给B *********"<<endl; cout<<"********* 3.判断T是否为空串 *********"<<endl; cout<<"********* 4.将 T 与 S 进行比较 *********"<<endl; cout<<"********* 5. T 和 S 里面有多少个元素 *********"<<endl; cout<<"********* 6.连接串S 和 T 赋值给新串 T1 *********"<<endl; cout<<"********* 7.用 Sub 返回串T1的第pos个字符起长度为 len 的子串*******"<<endl; cout<<"********* 8.判断T1中是否存在子串T2 *********"<<endl; cout<<"********* 9. 用 T3 替换T1 中出现的与 T2 相等的子串 *********"<<endl; cout<<"********* 10. 在串 T1 中第 pos 个字符前插入串 T4 *********"<<endl; cout<<"********* 11.从 T1 中删除第 pos 个字符长度为 len 的子串 *********"<<endl; cout<<"********* 12.退出 (自动清空串) *********"<<endl; cout<<"**************************************************************************"<<endl; cout<<"**************************************************************************"<<endl; } //主函数 int main(){ int i=0; SString T,T1,Sub,B,S,T2,T3,T4; char T22[]="周旋久"; char T33[]="思良久"; char T44[]="我爱干什么干什么自负盈亏" ; char chars[]="我与我周旋久宁做我"; char s[]="我要有做我自己的自由和敢于做我自己的胆量"; StrAssign(T2,T22); StrAssign(T3,T33); StrAssign(T4,T44); StrAssign(S,s); Menu(); do { i++; switch(i){ case 1:{ cout<<"第 1 项:"<<"生成一个其值等于chars的串T"<<endl; cout<<"chars的初始值为:"; puts(chars); cout<<"操作结果为:"; if (!StrAssign(T,chars)) cout<<"越界!"<<endl; else{ cout<<"成功!现在的 T 是: "; StrPrint(T); } cout<<"\n\n\n"; break; } case 2:{ cout<<"第 2 项:"<<"复制该串T给B "<<endl; cout<<"T的初始值为:"; StrPrint(T); cout<<"操作结果为:"; if (!StrCopy(T,B)) cout<<"失败!"<<endl; else{ cout<<"复制成功!现在的 B 是:"; StrPrint(B); } cout<<"\n\n\n"; break; } case 3:{ cout<<"第 3 项:"<<"判断T是否为空 "<<endl; cout<<"T的初始值为:"; StrPrint(T); cout<<"操作结果为:"; if (!StrEmpty(T)) cout<<"T不是空!"<<endl; else{ cout<<"T是空"; } cout<<"\n\n\n"; break; } case 4:{ cout<<"第 4 项:"<<"将 T 与 S 进行比较 "<<endl; cout<<"T的初始值为:"; StrPrint(T); cout<<"S的初始值为:"; StrPrint(S); cout<<"操作结果为: "; if (StrCompare(S,T)>0) cout<<"S比T长"<<endl; else if(StrCompare(S,T)<0) cout<<"T比S长"<<endl; else cout<<"二者一样长"<<endl; cout<<"\n\n\n"; break; } case 5:{ cout<<"第 5 项:"<<"T 和 S 里面有多少个元素 "<<endl; cout<<"T:"<<endl; StrPrint(T); cout<<"T里面有"<<StrLength(T)<<"个元素!"<<endl; cout<<"S:"<<endl; StrPrint(S); cout<<"S里面有"<<StrLength(S)<<"个元素!"<<endl; cout<<"\n\n\n"; break; } case 6:{ cout<<"第 6 项:"<<"连接串S 和 T 赋值给新串 T1 "<<endl; cout<<"T的初始值为:"; StrPrint(T); cout<<"S的初始值为:"; StrPrint(S); Concat(T1,T,S); cout<<"操作结果为:"; if(Concat(T1,T,S)) cout<<"未截断"<<endl; else cout<<"截断"<<endl; StrPrint(T1); cout<<"\n\n\n"; break; } case 7:{ cout<<"第 7 项:"<<"用 Sub 返回串T1的第pos个字符起长度为 len 的子串"<<endl; cout<<"在这里我设定 pos 的值为10,len的值为20"<<endl; cout<<"T1的初始值为:"; StrPrint(T1); SubString(Sub,T1,10,20); cout<<"操作结果为:"; StrPrint(Sub); cout<<"\n\n\n"; break; } case 8:{ cout<<"第 8 项:"<<"判断T1中是否存在子串T2 "<<endl; cout<<"在这里我设定 pos 的值为1"<<endl; cout<<"T1的初始值为:"; StrPrint(T1); cout<<"T2的初始值为:"; StrPrint(T2); cout<<"操作结果为:"; if(Index(T1,T2,1)>0) cout<<"T2在T1里第一次出现的位置是:"<<Index(T1,T2,1)<<endl; else cout<<"不存在"<<endl; cout<<"\n\n\n"; break; } case 9:{ cout<<"第 9 项:"<<"用 T3 替换T1 中出现的与 T2 相等的子串 "<<endl; cout<<"T1的初始值为:"; StrPrint(T1); cout<<"T2的初始值为:"; StrPrint(T2); cout<<"T3的初始值为:"; StrPrint(T3); cout<<"操作结果为:"; Replace(T1,T2,T3); StrPrint(T1); cout<<"\n\n\n"; break; } case 10:{ cout<<"第 10 项:"<<"在串 T1 中第 pos 个字符前插入串 T4 "<<endl; cout<<"在这里我设定 pos 的值为10"<<endl; cout<<"T1的初始值为:"; StrPrint(T1); cout<<"T4的初始值为:"; StrPrint(T4); cout<<"操作结果为:"; StrInsert(T1,10,T4); StrPrint(T1); cout<<"\n\n\n"; break; } case 11:{ cout<<"第 11 项:"<<"从 T1 中删除第 pos 个字符长度为 len 的子串"<<endl; cout<<"在这里我设定 pos 的值为10 len得值为12"<<endl; cout<<"T1的初始值为:"; StrPrint(T1); StrDelete(T1,10,12); cout<<"操作结果为:"; StrPrint(T1); cout<<"\n\n\n"; break; } case 12:{ ClearString(T1); ClearString(T2); ClearString(T3); ClearString(T4); ClearString(Sub); cout<<"销毁成功,退出!!!"; return 0; } default: { cout << "没有该选项,请重新选择。" << endl; break; } } }while(1); return 0; }
相关文章推荐
- 数据结构之无向图基本操作(采用邻接矩阵存储)—整理严蔚敏数据结构
- 数据结构:字符串的堆分配存储结构,基本操作实现和测试。
- 串操作——定长顺序存储,堆分配存储,模式匹配(KMP)
- 数据结构_线性表_链式存储_双向循环链表的基本操作
- C语言-单链表的基本操作-严蔚敏版的数据结构
- 数据结构(7)——串的堆分配的基本操作
- PHP数据结构之七_队列的链式存储和队列的基本操作
- 【数据结构 严蔚敏版】 矩阵转置 基本操作
- 数据结构_线性表_链式存储_单链表 的基本操作
- 重学数据结构003——栈的基本操作及实现(链式存储)
- 《数据结构》严蔚敏版(java解)——第二章 线性表01 基本操作
- 严蔚敏数据结构单链表的所有基本操作
- C语言数据结构二叉树的顺序存储基本操作
- 数据结构_图_定义/分类/顶点与边之间的关系/连通图/存储结构/基本操作
- [数据结构][C语言]图的基本介绍和操作实现之图的存储结构
- 字符串的基本操作--基于堆分配存储
- 【数据结构 严蔚敏版】 排序基本操作
- 数据结构 串(顺序存储)的基本操作
- 堆分配存储表示的串其基本操作的实现
- 数据结构之广义表(头尾链表存储)基本操作