【C++】—— string模拟实现(二)

简介: 【C++】—— string模拟实现

2、insert、erase

       insert重载也比较多,比较冗余;这里也只实现其中的一部分;

       erase这里只实现一个

//insert 、erase
void insert(size_t pos, const string& str)
{
  assert(pos >= 0 && pos < _size);
  size_t len = str._size;
  size_t n = _size + len;
  if (n > _capacity)
  {
    reserve(n);
  }
  //挪动数据
  for (size_t i = n; i >= pos + len; i--)
  {
    _str[i] = _str[i - len];
  }
  memcpy(_str + pos, str._str, str._size);
  _size += str._size;
  _str[_size] = '\0';
}
void insert(size_t pos, const char* s)
{
  assert(pos >= 0 && pos < _size);
  size_t len = strlen(s);
  size_t n = _size + len;
  if (n > _capacity)
  {
    reserve(n);
  }
  //挪动数据
  for (size_t i = n; i >= pos + len; i--)
  {
    _str[i] = _str[i - len];
  }
  memcpy(_str + pos, s, len);
  _size += len;
  _str[_size] = '\0';
}
void insert(size_t pos, size_t n, char c)
{
  assert(pos >= 0 && pos < _size);
  if (_size + n > _capacity)
  {
    reserve(_size + n);
  }
  //挪动数据
  for (size_t i = _size+n; i >= pos + n; i--)
  {
    _str[i] = _str[i - n];
  }
  for (size_t i = 0; i < n; i++)
  {
    _str[pos + i] = c;
  }
  _size += n;
  _str[_size] = '\0';
}
void erase(size_t pos, size_t len = npos)
{
  assert(pos >= 0 && pos < _size);
  if (len == npos)
  {
    _str[0] = '\0';
    _size = 0;
    return;
  }
  for (size_t i = pos; (len + i) < _size; i++)
  {
    _str[i] = _str[i + len];
  }
  _size -= len;
  _str[_size] = '\0';
}

       3、find

    //find
    size_t find(const string& str, size_t pos = 0)
    {
      assert(pos >= 0 && pos < _size);
      char* tmp = strstr(_str + pos, str._str);
      if (tmp == nullptr)
      {
        return -1;
      }
      return tmp - _str;
    }
    size_t find(const char* s, size_t pos = 0)
    {
      assert(pos >= 0 && pos < _size);
      char* tmp = strstr(_str + pos, s);
      if (tmp == nullptr)
      {
        return -1;
      }
      return tmp - _str;
    }
    size_t find(char c, size_t pos = 0)
    {
      assert(pos >= 0 && pos < _size);
      for (size_t i = pos; i < _size; i++)
      {
        if (_str[i] == c)
        {
          return i;
        }
      }
      return -1;
    }

       4、swap

       swap作为string的成员函数,交换两个string类类型的对象。

    //swap
    void swap(string& str)
    {
      Swap(_str, str._str);
      Swap(_size, str._size);
      Swap(_capacity, str._capacity);
    }

       这里swap函数内部也可以调用库里面的swap模版(这里我自己写了一个模版Swap)

有了swap函数,上面赋值运算符重载中就可以这样写了:

    string& operator= (const string& str)
    {
      string tmp(str);
      swap(tmp);
      return *this;
    }

四、字符串操作函数

       1、c_str

       c_str()函数返回string类对象中的字符串;

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

       2、substr

       获得,sting对象中字符串的子串。

//substr
string substr(size_t pos = 0, size_t len = npos) const
{
  assert(pos >= 0 && pos < _size);
  size_t n = 0;
  if (len == npos || pos + len > _size)
  {
    n = _size - pos;
  }
  else
  {
    n = len;
  }
  string ret;
  for (size_t i = 0; i < n; i++)
  {
    ret += _str[pos + i];
  }
  return ret;
}

五、其他成员函数

       

       这里max_size是返回容器可以容纳的最大元素的数量,这里就不进行实现了。

reserve在增加元素前已经实现了。(扩容)

//其他成员函数
size_t size() const
{
  return _size;
}
size_t length()const
{
  return _size;
}
size_t capacity()const
{
  return _capacity;
}
void clear()
{
  _str[0] = '\0';
  _size = 0;
}
bool empty()const
{
  return _size == 0;
}
void resize(size_t n)
{
  if (n > _capacity)
  {
    reserve(n);
  }
  _size = n;
  _str[_size] = '\0';
}
void resize(size_t n, char c)
{
  if (n > _capacity)
  {
    reserve(n);
  }
  for (size_t i = _size; i < n; i++)
  {
    _str[i] = c;
  }
  _size = n;
  _str[_size] = '\0';
}

       

六、流插入、流提取

       因为成员函数有一个隐藏的this指针,会和istream 和istream 类对象抢占第一个参数的位置,所以我们不能将流插入和流提取写成string类的成员函数。

       string中实现了访问元素方成员函数,就可以不将流插入、流提取写成string类的友元函数。

       1、流插入运算符重载

  std::ostream& operator<<(std::ostream& out, const HL::string& str)
  {
    //for (int i = 0; i < str.size(); i++)
    //{
    //  out << str[i];
    //}
    //return out;
    for (auto ch : str)
    {
      out << ch;
    }
    return out;
  }

       2、流提取运算符重载

       1、 s.clear()清理缓冲区(上次cin流提取的剩余);

       2、 创建一个数组,防止多次去开空间(输入到128或者输入结束(‘ ’或者‘\n’)才添加到str中)。

       3、下面的代码处理缓冲区的空格。

       char ch;
       ch = in.get();
       while (ch == ' ' || ch == '\n')
       {
           ch = in.get();
       }

       4、最后循环里if是遇到空格或者换行结束,将s中输入添加到s中,末尾添加'\0'。

     

std::istream& operator>>(std::istream& in, HL::string& str)
{
  char s[128] = { 0 };
  char ch;
  ch = in.get();
  while (ch == ' ' || ch == '\n')
  {
    ch = in.get();
  }
  str.clear();
  int i = 0;
  while (ch != '\n')
  {
    s[i] = ch;
    i++;
    if (i == 127)
    {
      s[i] = '\0';
      str += s;
      i = 0;
    }
    ch = in.get();
  }
  if (i)
  {
    str += s;
  }
  return in;
}
相关文章
|
25天前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
17天前
|
存储 关系型数据库 分布式数据库
GraphRAG:基于PolarDB+通义千问+LangChain的知识图谱+大模型最佳实践
本文介绍了如何使用PolarDB、通义千问和LangChain搭建GraphRAG系统,结合知识图谱和向量检索提升问答质量。通过实例展示了单独使用向量检索和图检索的局限性,并通过图+向量联合搜索增强了问答准确性。PolarDB支持AGE图引擎和pgvector插件,实现图数据和向量数据的统一存储与检索,提升了RAG系统的性能和效果。
|
4天前
|
JSON 自然语言处理 数据管理
阿里云百炼产品月刊【2024年9月】
阿里云百炼产品月刊【2024年9月】,涵盖本月产品和功能发布、活动,应用实践等内容,帮助您快速了解阿里云百炼产品的最新动态。
阿里云百炼产品月刊【2024年9月】
|
1天前
|
人工智能 Rust Java
10月更文挑战赛火热启动,坚持热爱坚持创作!
开发者社区10月更文挑战,寻找热爱技术内容创作的你,欢迎来创作!
256 12
|
19天前
|
人工智能 IDE 程序员
期盼已久!通义灵码 AI 程序员开启邀测,全流程开发仅用几分钟
在云栖大会上,阿里云云原生应用平台负责人丁宇宣布,「通义灵码」完成全面升级,并正式发布 AI 程序员。
|
21天前
|
机器学习/深度学习 算法 大数据
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
2024“华为杯”数学建模竞赛,对ABCDEF每个题进行详细的分析,涵盖风电场功率优化、WLAN网络吞吐量、磁性元件损耗建模、地理环境问题、高速公路应急车道启用和X射线脉冲星建模等多领域问题,解析了问题类型、专业和技能的需要。
2582 22
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
|
3天前
|
存储 人工智能 搜索推荐
数据治理,是时候打破刻板印象了
瓴羊智能数据建设与治理产品Datapin全面升级,可演进扩展的数据架构体系为企业数据治理预留发展空间,推出敏捷版用以解决企业数据量不大但需构建数据的场景问题,基于大模型打造的DataAgent更是为企业用好数据资产提供了便利。
169 2
|
1天前
|
编译器 C#
C#多态概述:通过继承实现的不同对象调用相同的方法,表现出不同的行为
C#多态概述:通过继承实现的不同对象调用相同的方法,表现出不同的行为
101 65
|
21天前
|
机器学习/深度学习 算法 数据可视化
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
2024年中国研究生数学建模竞赛C题聚焦磁性元件磁芯损耗建模。题目背景介绍了电能变换技术的发展与应用,强调磁性元件在功率变换器中的重要性。磁芯损耗受多种因素影响,现有模型难以精确预测。题目要求通过数据分析建立高精度磁芯损耗模型。具体任务包括励磁波形分类、修正斯坦麦茨方程、分析影响因素、构建预测模型及优化设计条件。涉及数据预处理、特征提取、机器学习及优化算法等技术。适合电气、材料、计算机等多个专业学生参与。
1578 16
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
|
5天前
|
Linux 虚拟化 开发者
一键将CentOs的yum源更换为国内阿里yum源
一键将CentOs的yum源更换为国内阿里yum源
257 2