那些年我与c++的叫板(一)--string类自实现

news2024/11/15 20:25:19

引子:我们学习了c++中的string类,那我们能不能像以前数据结构一样自己实现string类呢?以下是cplusplus下的string类,我们参考参考!

废话不多说,直接代码实现:(注意函数之间的复用!)

#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include<iostream>
#include<assert.h>
using namespace std;
//一般在类外进行静态区变量赋值
const static size_t npos = -1;
//本string简单实现,代码量小,故直接写在声明中
namespace bit
{
    class string
    {
    public:
        //采用typedef 让iterator保持接口的一致性
        //iterator底层是模版template
        typedef char* iterator;
        typedef const char* const_iterator;
        
        iterator begin()
        {
            return _str;
        }
        iterator end()
        {
            return _str + _size;
        }
        const_iterator begin() const
        {
            return _str;
        }
        const_iterator end() const
        {
            return _str + _size;
        }

        //构造函数
        string(const char* str = "")
            :_size(strlen(str))
        {
            _str = new char[_size + 1];//为深拷贝,因为如果浅拷贝的话,共用一块空间,那结果可想而知
            _capacity = _size;
            strcpy(_str, str);//注意char * strcpy ( char * destination, const char * source );
        }
        //拷贝构造,可以隐式类型赋值
        string(const string& s)
        {
            _str = new char[s._capacity + 1];
            strcpy(_str, s._str);
            _size = s._size;
            _capacity = s._capacity;
        }
        string& operator=(const string& s)
        {
            if (this != &s)//排除等于自身的情况
            {
                char* tmp = new char[s._capacity + 1];
                strcpy(tmp, s._str);
                delete[]_str;//只析构_str上的资源
                _str = tmp;
                _size = s._size;
                _capacity = s._capacity;
            }
            return *this;
        }
        ~string()
        {
            delete[]_str;
            _str = nullptr;
            _size = _capacity = 0;
        }
        const char* c_str() const
        {
            return _str;
        }
        size_t size() const
        {
            return _size;
        }
        char& operator[](size_t pos)
        {
            assert(pos < _size);
            return _str[pos];
        }
        const char& operator[](size_t pos) const
        {
            assert(pos < _size);
            return _str[pos];
        }

        void reserve(size_t n)
        {
            if (n > _capacity)
            {
                char* tmp = new char[n + 1];
                strcpy(tmp, _str);
                delete[] _str;

                _str = tmp;
                _capacity = n;
            }
        }
        void insert(size_t pos, char ch)
        {
            assert(pos <= _size);

            if (_size == _capacity)
            {
                size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;
                reserve(newcapacity);
            }
            size_t end = _size + 1;
            while (end > pos)
            {
                _str[end] = _str[end - 1];
                --end;
            }
            _str[pos] = ch;
            ++_size;
        }
        void insert(size_t pos, const char* str)
        {
            assert(pos <= _size);
            size_t len = strlen(str);
            if (_size + len > _capacity)
            {
                reserve(_size + len);
            }
            size_t end = _size;
            //注意pos=0时,对应的值为size_t类型,要int转
            while (end > (int)pos)
            {
                _str[end+len] = _str[end];
                --end;
            }

            memcpy(_str + pos, str, len);//void * memcpy ( void * destination, const void * source, size_t num );
            _size += len;
        }
        void push_back(char ch)
        {
            insert(_size, ch);
        }
        void append(const char* str)
        {
            insert(_size, str);
        }
        string& operator+=(char ch)
        {
            push_back(ch);
            return *this;
        }
        string& operator+=(const char* str)
        {
            append(str);
            return *this;
        }
        void erase(size_t pos = 0, size_t len = npos)
        {
            assert(pos < _size);

            // len大于前面字符个数时,有多少删多少
            if (len >= _size - pos)
            {
                _str[pos] = '\0';
                _size = pos;
            }
            else
            {
                strcpy(_str + pos, _str + pos + len);
                _size -= len;
            }
        }

        size_t find(char ch, size_t pos = 0)
        {
            for (size_t i = pos; i < _size; i++)
            {
                if (_str[i] == ch)
                {
                    return i;
                }
            }
            return npos;
        }
        size_t find(const char* str, size_t pos = 0)
        {
            char* p = strstr(_str + pos, str);//char * strstr (char * str1, const char * str2 );
            return  p - _str;
        }
        void swap(string& s)
        {
            std::swap(_str, s._str);
            std::swap(_size, s._size);
            std::swap(_capacity, s._capacity);
        }
        string substr(size_t pos = 0, size_t len = npos)
        {
            // len大于后面剩余字符,有多少取多少
            if (len > _size - pos)
            {
                string sub(_str + pos);
                return sub;
            }
            else
            {
                string sub;
                sub.reserve(len);
                for (size_t i = 0; i < len; i++)
                {
                    sub += _str[pos + i];
                }
                return sub;
            }
        }
        bool operator<(const string& s) const
        {
            return strcmp(_str, s._str) < 0;
        }
        bool operator>(const string& s) const
        {
            return !(*this <= s);
        }
        bool operator<=(const string& s) const
        {
            return *this < s || *this == s;
        }
        bool operator>=(const string& s) const
        {
            return !(*this < s);
        }
        bool operator==(const string& s) const
        {
            return strcmp(_str, s._str) == 0;
        }
        bool operator!=(const string& s) const
        {
            return !(*this == s);
        }
        void clear()
        {
            _str[0] = '\0';
            _size = 0;
        }
    private:
        // char _buff[16];
        char* _str;
        size_t _size;
        size_t _capacity;
        const static size_t npos;
    };
    istream& operator>> (istream& is, string& str)
    {
        str.clear();
        char ch = is.get();
        while (ch != ' ' && ch != '\n')
        {
            str += ch;
            ch = is.get();
        }
        return is;
    }
    ostream& operator<< (ostream& os, const string& str)
    {
        for (size_t i = 0; i < str.size(); i++)
        {
            os << str[i];
        }
        return os;
    }
}

长图形式:

还需大家一起改善!我们共赴山海!~~~~~

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

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

相关文章

公司邮箱是什么?公司邮箱和个人邮箱有什么不同?

公司邮箱是企业用来收发邮件的专业版电子邮箱&#xff0c;不同于个人邮箱的简单功能和有限的存储空间&#xff0c;公司邮箱的功能更加丰富&#xff0c;能够满足企业的日常办公和协作需求。本文将为您详细讲解公司邮箱和个人邮箱的区别&#xff0c;以供您选择更适合自己的邮箱类…

数学建模——农村公交与异构无人机协同配送优化

目录 1.题目 2.问题1 1. 问题建模 输入数据 ​编辑 2. 算法选择 3.数据导入 3.模型构建 1. 距离计算 2. 优化模型 具体步骤 进一步优化 1. 重新定义问题 2. 变量定义 3. 优化目标 具体步骤 再进一步优化 具体实现步骤 1. 计算距离矩阵 2. 变量定义 3. 约束…

【C++】:string类的基本使用

目录 引言一&#xff0c;string类对象的常见构造二&#xff0c;string类对象的容量操作三&#xff0c;string类对象的访问及遍历操作四&#xff0c;string类对象的修改操作五&#xff0c;string类非成员函数六&#xff0c;整形与字符串的转换 引言 string 就是我们常说的"…

UIKit之图片浏览器

功能需求 实现一个图片浏览器&#xff0c;点击左右按钮可以切换背景图&#xff0c;且更新背景图对应的索引页和图片描述内容。 分析&#xff1a; 实现一个UIView的子类即可&#xff0c;该子类包含多个按钮。 实现步骤&#xff1a; 使用OC语言&#xff0c;故创建cocoa Touch类…

【JavaScript】WeakMap 和 WeakSet

Map Map 用于存储键值对。 添加属性&#xff1a; 使用 Map 的 set() 方法可以向 Map 对象中添加键值对。例如&#xff1a; const map new Map(); map.set(key1, value1); map.set(key2, value2);通过二维数组快速创建 map 键值对。 let arr [[1, 2],[2, 3],[3, 4]]let map …

window10下安装ubuntu系统以及docker使用

window10下安装ubuntu系统以及docker使用 1. 启用适用于Linux的Windwos子系统2.下载Linux内核更新包3.将 WSL 2 设置为默认版本4.安装Ubuntu<br />直接去Microsoft store里面直接搜索Ubuntu进行安装。5.可能出现的问题1.win10启动ubuntu报错 参考的对象类型不支持尝试的操…

2024中国应急(消防)品牌巡展西安站成功召开!惊喜不断

消防品牌巡展西安站 5月10日&#xff0c;由中国安全产业协会指导&#xff0c;中国安全产业协会应急创新分会、应急救援产业网联合主办&#xff0c;陕西消防协会协办的“一切为了安全”2024年中国应急(消防)品牌巡展-西安站成功举办。该巡展旨在展示中国应急&#xff08;消防&am…

ABC352编程笔记

ABC352 编程笔记 题意&#xff1a;输入&#xff0c;四个数 a , b , c , d a,b,c,d a,b,c,d&#xff0c;若 d d d 在 c , d c,d c,d 之间&#xff0c;则输出 Yes&#xff0c;否则输出 No。 正解&#xff1a;直接判断。 #include <bits/stdc.h> //#define int long lo…

大数据比赛-环境搭建(二)

一、ubuntu安装google 1、下载google的Linux安装版 链接&#xff1a;https://pan.baidu.com/s/1w4Hsa1wbJDfC95fX2vU_1A 提取码&#xff1a;xms6 或者&#xff1a;Google Chrome 64bit Linux版_chrome浏览器,chrome插件,谷歌浏览器下载,谈笑有鸿儒 (chromedownloads.net) …

docker-java 操作docker

部署docker 10分钟学会Docker的安装和使用_docker安装-CSDN博客文章浏览阅读2.5w次&#xff0c;点赞44次&#xff0c;收藏279次。文章目录Docker简介Docker安装Windows安装Linux安装CentOS安装Ubuntu安装最近花了些时间学习docker技术相关&#xff0c;在此做一些总结&#xff0…

静态IP代理:网络世界的隐秘通道

在数字化时代&#xff0c;网络安全和隐私保护日益受到重视。静态IP代理作为一种网络服务&#xff0c;为用户提供了一个稳定且可预测的网络连接方式&#xff0c;同时保护了用户的在线身份。本文将从五个方面深入探讨静态IP代理的概念、优势、应用场景、技术实现以及选择时的考量…

【传知代码】VRT: 关于视频修复的模型(论文复现)

前言&#xff1a;随着数字媒体技术的普及&#xff0c;制作和传播视频内容变得日益普遍。但是&#xff0c;视频中由于多种因素&#xff0c;例如传输、存储和录制设备等&#xff0c;经常出现质量上的问题&#xff0c;如图像模糊、噪声干扰和低清晰度等。这类问题对用户的体验和观…

【JAVA】嵌入式软件工程师-2025校招必备-详细整理

一、Java 基础 1.JDK 和 JRE 有什么区别&#xff1f; jdk&#xff1a;java development kit jre&#xff1a;java runtime Environment jdk是面向开发人员的&#xff0c;是开发工具包&#xff0c;包括开发人员需要用到的一些类。 jre是java运行时环境&#xff0c;包括java虚拟机…

困惑点记录

【第十章 总结思考】CIM之我见 - 知乎

STK中的光照计算模型

本文简要阐述STK中光照计算的模型。 在航天任务中&#xff0c;通常需要分析地面站、飞行器在一定时间内的光照情况&#xff0c;具体包括&#xff1a; 地面站处在光照区和阴影区的具体时间范围&#xff1b;考虑地形遮挡后&#xff0c;地面站的光照区和阴影区的变化情况&#x…

解决kali Linux安装后如何将语言修改为中文

开启虚拟机 用root用户进入终端 进入终端执行dpkg-reconfigure locales命令 选择en_US.UTF-8 UTF-8选项&#xff0c;按空格键将其取消。 选择zh_CN.UTF-8 UTP-8&#xff0c;按空格选择&#xff0c;按tab键选择ok。 选择zh_CN.UTF-8字符编码&#xff0c;按tab键选择ok&#xff0…

【漏洞复现】Secnet-智能路由系统 actpt_5g.data信息泄露

0x01 产品简介 Secnet安网智能AC管理系统是广州安网通信技术有限公司(简称“安网通信”)的无线AP管理系统 0x02 漏洞描述 Secnet智能路由系统 acipt 5g.data 接口存在信息泄露漏洞&#xff0c;未经身份验证的远程攻击者可以利用此漏洞获取系统账户名密码等重要凭据&#xff…

社区服务用工具建立与居民的强关系

在数字化时代的浪潮下&#xff0c;社区服务不再局限于传统的面对面交流模式&#xff0c;而是借助互联网医疗健康服务应用&#xff0c;尤其是智慧康养服务平台&#xff0c;构建起了与居民之间更为紧密、便捷的联系。这种新型的社区服务模式&#xff0c;不仅提升了服务效率&#…

wsl2安装rancher并导入和创建k8s集群

环境准备 安装wsl2点击此文]ubuntu20.04安装docker 点击此文,安装完成后docker镜像仓库改成阿里云镜像加速地址.如果不熟请点击此文 docker 安装rancher 启动wsl,根据官方文档以root身份执行 sudo docker run -d --restartunless-stopped -p 80:80 -p 443:443 --privileged …