hstring就是自己创建一个字符串操作类,实现对字符串的增删改查,而不是调用string类。总体考察了类的使用,缓冲区考察了指针和数组的使用、增删改查、考察编码思维、考察了类的重载。
完整代码在最下面
要求:
- 1.设置缓冲区: 存储数据的时候使用缓冲区。
- 2.重载
+
运算符: 增加数据,即 “123456789” + “abc” 得到 “123456789abc” (最多new一次) - 3.重载
-
运算符: 删除数据,增加数据要实现的形态:”123456789” - “456” 得到 “123789” (函数中不使用new) - 4.修改数据: 即 “123456789” 将34修改为 abc 得到 12abc56789 (最多new一次)
- 5.查找数据: 即查找123456中的34,并得到34的起始位置2(不使用new)
- 6.重载
=
运算符: 实现 int 转 hstring 字符串 (最多new一次) - 7.不能使用库函数(只可使用memcpy,remove,memset)
①重载+
运算符
思路:
1.首先判断缓冲区和另一个hstring
是否为空,有一方为空则返回另一方。
2.如都不为空,则分别获取双方的字符串长度(用循环),然后new
一个char* result
来存储结果
3.使用memcpy
分别把两个字符串复制给result
4.最后返回hstring(result)
,这样让hstring
来管理result
,实现自动释放内存
//重载+运算符
hstring operator+(const hstring& x) const{
//如果有一方字符串为空,则返回另一方字符串
if(buffer==NULL){
return hstring(x.buffer);
}else if(x.buffer==NULL){
return *this;
}
//如果双方都不空
//获取buffer的字符长度
int buffer_length=0;
while(buffer[buffer_length]!='\0'){
++buffer_length;
}
//获取x的字符长度
int x_length=0;
while(x.buffer[x_length]!='\0'){
++x_length;
}
int result_length=buffer_length+x_length;//结果的长度
//创建一个result用来存储结果,给缓冲区分配内存,因为有'\0'所以+1
char* result=new char[result_length+1];
memcpy(result,buffer,buffer_length);//复制第一个字符串
memcpy(result+buffer_length,x.buffer,x_length+1);//复制第二个字符串
return hstring(result);//让char指针接受hstring的管理,自动释放指针
}
②重载-
运算符
思路:
1.若-
右边的字符串为空,则输出原来的字符串
2.若-
右边的字符串不为空,则分别获取母串和子串的长度(用循环),然后创建一个固定大小的数组temp_buffer
来临时储存
3.创建一个index
来记录写入temp_buffer
的位置
4.遍历两个hstring
进行匹配,若匹配则跳过写入temp_buffer
,若不匹配则写入temp_buffer
5.最后用memset
把原buffer
重置,再用memcpy
把临时缓冲区的数据写入buffer
,返回*this
//重载-运算符
hstring operator-(const hstring& x) const{
//如果-右边的字符串为NULL,则输出原来的字符串
if(x.buffer==NULL||buffer==NULL){
return *this;
}
int x_length=0;//要删除的子串的长度
while(x.buffer[x_length]!='\0'){
++x_length;
}
int buffer_length=0;//获取buffer的字符长度
while(buffer[buffer_length]!='\0'){
++buffer_length;
}
char temp_buffer[buffer_length + 1]={0}; // 使用固定大小的数组
int index = 0; // 用于记录写入temp_buffer的位置
int j=0;
for(int i = 0; i < buffer_length;i++) {
for(j; j < x_length; ++j) {
if(buffer[i]!=x.buffer[j]) {
temp_buffer[index++] = buffer[i];
break;
}else{
++j;
break;
}
}
}
temp_buffer[index] = '\0'; // 添加结束符
memset(buffer,0,sizeof(buffer));//重置buffer
memcpy(buffer,temp_buffer,index);//把临时缓冲区数据复制给buffer
return *this;
}
③修改数据
思路:
1.如果oldHstring
为空,返回原值;如果newHstring
为空,则提示输入newHstring
2.如果参数合理,获取buffer
、oldHstring
和newHstring
的长度
3.new
一个result
存储结果,长度是:buffer
的长度减去oldHstring
的长度加上newHstring
的长度+1
,因为有'\0'
4.查找oldHstring
在buffer
中的起始位置
5.用memcpy
把oldHstring
起始位置前的内容复制到result
,然后把newHstring
复制到result
,再把oldHstring
中buffer_length - pos - old_length
位置之后之后内容复制到result
6.最后用memset
把原缓冲区buffer
重置,把结果result
赋值给buffer
,这样就实现了在原数据上进行修改
const hstring& setHstring(const char* oldHstring,const hstring& newHstring){
//如果oldHstring为空,返回原值
if(oldHstring==NULL||buffer==NULL){
return *this;
}else if(newHstring.buffer==NULL){//如果newHstring为空,则提示输入newHstring
cout<<"newHstirng is null,plese enter newHstring"<<endl;
return *this;
}
//如果参数合理,获取buffer、oldHstring和newHstring的长度
int buffer_length=0;
while(buffer[buffer_length]!='\0'){++buffer_length;}
int old_length=0;
while(oldHstring[old_length]!='\0'){++old_length;}
int new_length=0;
while(newHstring.buffer[new_length]!='\0'){++new_length;}
//创建一个char存储结果
//长度为buffer的长度减去oldHstring的长度加上newHstring的长度+1,因为有'\0'
int result_length=buffer_length-old_length+new_length+1;
char* result=new char[result_length];
memset(result, 0, result_length);//重置清零
//查找oldHstring在buffer中的起始位置
int pos = -1;
for (int i = 0; i <= buffer_length ; ++i) {
for (int j = 0; j < old_length; ++j) {
if (buffer[i] == oldHstring[j]) {
pos=i;
memcpy(result, buffer, pos); // 复制到匹配位置前的内容
memcpy(result + pos, newHstring.buffer, new_length); // 替换内容
memcpy(result + pos + new_length, buffer + pos + old_length, buffer_length - pos - old_length); // 复制匹配位置之后的内容
result[buffer_length-old_length+new_length+1] = '\0';
delete[] buffer;//重置原缓冲区
buffer = result;//把结果赋给buffer,这样就能实现在原数据上修改
break;
}
}
}
return *this;
}
④查找数据
思路:
1.初始化子字符串的起始位置为-1,表示未找到,若buffer或findHstring为空,则返回-1
2.获取buffer和findHstring的长度
3.然后循环遍历寻找子串在母串中的起始位置,循环时可以通过两个长度相减,避免循环越界
const int findHstring(const char* findHstring) const {
int pos = -1;// 初始化子字符串的起始位置为-1,表示未找到
if (buffer == NULL || findHstring == NULL) {//buffer或findHstring为空,则返回-1
pos = -1;
return pos;
}
//获取buffer和findHstring的长度
int buffer_length = 0;
while (buffer[buffer_length] != '\0') { ++buffer_length; }
int find_length = 0;
while (findHstring[find_length] != '\0') { ++find_length; }
for (int i = 0; i <= buffer_length - find_length; ++i) { //通过两个长度相减,避免循环越界
bool found = true;
for (int j = 0; j < find_length; ++j) {
if (buffer[i + j] != findHstring[j]) {
found = false;
break;
}
}
if (found) {
pos = i+1;
break;
}
}
return pos;
}
⑤重载=运算符实现int转hstirng字符串
思路:
1.首先判断是否为负数
2.把原值用abs()
绝对值化
3.计算数字的位数
4.先在末尾加上'\0'
,然后根据是否为负数添加-
符号
5.最后通过循环,从后往前填充,手动通过ASCII码转换'0' + abs_x % 10
hstring& operator=(const int& x) {
if(!x){
cout<<"x is NULL,fault!"<<endl;
return *this;
}
//判断是否为负数
bool is_negative = 0;
if(x < 0){
is_negative = 1;
}
//使用绝对值方便处理
int abs_x = abs(x);
//计算数字的位数
int abs_x_buffer=abs_x;//创建一个副本
int x_length=0;
while (abs_x_buffer!=0)
{
++x_length;
abs_x_buffer/=10;
}
buffer = new char[x_length+is_negative+1]; // 考虑负号和'\0'
int i = x_length + is_negative;//末尾位置
buffer[i] = '\0'; // 根据是否为负数正确放置终止符
if (is_negative==1) {
buffer[0] = '-';
}
//从后往前填充
for (i-1; i >0 +is_negative; --i) {
int digit = abs_x % 10;
buffer[i-1] = '0' + digit;
abs_x /= 10;
}
return *this;
}
完整代码
#include <iostream>
#include <cstring>//只能使用memcpy,remove,memset
using namespace std;
//hstring类
class hstring
{
private:
char* buffer;//缓冲区
public:
// 默认构造函数
hstring() : buffer(NULL) {}
// 构造函数,用于接收一个char*类型的指针
hstring(char* managedBuffer) : buffer(managedBuffer) {}
// hstring类中添加一个接受int类型参数的构造函数
hstring(int val) {
*this = val; // 使用已经实现的重载赋值运算符来进行转换
}
//把数据复制给缓冲区
hstring(const char* initHstring){
if (initHstring!=NULL)//给缓冲区分配时,initHstring不为空,避免分配失败
{
int init_length=0;//获取字符长度
while(initHstring[init_length]!='\0'){//通过循环获取initHstring的长度
++init_length;
}
buffer=new char[init_length+1];//给缓冲区分配内存,因为有"\0",所以要+1
memcpy(buffer,initHstring,init_length+1);
}else{
buffer=NULL;
}
}
//析构函数
~hstring(){
cout<<"cleanring!"<<endl;//清除提示
if(buffer!=NULL){
delete[] buffer;
}
}
//获取缓冲区数据
const char* getHstring(){
return buffer;
}
//重载+运算符
hstring operator+(const hstring& x) const{
//如果有一方字符串为空,则返回另一方字符串
if(buffer==NULL){
return hstring(x.buffer);
}else if(x.buffer==NULL){
return *this;
}
//如果双方都不空
//获取buffer的字符长度
int buffer_length=0;
while(buffer[buffer_length]!='\0'){
++buffer_length;
}
//获取x的字符长度
int x_length=0;
while(x.buffer[x_length]!='\0'){
++x_length;
}
int result_length=buffer_length+x_length;//结果的长度
//创建一个result用来存储结果,给缓冲区分配内存,因为有'\0'所以+1
char* result=new char[result_length+1];
memcpy(result,buffer,buffer_length);//复制第一个字符串
memcpy(result+buffer_length,x.buffer,x_length+1);//复制第二个字符串
return hstring(result);//让char指针接受hstring的管理,自动释放指针
}
//重载-运算符
hstring operator-(const hstring& x) const{
//如果-右边的字符串为NULL,则输出原来的字符串
if(x.buffer==NULL||buffer==NULL){
return *this;
}
int x_length=0;//要删除的子串的长度
while(x.buffer[x_length]!='\0'){
++x_length;
}
int buffer_length=0;//获取buffer的字符长度
while(buffer[buffer_length]!='\0'){
++buffer_length;
}
char temp_buffer[buffer_length + 1]={0}; // 使用固定大小的数组
int index = 0; // 用于记录写入temp_buffer的位置
int j=0;
for(int i = 0; i < buffer_length;i++) {
for(j; j < x_length; ++j) {
if(buffer[i]!=x.buffer[j]) {
temp_buffer[index++] = buffer[i];
break;
}else{
++j;
break;
}
}
}
temp_buffer[index] = '\0'; // 添加结束符
memset(buffer,0,sizeof(buffer));//重置buffer
memcpy(buffer,temp_buffer,index);//把临时缓冲区数据复制给buffer
return *this;
}
//修改数据
const hstring& setHstring(const char* oldHstring,const hstring& newHstring){
//如果oldHstring为空,返回原值
if(oldHstring==NULL||buffer==NULL){
return *this;
}else if(newHstring.buffer==NULL){//如果newHstring为空,则提示输入newHstring
cout<<"newHstirng is null,plese enter newHstring"<<endl;
return *this;
}
//如果参数合理,获取buffer、oldHstring和newHstring的长度
int buffer_length=0;
while(buffer[buffer_length]!='\0'){++buffer_length;}
int old_length=0;
while(oldHstring[old_length]!='\0'){++old_length;}
int new_length=0;
while(newHstring.buffer[new_length]!='\0'){++new_length;}
//创建一个char存储结果
//长度为buffer的长度减去oldHstring的长度加上newHstring的长度+1,因为有'\0'
int result_length=buffer_length-old_length+new_length+1;
char* result=new char[result_length];
memset(result, 0, result_length);//重置清零
//查找oldHstring在buffer中的起始位置
int pos = -1;
for (int i = 0; i <= buffer_length ; ++i) {
for (int j = 0; j < old_length; ++j) {
if (buffer[i] == oldHstring[j]) {
pos=i;
memcpy(result, buffer, pos); // 复制到匹配位置前的内容
memcpy(result + pos, newHstring.buffer, new_length); // 替换内容
memcpy(result + pos + new_length, buffer + pos + old_length, buffer_length - pos - old_length); // 复制匹配位置之后的内容
result[buffer_length-old_length+new_length+1] = '\0';
delete[] buffer;//重置原缓冲区
buffer = result;//把结果赋给buffer,这样就能实现在原数据上修改
break;
}
}
}
return *this;
}
//查找数据
const int findHstring(const char* findHstring) const {
int pos = -1;// 初始化子字符串的起始位置为-1,表示未找到
if (buffer == NULL || findHstring == NULL) {//buffer或findHstring为空,则返回-1
pos = -1;
return pos;
}
//获取buffer和findHstring的长度
int buffer_length = 0;
while (buffer[buffer_length] != '\0') { ++buffer_length; }
int find_length = 0;
while (findHstring[find_length] != '\0') { ++find_length; }
for (int i = 0; i <= buffer_length - find_length; ++i) { //通过两个长度相减,避免循环越界
bool found = true;
for (int j = 0; j < find_length; ++j) {
if (buffer[i + j] != findHstring[j]) {
found = false;
break;
}
}
if (found) {
pos = i+1;
break;
}
}
return pos;
}
//重载=运算符实现int转hstirng字符串
hstring& operator=(const int& x) {
if(!x){
cout<<"x is NULL,fault!"<<endl;
return *this;
}
//判断是否为负数
bool is_negative = 0;
if(x < 0){
is_negative = 1;
}
//使用绝对值方便处理
int abs_x = abs(x);
//计算数字的位数
int abs_x_buffer=abs_x;//创建一个副本
int x_length=0;
while (abs_x_buffer!=0)
{
++x_length;
abs_x_buffer/=10;
}
buffer = new char[x_length+is_negative+1]; // 考虑负号和'\0'
int i = x_length + is_negative;//末尾位置
buffer[i] = '\0'; // 根据是否为负数正确放置终止符
if (is_negative==1) {
buffer[0] = '-';
}
//从后往前填充
for (i-1; i >0 +is_negative; --i) {
int digit = abs_x % 10;
buffer[i-1] = '0' + digit;
abs_x /= 10;
}
return *this;
}
};
int main(){
hstring sayHello1("1223456");
hstring sayHello2("hstring");
hstring sayHello3("246");
hstring sayHello4("56");
hstring sayHello5("st");
int a=23;
cout<<"sayHello1_buffer is: "<<sayHello1.getHstring()<<endl;
cout<<"sayHello2_buffer is: "<<sayHello2.getHstring()<<endl;
hstring res1=sayHello1+sayHello2;
cout<<"sayHello1+sayHello2: "<<res1.getHstring()<<endl;
hstring res2=sayHello1-sayHello3;
cout<<"sayHello1-sayHello3: "<<res2.getHstring()<<endl;
cout<<"sayHello1"<<": "<<sayHello1.getHstring()<<endl;
hstring res3=sayHello1-sayHello4;
cout<<"sayHello1-sayHello3: "<<res3.getHstring()<<endl;
hstring res4=sayHello1.setHstring("22",sayHello5);
cout<<"setHstring: "<<res4.getHstring()<<endl;
int res5=sayHello1.findHstring("22");
cout<<"findHstring: "<<res5<<endl;
hstring b=a;
cout<<"int to hstring: "<<b.getHstring()<<endl;
system("pause");
return 0;
}