当前位置:首页 » 《关注互联网》 » 正文

【C++】string的底层剖析以及模拟实现

18 人参与  2024年03月22日 14:16  分类 : 《关注互联网》  评论

点击全文阅读


一、字符串类的认识

        C语言中,字符串是以'\0'结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数, 但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。在OJ中,有关字符串的题目基本以string类的形式出现,而且在常规工作中,为了简单、方便、快捷,基本 都使用string类,很少有人去使用C库中的字符串操作函数。为了增加自己对于string的理解,自己将模仿库中string类有的方法,设计一个简单的string类。其中类成员包括以下:

class string    {    private:        char* _str;//字符串首地址        size_t _capacity;//字符串容量        size_t _size;//有效数据的个数    public:        typedef char* iterator;    }

二、库中string常用的方法

        我主要会实现string中经常会用到的方法,若大家想要了解更多关于string的细节,可以登录这个C++查询网站https://cplusplus.com/reference/自行查询下面是一些常用方法以及代码片段,可能前面出现的方法会用到后面出现的方法的实现,若有疑问可以看最后面的完整代码

正向迭代器

iterator begin(){    return _str;}iterator end(){    return _str + _size;}

+=

        string& operator+=(char c)        {            if (_size == _capacity)            {                _capacity = _capacity == 0 ? 4 : 2 * _capacity;                char* tmp = new char[_capacity +1];                strcpy(tmp, _str);                delete[] _str;                _str = tmp;            }            _str[_size] = c;            _str[_size + 1] = '\0';            _size++;            return *this;        }        string& operator+=(const char* str)        {            append(str);            return *this;        }

push_back(尾插)

        void push_back(char c)        {            *this += c;        }

 append(在字符串末尾追加)

        void append(const char* str)        {            int i = 0;            while (str[i])            {                push_back(str[i]);                i++;            }        }

  clear(清除掉字符串的数据)

        void clear()        {            _size = 0;            _str[0] = '\0';        }

   swap(交换两个字符串的内容)

        void swap(string& s)        {            std::swap(_str,s._str);            std::swap(_size, s._size);            std::swap(_capacity, s._capacity);        }

  c_str(返回字符串的首地址)

        const char* c_str()const        {            return _str;        }

 resize(将字符串设定为指定大小,字符串占满所开辟的空间)

        void resize(size_t n, char c = '\0')        {            if (n > _capacity)            {                reserve(n);                for (int i = _size; i < _capacity; i++)                {                    _str[i] = c;                }                _size = _capacity;            }            else            {                _size = n;            }        }

 reserve(预开辟出空间,字符串还是原来的大小(一般不缩容))

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

  find(返回字符c在string中第一次出现的位置/返回子串s在string中第一次出现的位置

        size_t find(char c, size_t pos = 0) const        {            for (size_t i = pos; i < _size; i++)            {                if (_str[i] == c)                    return i;            }            return std::string::npos;        }        size_t find(const char* s, size_t pos = 0) const        {            const char* ptr = std::strstr(_str + pos, s);            if (ptr == nullptr)                return std::string::npos;            else            {                return ptr - _str;            }        }

insert(在pos位置上插入字符c/字符串str,并返回该字符的位置)

 

        string& insert(size_t pos, char c)        {            if (_size == _capacity)            {                reserve(_capacity == 0 ? 4 : 2 * _capacity);            }            size_t end = _size - 1;            while (end >= pos)            {                _str[end + 1] = _str[end];                end--;            }            _str[pos] = c;            return *this;        }        string& insert(size_t pos, const char* str)        {            int len = 0;            while (str[len++]);            if (_size + len > _capacity)            {                reserve(_size + len);            }            memmove(_str + pos + len, _str + pos, len * sizeof(char));            for (int i = pos; i < pos + len; i++)            {                _str[i] = str[i - pos];            }            _size += len;            return *this;        }

erase(删除pos位置上的元素,并返回该string)

        string& erase(size_t pos, size_t len)        {            memmove(_str + pos, _str + pos + len, (_size - pos-len) * sizeof(char));            _size -= len;            return *this;        }

三、完整代码

//string.h#pragma once#define _CRT_SECURE_NO_WARNINGS 1#include <iostream>#include <string>//using namespace std;namespace sxb{    class string    {        friend std::ostream& operator<<(std::ostream& _cout, const string& s);        friend std::istream& operator>>(std::istream& _cin, string& s);    private:        char* _str;        size_t _capacity;        size_t _size;    public:        typedef char* iterator;    public:        string(const char* str = "")        {            //_str = str;            int len = 0;            while(str[len] != ' ' && str[len] != '\0')            {                len++;            }            _str = new char[len + 1];            for (int i = 0; i < len; i++)            {                _str[i] = str[i];            }            _str[len] = '\0';            _capacity = len;            _size = len;        }        string(const string& s)        {            _str = new char[s.size() + 1];            strcpy(_str, s.c_str());            _str[s.size()] = '\0';            _capacity = s.size();            _size = s.size();        }        string& operator=(const string& s)        {            for (int i = 0; i < size(); i++)            {                _str += s[i];            }            return *this;        }        ~string()        {            delete[] _str;            _size = 0;            _capacity = 0;        }            //            // iterator        iterator begin()        {            return _str;        }        iterator end()        {            return _str + _size;        }        //    /        //    // modify        void push_back(char c)        {            *this += c;        }        string& operator+=(char c)        {            if (_size == _capacity)            {                _capacity = _capacity == 0 ? 4 : 2 * _capacity;                char* tmp = new char[_capacity +1];                strcpy(tmp, _str);                delete[] _str;                _str = tmp;            }            _str[_size] = c;            _str[_size + 1] = '\0';            _size++;            return *this;        }        void append(const char* str)        {            int i = 0;            while (str[i])            {                push_back(str[i]);                i++;            }        }        string& operator+=(const char* str)        {            append(str);            return *this;        }        void clear()        {            _size = 0;            _str[0] = '\0';        }        void swap(string& s)        {            std::swap(_str,s._str);            std::swap(_size, s._size);            std::swap(_capacity, s._capacity);        }        const char* c_str()const        {            return _str;        }        ///         capacity        size_t size()const        {            return _size;        }        size_t capacity()const        {            return _capacity;        }        bool empty()const        {            return _str[0] == '\0';        }        void resize(size_t n, char c = '\0')        {            if (n > _capacity)            {                reserve(n);                for (int i = _size; i < _capacity; i++)                {                    _str[i] = c;                }                _size = _capacity;            }            else            {                _size = n;            }        }        void reserve(size_t n)        {            if (n > _capacity)            {                _capacity = n;                char* tmp = new char[_capacity + 1];                strcpy(tmp, _str);                delete[] _str;                _str = tmp;            }        }        ///         access        char& operator[](size_t index)        {            return _str[index];        }        const char& operator[](size_t index)const        {            return _str[index];        }        ///        relational operators        bool operator==(const string& s)        {            if (_size != s.size())                return false;            for (int i = 0; i < _size; i++)            {                if (_str[i] != s[i])                    return false;            }            return true;        }        bool operator!=(const string& s)        {            return !operator==(s);        }         返回c在string中第一次出现的位置        size_t find(char c, size_t pos = 0) const        {            for (size_t i = pos; i < _size; i++)            {                if (_str[i] == c)                    return i;            }            return std::string::npos;        }         返回子串s在string中第一次出现的位置        size_t find(const char* s, size_t pos = 0) const        {            const char* ptr = std::strstr(_str + pos, s);            if (ptr == nullptr)                return std::string::npos;            else            {                return ptr - _str;            }        }         在pos位置上插入字符c/字符串str,并返回该字符的位置        string& insert(size_t pos, char c)        {            if (_size == _capacity)            {                reserve(_capacity == 0 ? 4 : 2 * _capacity);            }            size_t end = _size - 1;            while (end >= pos)            {                _str[end + 1] = _str[end];                end--;            }            _str[pos] = c;            return *this;        }        string& insert(size_t pos, const char* str)        {            int len = 0;            while (str[len++]);            if (_size + len > _capacity)            {                reserve(_size + len);            }            memmove(_str + pos + len, _str + pos, len * sizeof(char));            for (int i = pos; i < pos + len; i++)            {                _str[i] = str[i - pos];            }            _size += len;            return *this;        }         删除pos位置上的元素,并返回该元素的下一个位置        string& erase(size_t pos, size_t len)        {            memmove(_str + pos, _str + pos + len, (_size - pos-len) * sizeof(char));            _size -= len;            return *this;        }    };    std::ostream& operator<<(std::ostream& _cout, const string& s)    {        for (int i = 0; i < s.size(); i++)        {            _cout << s[i];        }        return _cout;    }    std::istream& operator>>(std::istream& _cin, string& s)    {        char buffer[128];        int len = 0;        char bu = _cin.get();        while (bu != ' ' && bu != '\n')        {            buffer[len] = bu;            len++;            bu = _cin.get();        }        for (int i = 0; i < len; i++)        {            s += buffer[i];        }        return _cin;    }}


点击全文阅读


本文链接:http://m.zhangshiyu.com/post/83638.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1