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'所以+1char* 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));//重置buffermemcpy(buffer,temp_buffer,index);//把临时缓冲区数据复制给bufferreturn *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为空,则提示输入newHstringcout<<"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为空,则返回-1pos = -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,memsetusing 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",所以要+1memcpy(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'所以+1char* 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));//重置buffermemcpy(buffer,temp_buffer,index);//把临时缓冲区数据复制给bufferreturn *this;}//修改数据const hstring& setHstring(const char* oldHstring,const hstring& newHstring){//如果oldHstring为空,返回原值if(oldHstring==NULL||buffer==NULL){return *this;}else if(newHstring.buffer==NULL){//如果newHstring为空,则提示输入newHstringcout<<"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为空,则返回-1pos = -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;
}