字符串的顺序存储—C++实现
字符串的实现先对于之前的线性表难度有很大提高,但顺序存储的容器依然是数组。必须有两个内置的变量:一个存储字符串的数组 、一个显示数组长度的变量
顺序存储的操作如下:
- 对数组初始化,为其赋值
- 遍历输出数组元素
- 获取数组的长度
- 从数组中元素i开始,删除长度为j的子串(i为子串的首元素),返回剩下的字符串
- 将一个字符串中的所有元素拷贝到另一个字符串数组中
- 判断两个字符串是否相等
- 链接两个字符串
- 获取数组中第i个元素开始,长度为j的子串
- 在字符串第i个位置,插入一个子串,返回插入子串后的字符串
- 将数组中的第i个元素开始,长度为j的子串,替换成指定字符串t
头文件如下:
#pragma once
//字符串的顺序存储依靠数组实现,那它就一定要有两个内置元素
//①用于存放字符串常量的容器(数组) ②记录字符串长度的变量
#include<iostream>
using namespace std;
#define MAXSIZE 20
class SqString
{
public:
SqString();
void Assign(char s[]);
void Show();
int Getlength();
SqString Delete(int i, int j);
void Copy(SqString s);
bool Issame(SqString s);
SqString Concat(SqString s);
SqString Getsub(int i, int j);
SqString InsStr(int i, SqString t);
SqString RepStr(int i, int j, SqString t);
private:
char str[MAXSIZE];//*自定义数组的最大容量
int length;
};
具体实现如下:
#include<iostream>
#include"字符串.h"
using namespace std;
SqString::SqString()
{
length = 0;
}
void SqString::Assign(char s[])//为自定义的字符串类赋初值,传入一个字符串数组
{
for (int i = 0; s[i] != '\0'; i++)//这里注意:要找到传入的字符串数组中的最后一个元素
{
str[i] = s[i];
length++;//别忘了累加长度
}
}
void SqString::Show()
{
for (int i = 0; i < length; i++)
{
cout << str[i] << " ";
}
cout << endl;
}
int SqString::Getlength()
{
return length;
}
SqString SqString::Delete(int i, int j)//从元素i开始,删除长度为j的子串,返回剩下的字符串
{
SqString temp;
if (i < 0 || i>length || j<0 || i - 1 + j>length)
{
//这里i-1是为了取该元素的索引值下标,若下标加j大于length,条件就不满足
//本例中,例如i=11,j=1,也是满足条件的==》取出最后一个元素k
cout << "输入不合法" << endl;
return temp;//返回空串
}
else//假设输入合法的话
{
int k;
for (k = 0; k < i - 1; k++)//从元素i开始(下标为i-1),包括它自身
{
temp.str[k] = str[k];//前边元素不变,保存到temp字符串数组中
}
for (k; k + j < length; k++)
{
temp.str[k] = str[k + j];//忽略k~k+j中的这j个元素
}
temp.length = length - j;//注意长度别忘了更新
return temp;
}
}
void SqString::Copy(SqString s)//将一个字符串数组中的元素代替原来数组中的相应元素
{
for (int i = 0; i < s.length; i++)
{
str[i] = s.str[i];
}
length = s.length;//写这句话两个字符串就变等长了
}
bool SqString::Issame(SqString s)//判断两个字符串是否相等
{
//①判断长度是否相等
if (length != s.length)
return false;
else//②长度相等时,判断每个位置上的元素是否相等
{
for (int i = 0; i < length; i++)
{
if (str[i] != s.str[i])
return false;
else return true;
}
}
}
SqString SqString::Concat(SqString s)//链接两个字符串,首尾相连
{
SqString temp;
int i, j;
for ( i = 0; i < length; i++)
{
temp.str[i] = str[i];
}
for ( j=0; j < s.length; j++)
{
temp.str[i+j] = s.str[j];//开始链接
}
temp.length = length + s.length;//别忘了更新长度
return temp;
}
SqString SqString::Getsub(int i, int j)//找到从位置i开始,长度为j的子串,并返回
{
SqString temp;
if (i<0 || i>length || j<0 || i - 1 + j>length)
return temp;
else
{
for (int k=0;k<j;k++)
{
temp.str[k] = str[i - 1 + k];
temp.length++;
}
return temp;
}
}
SqString SqString::InsStr(int i, SqString t)//将串t插入到原串第i个字符后,返回新串
{
SqString temp;//创建一个空串
if (i<0 || i>length)
return temp;//输入不合法,返回空串
else
{
int k;
for (k = 0; k < i; k++)//i前面的元素与原串相同
{
temp.str[k] = str[k];
}
for (k; k < i + t.length; k++)//从元素i开始找出长度为j的位置,用子串t对它赋值
{
temp.str[k] = t.str[k-i];
}
for (k; k < length + t.length; k++)
//从第i+j的位置开始,后面的元素与原串中i后的元素相同
{
temp.str[k] = str[k - t.length];
}
temp.length = length + t.length;//**别忘了更新长度
return temp;
}
}
SqString SqString::RepStr(int i, int j, SqString t)
//将串中第i个元素开始,长度为j的字符串,用子串t代替
{
SqString temp;
if (i<0 || i>length || j<0 || i - 1 + j>length)
return temp;
else
{
if (t.length == j)
{
int k;
for (k = 0; k < i - 1; k++)
{
temp.str[k] = str[k];
}
for (k; k < i - 1 + j; k++)
{
temp.str[k] = t.str[k - i + 1];
}
for (k; k < length; k++)
{
temp.str[k] = str[k];
}
temp.length = length;
return temp;
}
else//这里的条件是子串的长度小于j,填不满空余位置
{
int k;
for (k = 0; k < i - 1; k++)
{
temp.str[k] = str[k];
}
for (k; k < i - 1 + t.length; k++)
{
temp.str[k] = t.str[k - i + 1];
}
for (k; k < length - j + t.length; k++)
{
temp.str[k] = str[k + j - t.length];
}
temp.length = length + t.length - j;
return temp;
}
}
}
int main()
{
SqString ss;//实例化一个字符串类型
char temp[] = { "abcdefghijk" };
ss.Assign(temp);
ss.Show();
cout << "ss字符串的长度为:" << ss.Getlength() << endl;
cout << "-----------------------" << endl;
ss.Delete(4, 3);//从第4个元素开始,删除长度为3的子串即第4、5、6个元素,下标为3、4、5
SqString ss2 = ss.Delete(5, 3);//将efg删掉
ss2.Show();
cout << "ss2字符串的长度为:" << ss2.Getlength() << endl;
cout << "-----------------------" << endl;
ss.Copy(ss2);
ss.Show();
cout << "拷贝后ss字符串的长度为:" << ss.Getlength() << endl;
cout << "-----------------------" << endl;
bool ret = ss.Issame(ss2);
if (ret)
cout << "两个字符串相等" << endl;
else cout << "两个字符串不等" << endl;
cout << "-----------------------" << endl;
SqString s = ss.Concat(ss2);
cout << "链接后的字符串为:" << endl;
s.Show();
cout << "链接后s字符串的长度为:" << s.Getlength() << endl;
cout << "-----------------------" << endl;
cout << "原串为:" << endl;
ss.Show();
SqString sde=ss.Getsub(5, 3);
cout << "返回的子串为:" << endl;
sde.Show();
cout << "子串的长度为:" << sde.Getlength() << endl;
cout << "-----------------------" << endl;
cout << "原串为:" << endl;
ss.Show();
SqString sde2=ss.InsStr(5,sde);//sde为“hij”
sde2.Show();
cout << "插入子串的新字符串长度为:" << sde2.Getlength() << endl;
cout << "-----------------------" << endl;
cout << "原串为:" << endl;
ss.Show();
SqString zichuan;
char abe[] = { "shuang" };
zichuan.Assign(abe);
cout << "子串为:" << endl;
zichuan.Show();
SqString sde3 = ss.RepStr(4,3, zichuan);//sde为“hij”
cout << "替换后的字符串为:" << endl;
sde3.Show();
}
输出结构如下:
删除子串这些操作有套路可循,理顺了就不难了~