《21天学通C++》阶段性成果测试题——hstring(手写string类)

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.如果参数合理,获取bufferoldHstringnewHstring的长度
3.new一个result存储结果,长度是:buffer的长度减去oldHstring的长度加上newHstring的长度+1,因为有'\0'
4.查找oldHstringbuffer中的起始位置
5.用memcpyoldHstring起始位置前的内容复制到result,然后把newHstring复制到result,再把oldHstringbuffer_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;
}

  • 13
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
C++stringC++标准库中提供的一个用于处理字符串。它提供了一系列成员函数和操作符重载,使得字符串操作更加方便和高效。 string的特点包括: 1. 动态内存管理:string会自动管理字符串的内存,无需手动分配和释放内存。 2. 可变性:string对象可以随时修改其内容,包括插入、删除、替换等操作。 3. 字符串操作string提供了丰富的字符串操作函数,如查找、比较、连接、截取等。 以下是一些常用的string成员函数和操作符重载: 1. 构造函数:可以使用不同的方式创建string对象,如默认构造函数、拷贝构造函数、从C风格字符串构造等。 2. 赋值操作:可以使用赋值运算符=将一个string对象赋值给另一个对象。 3. 连接操作:可以使用+运算符将两个string对象连接起来。 4. 访问字符:可以使用下标运算符[]或at()函数来访问字符串中的单个字符。 5. 获取长度:可以使用length()或size()函数获取字符串的长度。 6. 查找子串:可以使用find()函数在字符串中查找指定的子串。 7. 插入和删除:可以使用insert()函数在指定位置插入字符或子串,使用erase()函数删除指定位置的字符或子串。 8. 截取子串:可以使用substr()函数截取指定位置和长度的子串。 9. 比较字符串:可以使用比较运算符==、!=、<、>等来比较两个字符串的大小。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青石横刀策马

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值