string的模拟实现

string的构造与遍历

构造函数与析构函数

  • 构造函数

    复制代码
            string(const char* str = "")//常量字符串默认结尾\0
                :_str(new char[strlen(str) + 1])
                , _size(strlen(str))
                , _capacity(_size)
            {
                strcpy(_str, str);
            }
    ​
    ​
            //string() //无参构造
            //  :_size(0)
            //  , _capacity(0)
            //  , _str(new char[1])
            //{
            //  _str[0] = '\0';
            //}

    带默认参数的构造函数中,const char*用于指向常量字符,接收以\0结尾的字符串。当调用时不提供参数时,str取值由默认参数 "" 替代,空字符串在内存中占一个字符'\0';若默认参数采用nullptr则会导致返回的是空指针,一不符合构造函数中的strlen调用,二不符合创建空字符串的概念;也就是一个默认构造的字符串对象 应该表示内容为空的字符串,而不是"未初始化的指针状态"。

  • 析构函数

    复制代码
            ~string()
            {
                delete[] _str;
                _str = nullptr;
                _size = _capacity = 0;
            }

    下标运算符重载

    复制代码
    char& operator[] (size_t pos) // 读写
    {
        assert(pos < _size);
        return _str[pos];
    }
    ​
    const char& operator[] (size_t pos) const // 只读
    {
        assert(pos < _size);
        return _str[pos];
    }

    迭代器

    复制代码
            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;
            }

    iterator :被定义为 char*,即指向字符的可变指针。它既可以读取字符,也可以通过解引用修改字符。

    const_iterator :被定义为 const char*,即指向常量字符的指针。它只能读取字符,不能通过它修改字符内容

    string的增删查改

    push_back,append,+=

    复制代码
    void reserve(size_t n)//异地扩容
    {
        if (n > _capacity)
        {
            char* tmp = new char[n + 1];
            strcpy(tmp, _str);
            delete[] _str;
            _str = tmp;
            _capacity = n;
        }
    }
    ​
    void push_back(char ch)
    {
        if (_size == _capacity)
        {
            //二倍扩容
            reserve(_capacity == 0 ? 4 : _capacity * 2);
        }
        _str[_size] = ch;
        _size++;
        _str[_size] = '\0';
    }
    ​
    void append(const char* str)
    {
        size_t len = strlen(str);
        if (_size + len > _capacity)
        {
            //至少扩容到_size + len
            reserve(_size + len);
        }
        strcpy(_str + _size, str);
        _size += len;
    }
    ​
    string& operator+=(char ch)
    {
        push_back(ch);
        return *this;
    }
    ​
    string& operator+=(const char* str)
    {
        append(str);
        return *this;
    }

insert

复制代码
void insert(size_t pos, size_t n, char ch)
{
    assert(pos <= _size);
    if (_size + n > _capacity)
    {
        reserve(_size + n);
    }
​
    //移动元素
    size_t end = _size;
    //此处无法处理pos为0的情况,
    //while (end >= pos)
    //{
    //  _str[end + n] = _str[end];
    //  --end;
    //}
​
    //解决方案1,强转int
    //int end = _size;
    //while (end >= (int)pos)
    //{
    //  _str[end + n] = _str[end];
    //  --end;
    //}
​
    //2 使用npos
    while (end >= pos&& end != npos)
    {
        _str[end + n] = _str[end];
        --end;
    }
​
​
    for (size_t i = 0; i < n; i++)
    {
        _str[pos + i] = ch;
    }
​
    _size += n;
}
​
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;
    while (end >= pos && end != npos)
    {
        _str[end + len] = _str[end];
        --end;
    }
    for (size_t i = 0; i < len; i++)
    {
        _str[pos + i] = str[i];
    }
​
    _size += len;
}

erase

复制代码
void erase(size_t pos, size_t len = npos)
{
    assert(pos <= _size);
    if (len = npos || pos + len >= _size)
    {
        _str[pos] = '\0';
        _size = pos;
        _str[_size] = '\0';
    }
    else
    {
        size_t end = pos + len;
        while (end <= _size)
        {
            _str[pos] = _str[end++];
        }
        _size -= len;
    }
}

find

复制代码
size_t find(char ch, size_t pos = 0)
{
    assert(pos < _size);
    for (size_t i = 0; i < _size; i++)
    {
        if (_str[i] == ch)
        {
            return i;
        }
    }
    return npos;
}
​
size_t find(const char* str, size_t pos = 0)
{
    assert(pos < _size);
​
    const char* ptr = strstr(_str, str);
    if (ptr) return ptr - _str;
    else return npos;
    return npos;
}

substr

复制代码
string substr(size_t pos = 0, size_t len = npos)
{
    assert(pos < _size);
​
    size_t n = len;
    if (len == npos || pos + len > _size)
    {
        n = _size - pos;
    }
​
    string tmp;
    tmp.reserve(n);
    for (size_t i = pos; i < pos + n; i++)
    {
        tmp += _str[i];
    }
​
    return tmp;//默认浅拷贝,需自定义拷贝构造
}
​
string(const string& s)
    : _str(s._str)          
    , _size(s._size)
    , _capacity(s._capacity)
{}

流插入和流提取

复制代码
    ostream& operator<<(ostream& out, const string& s)
    {
        for (size_t i = 0; i < s.size(); i++)
        {
            out << s[i];
        }
        return out;
    }
​
    istream& operator>>(istream& in, string& s)
    {
        char ch = in.get();
        //in >> ch; 遇到空格和\n截至
        char buff[128] = { '\0' };
        int i = 0;
        while (ch != ' ' || ch != '\n')
        {
            buff[i++] = ch;
            if (i == 127)
            {
                buff[i] = '\0';
                s += buff;
                i = 0;
            }
        }
​
        if (i != 0)
        {
            buff[i] = '\0';
            s += buff;
        }
​
        return in;
    }
相关推荐
kkeeper~4 小时前
0基础C语言积跬步之数据在内存中的存储
c语言·数据结构·算法
2401_868534784 小时前
论企业网络设计
数据结构
wabs6665 小时前
关于贪心算法的一些自我总结【力扣45.跳跃游戏II】【灵感来源:代码随想录】
算法·贪心算法·复盘
2401_876964135 小时前
【湖北专升本】2026湖北专升本真题PDF+备考资料汇总
数据结构·人工智能·经验分享·深度学习·算法·计算机视觉
嗝o゚6 小时前
CANN GE 算子融合——融合算法与调度策略
算法·昇腾·cann·ge
小江的记录本6 小时前
【JVM虚拟机】垃圾回收GC:垃圾回收算法:标记-清除、标记-复制、标记-整理、分代收集(附《思维导图》+《面试高频考点清单》)
java·jvm·后端·python·算法·安全·面试
Ulyanov8 小时前
用声明式语法重新定义Python桌面UI:QML+PySide6现代开发入门(一)
开发语言·python·算法·ui·系统仿真·雷达电子对抗仿真
数据科学小丫8 小时前
特征工程处理
人工智能·算法·机器学习
z落落8 小时前
C#参数区别
java·算法·c#
c238569 小时前
vector(下)
数据结构·算法