《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'所以+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.如果参数合理,获取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为空,则提示输入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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/836581.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥杯备战11.歌唱比赛

P5738 【深基7.例4】歌唱比赛 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) #include<bits/stdc.h> #define endl \n #define int long long using namespace std; const int N 2e710,M 1e310; int a[N],sum[N];signed main() {//std::ios::sync_with_stdio(0),cin.…

VScode查看以十六进制查看文件的插件说明

找到插件并下载 打开指定的文件 选择打开方式即可 结果如下

C++/Qt 小知识记录6

工作中遇到的一些小问题&#xff0c;总结的小知识记录&#xff1a;C/Qt 小知识6 dumpbin工具查看库导出符号OSGEarth使用编出的protobuf库&#xff0c;报错问题解决VS2022使用cpl模板后&#xff0c;提示会乱码的修改设置QProcess调用cmd.exe执行脚本QPainterPath对线段描边处理…

英文文本标点恢复

文章目录 一、安装 rpunct二、使用三、下载模型时报错1、报错详情2、报错原因3、解决方案 四、程序运行时报错1、报错详情2、报错原因3、解决方案 五、修改默认缓存路径 一、安装 rpunct pip install rpunct 相关依赖包信息&#xff1a; langdetect1.0.9 pandas1.2.4 simpletr…

Java入门最小必要知识:变量及其本质

编程语言是与计算机交流的桥梁&#xff0c;而在编程世界中&#xff0c;变量是这座桥上不可或缺的砖石。 从本质上&#xff0c;可以把复杂的编程工作简化为两件事&#xff1a; ①定义变量②操作变量 可见&#xff0c;变量之于编程的重要性。 对于Java开发者&#xff0c;理解…

阿里云 物联网平台 MQTT连接、数据传输

阿里云 物联网平台 MQTT连接、数据传输 1、设备连接阿里云 2、多设备之前的通信、数据流转 3、设备数据来源的读取。 基于C# winform 开发上位机&#xff0c;读取设备、仪器、MES或者电子元器件的数据&#xff0c;MQTT传输至阿里云平台&#xff0c;可视化界面构建界面&#…

华为OD介绍

概念 华为OD是华为提出的一种新的用工方式&#xff0c;其全称是Outsourcing Dispacth&#xff0c;也可以简写为ODP&#xff0c;是华为和北京外企德科人力资源服务上海有限公司联合招聘的简称。华为OD岗位属于华为外包员工的一种&#xff0c;仅限于软件研发类岗位&#xff0c;类…

1065: 无向图的连通分量计算

解法&#xff1a; dfs求连通性 1.设节点表vis[] 2.遍历节点表dfs标记&#xff0c;每次得到一个连通分量 #include<iostream> #include<vector> using namespace std; int arr[100][100]; void dfs(vector<bool>& vis, int v) {//不用终止条件&#x…

StringRedisTemplate使用

文章目录 一&#xff0c;StringRedisTemplate介绍二&#xff0c;StringRedisTemplate使用1.字符串&#xff08;String&#xff09;&#xff1a;2.哈希&#xff08;Hash&#xff09;&#xff1a;3.列表&#xff08;List&#xff09;&#xff1a;4.集合&#xff08;Set&#xff0…

省级生活垃圾无害化处理率面板数据(2004-2022年)

01、数据简介 生活垃圾无害化处理率是指经过处理的生活垃圾中&#xff0c;达到无害化标准的垃圾所占的比例。这一指标是衡量城市垃圾处理水平的重要标准&#xff0c;反映了城市对垃圾进行有效管理和处理的能力。 生活垃圾无害化处理的主要方式包括生活垃圾焚烧、生活垃圾卫生…

金三银四面试题(二十八):观察者模式知多少?

什么是观察者模式 观察者模式&#xff08;Observer Pattern&#xff09; 是一种设计模式&#xff0c;它定义了一种一对多的关系&#xff0c;让多个观察者对象能够同时监听一个主题对象。当主题对象的状态发生变化时&#xff0c;会通知所有观察者对象&#xff0c;使它们能够作出…

Sass:强大而灵活的CSS预处理器详解

Sass&#xff1a;强大而灵活的CSS预处理器详解 在前端开发的世界里&#xff0c;CSS&#xff08;层叠样式表&#xff09;作为样式描述语言&#xff0c;为我们提供了丰富的样式定义和布局方式。然而&#xff0c;随着项目规模的不断扩大和复杂度的提升&#xff0c;原生CSS的编写和…

C++:完美转发(二)(std::forward)

一、RVO优化和std::move、std::forward 以下是一个综合性的例子&#xff1a; #include <iostream> #include <memory> #include <ostream> using namespace std;// 1. 针对右值引用实施std::move&#xff0c;针对万能引用实施std::forward class Data {};c…

react之Reducer和Context的联合使用

第三章 - 状态管理 使用 Reducer 和 Context 拓展你的应用 Reducer 可以整合组件的状态更新逻辑。Context 可以将信息深入传递给其他组件。你可以组合使用它们来共同管理一个复杂页面的状态。 结合使用 reducer 和 context 在 reducer 介绍 的例子里面&#xff0c;状态被 r…

如何修复Windows中的“无Internet,安全”错误?这里有详细步骤

序言 在Windows计算机上连接到互联网非常容易,但是,当你尝试连接到网络时,Windows有时可能会显示消息“无Internet,安全”。此消息的确切含义是什么?如何修复?以下是你需要了解的所有信息。 为什么Windows显示“无Internet,安全”消息 “无Internet,安全”消息是一个…

简约在线生成短网址系统源码 短链防红域名系统 带后台

简约在线生成短网址系统源码 短链防红域名系统 带后台 安装教程&#xff1a;访问 http://你的域名/install 进行安装 源码免费下载地址抄笔记 (chaobiji.cn)https://chaobiji.cn/

图像分割各种算子算法-可直接使用(Canny、Roberts、Sobel)

Canny算子&#xff1a; import numpy as np import cv2 as cv from matplotlib import pyplot as pltimg cv.imread("../test_1_1.png") edges cv.Canny(img, 100, 200)plt.subplot(121),plt.imshow(img,cmap gray) plt.title(Original Image), plt.xticks([]), …

MySQL数据库之UNION 和JOIN连接的区别?

UNION和JOIN连接是用于合并表中数据的两种不同方法。 1、JOIN连接&#xff1a; 用于在查询中将两个或多个表中的行基于它们之间的关联条件进行匹配。JOIN操作允许您将来自不同表的相关数据组合到一起&#xff0c;以便一次性检索所有相关信息。JOIN操作通常涉及使用ON子句指定…

电文加密(C语言)

一、题目说明&#xff1b; 即第1个字母变成第26个字母&#xff0c;第i个字母变成第(26 - i 1)个字母&#xff0c;非字母字符不变。 二、N-S流程图&#xff1b; 三、运行结果&#xff1b; 四、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h&g…

C语言深入理解指针(4)--指针笔试题解析

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 C语言深入理解指针(4) 收录于专栏【C语言学习】 本专栏旨在分享学习C语言学习的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 1. size…