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

引子:我们学习了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.mzph.cn/web/12929.shtml

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

相关文章

Nacos+GateWay 搭建微服务架构

文章目录 1.当前项目架构分析1.请求多个模块的方式1.请求renren-fast模块开发环境生产环境 2.请求sunliving-commodity模块1.使用环境变量资源路径的方式2.开发环境 dev.env.js3.生产环境 prod.env.js 3.文件上传请求 sunliving-service模块1.请求后端接口&#xff08;开发环境…

汇聚荣科技:拼多多上架商品后需要做页面推广吗?

在电商平台上&#xff0c;商品的曝光率和销量往往成正比。那么&#xff0c;当您在拼多多上架了新品&#xff0c;是不是就意味着坐等订单呢?答案显然是否定的。商品一旦上架&#xff0c;接下来需要做的就是通过有效的页面推广来增加商品的可见度&#xff0c;吸引潜在买家的注意…

html基础(全)

html简介 目录 什么是网页 什么是 HTML 常用浏览器 WebE标准的构成 基本语法概述 第一个HTML页面 文档类型声明标签 lang 语言种类 字符集 标题标签 段落和换行标签 文本格式化标签 div和span标签 图像标签和路径 超链接标签 表格的主要作用 表头单元格标签 列…

纯血鸿蒙APP实战开发——Web获取相机拍照图片案例

介绍 本示例介绍如何在HTML页面中拉起原生相机进行拍照&#xff0c;并获取返回的图片。 效果预览图 使用说明 点击HTML页面中的选择文件按钮&#xff0c;拉起原生相机进行拍照。完成拍照后&#xff0c;将图片在HTML的img标签中显示。 实现思路 添加Web组件&#xff0c;设置…

【SpringBoot】SpringBoot整合jasypt进行重要数据加密

&#x1f4dd;个人主页&#xff1a;哈__ 期待您的关注 目录 &#x1f4d5;jasypt简介 &#x1f525;SpringBoot使用jasypt &#x1f4c2;创建我需要的数据库文件 &#x1f4d5;引入依赖 &#x1f513;配置数据库文件&#xff08;先不进行加密&#xff09; &#x1f319;创…

Anaconda安装-超详细版(2024)

扫盲&#xff1a;先装Python还是先装anaconda? 安装anaconda即可&#xff0c;不需要单独装python anaconda 是一个python的发行版&#xff0c;包括了python和很多常见的软件库, 和一个包管理器conda。 一、下载Anaconda 安装包&#xff08;官网和国内镜像资源&#xff09; …

【深度学习】SDXL中的Offset Noise,Diffusion with Offset Noise,带偏移噪声的扩散

https://www.crosslabs.org//blog/diffusion-with-offset-noise 带有偏移噪声的扩散 针对修改后的噪声进行微调&#xff0c;使得稳定扩散能够轻松生成非常暗或非常亮的图像。 作者&#xff1a;尼古拉斯古藤伯格 | 2023年1月30日 马里奥兄弟使用稳定扩散挖掘隧道。左图显示了未…

Springboot+Vue项目-基于Java+MySQL的高校专业实习管理系统(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &…

Linux文件:重定向底层实现原理(输入重定向、输出重定向、追加重定向)

Linux文件&#xff1a;重定向底层实现原理&#xff08;输入重定向、输出重定向、追加重定向&#xff09; 前言一、文件描述符fd的分配规则二、输出重定向&#xff08;>&#xff09;三、输出重定向底层实现原理四、追加重定向&#xff08;>>&#xff09;五、输入重定向…

关于 vs2019 c++20 规范里的 STL 库里模板 decay_t<T>

&#xff08;1&#xff09; 这个模板&#xff0c;在库代码里非常常见。 decay 英文是“衰弱&#xff0c;消减” 的意思&#xff0c;大概能感觉到就是要简化模板参数 T 的类型&#xff0c;去掉其上的修饰符。因为常用且复杂&#xff0c;故单独列出其源码和注释。先举例其应用场景…

基于Springboot的学生心理压力咨询评判(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的学生心理压力咨询评判&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系…

Yalmip使用教程(8)-常见报错及调试方法

博客中所有内容均来源于自己学习过程中积累的经验以及对yalmip官方文档的翻译&#xff1a;https://yalmip.github.io/tutorials/ 这篇博客将详细介绍使用yalmip工具箱编程过程中的常见错误和相应的解决办法。 1.optimize的输出参数 众所周知&#xff0c;optimize是yalmip用来求…

PS滤镜插件Camera Raw 15.4升级,开启智能修图

前段时间Adobe 更新了photoshop 的智能AI填充功能&#xff0c;深受很多设计师朋友的喜爱。Camera Raw作为PS的一个滤镜插件对RAW图片的处理上面有一定的优势&#xff0c;Camera Raw 15.4升级了&#xff0c;开启智能修图木事&#xff0c;一起来看看吧&#xff01; Camera Raw滤镜…

【2024华为HCIP831 | 高级网络工程师之路】刷题日记(18)

个人名片&#xff1a;&#x1faaa; &#x1f43c;作者简介&#xff1a;一名大三在校生&#xff0c;喜欢AI编程&#x1f38b; &#x1f43b;‍❄️个人主页&#x1f947;&#xff1a;落798. &#x1f43c;个人WeChat&#xff1a;hmmwx53 &#x1f54a;️系列专栏&#xff1a;&a…

ClassificationPrimitive 内部原理

ClassificationPrimitive 内部原理 发明 ClassificationPrimitive的真是个天才。其原理是利用 webgl 的模板缓冲区实现。 渲染两次, 首先是绘制模板, 然后绘制真正的内容。 示意图: function createClass() {const { program, uniforms } WebGLProgram.buildPrograms(gl, …

代码随想录算法训练营第36期DAY22

DAY22 654最大二叉树 自己做的时候忽略了&#xff1a;nums.length>1的题给条件。所以每次递归都要判断是否size()>1&#xff0c;不要空的。 /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *rig…

牛客网刷题 | BC84 牛牛学数列2

目前主要分为三个专栏&#xff0c;后续还会添加&#xff1a; 专栏如下&#xff1a; C语言刷题解析 C语言系列文章 我的成长经历 感谢阅读&#xff01; 初来乍到&#xff0c;如有错误请指出&#xff0c;感谢&#xff01; 描述 这次牛牛又换了个数…

「AIGC」Python实现tokens算法

本文主要介绍通过python实现tokens统计,避免重复调用openai等官方api,开源节流。 一、设计思路 初始化tokenizer使用tokenizer将文本转换为tokens计算token的数量二、业务场景 2.1 首次加载依赖 2.2 执行业务逻辑 三、核心代码 from transformers import AutoTokenizer imp…

React: memo

React.memo 允许你的组件在 props 没有改变的情况下跳过重新渲染。 const MemoizedComponent memo(SomeComponent, arePropsEqual?)React 通常在其父组件重新渲染时重新渲染一个组件。你可以使用 memo 创建一个组件&#xff0c;当它的父组件重新渲染时&#xff0c;只要它的新…