您的位置:首页 > 理论基础 > 数据结构算法

【数据结构 严蔚敏版】 串的定长分配存储 基本操作

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: