各位好友, 上期 string 模拟实现 已初步完成,下面继续开战 ----->string --->删除 ~~ 插入 ~~ 查找
A.补充 头文件 “String.h”
//补充:string类---->模拟实现 ---->删除,插入,与查找
namespace UC
{
class string
{
public:
//·····
//从某一个位置,插入 n个字符
void insert(size_t pos; size_t n; char n)
{
assert(pos <= _size); //注意:位置合法性
if(_size + n > _capacity)
{
reserve(_size + n);
}
size_t end = _size;
while(end >= pos && end != npos)
{
//运用了值覆盖原理
_str[end + n] = _str[end];
--end;
}
for(size_t i = 0; i < n; i++)
{
_str[i + pos] = ch;
}
_size += n;
}
void insert(size_t pos, const char* str)
{
assert(pos <= _size); //注意:位置合法性
size_t len = strlen(str);
if(len + _size > _capacity)
{
reserve(len + _size);
}
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;
}
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;
while(end <= _size)
{
_str[pos++] = _str[end++];
}
_size -= len;
}
}
size_t find(const char* str, size_t pos = 0)
{
assert(pos < _size); //位置从到'\0'开始查找,没有任何意义
const char* ptr = strstr(pos + _str, str);
if(ptr)
{
return ptr - _str;
}
else
{
return npos;
}
}
private:
size_t _size;
size_t _capacity;
char* _str;
public:
const static size_t npos;
};
const size_t string::npos = -1; //难点
}
为了方便好友们, 有更好的观感体验, 现 附上有彩色的代码图样 !
(a1)insert 源码模拟 :>
对于插入字符串, 库里面给我们列出了许多实现方式 !下面仅仅 介绍两种 ---->最常见 ~~ 最常用的实现接口 !
-------->(1)insert n 个字符 <---------------> (2)insert 字符串<---------
(a2) insert 测试运行 :>
虽然上述实现 没有用到 “string&” 但是二者效果相同, 并且-->更加简洁 !不用写返回值 “return *this”
(b1) erase 源码模拟 : >
(b2) erase 测试运行 : >
(C1) find 源码模拟 : >
(C2) find 测试运行 : >
下面进入解析 :>
(1)pos 界线划定
注意:>只有整形类型才可以, 诸如其他类型等, double 就不可以了 (很奇怪的一种设计, 很无语):>😊
--------------------------->另外, 建议大家在用的时候, 声明 与定义要分开写 (通用写法, 不需要刻意记住)
修改版本 :>
------------->另外要注意:>别漏写了, 指明 命名空间 UC
-------->在 insert 中运用
-------->在 erase 中运用
-------->在 find 中运用
各位好友, 下面进入 解析逻辑 :>
(1)细节逻辑一:>“&&”(前后都为“真”才可以)(高中知识:>"😊😊)
插入数据, 是一个不断运用 “值覆盖原理”的过程
既要在过程中 ----->保持 每一次遍历循环之后, 结尾 end 有效合法性
又要保证 结尾 end ----->需要在空间的限度内(即不能越界访问);而 “或”的关系, 是有一个为真就可以进行
(2)细节逻辑二 :>“ || ”(前后有一个为假就会跳出, 但有一个为 真 就会继续)
删除数据,有两种情况:>
若是删除长度在 空间限度之内, 则仍然 运用了 “值覆盖原理” !只是此处的值是 空字符 !
若是删除长度超过了 空间限度, 意味着 起始位置 pos 之后的所有有效字符, 都需要消失 !
---------------------->只在 pos 位置添加一个结束字符 ‘ \0 ’ 即可 !这种情况非常简单 !
(3)细节逻辑三 :>运用 “strstr” 查找目标字符(串)
翻译 :>
返回指向 str1 中 str2 第一次出现的的指针,如果 str2 不是 str1 的一部分, 则会返回空指针 !
------------------------------------------>注意 :>匹配过程 不会包含 结束字符 ‘\0’ 但是会到此处停止 !
另外, 需要注意的一点 :>位置 pos 合法性, 这一次没有 “==” 是由于 pos 从 '\0' 开始查找, 没有意义 !
还有就是 “strstr(pos + _str, str)”中, 是否可以省略不用写 "_str" 答案当然是 不可以 !
----->原因在于:>虽然 一开始调用 “strstr()”接口, *_str == 0 ;看样子, 就算不写也没事 !
其实, 要注意, 查找的位置在哪里 ?即 是在哪一个字符串当中去 查找, 如果不写上的话, 会指代不明 !
举一个例子 :>
如果在 一个 main() 函数当中, 测试的是 多个变量, 那么就会造成 “strstr()”接口调用发生错误 !
各位好友, string 底层模拟实现已完成 !不过上述实现,还有一类大问题没有考虑到 !
------------>string 深拷贝
下一期, 将继续推进 string 模拟实现 过程 深浅 ~~ 拷贝 的探究 !敬请期待 !“😊😊