一、resize
昨天说这个的时候没有考虑到缩小范围时咋处理,然后发现报错了,接着我调试发现缩小就不能正常执行了,因为用的是strcap所以临时的字符串就会在拷贝回去时就会死循环一直拷贝,就造成了越界访问了,然后就卡死了,这里我去查了一下发现resize,这个在缩小时不会释放地址,只是删除数据,这样就可以,如下方代码所示就是我想出改进的方法,就是判断当n>=的时候才正常进行判断,然后在经过测试发现可以,如下方图二。
void resize(size_t n,char c ='\0') { if (n >=_size) { char* tmp = new char[n + 1]; strcpy(tmp, _str); while (n - _size - 1) { tmp[_size] = c; _size++; } delete[] _str; _str = tmp; _capacity = n; _str[++_size] = '\0'; } _size = n; _str[_size] = '\0'; }
二、insert
这里上篇中只用了中间插入忘了考虑在头位置插入的情况,这时就会出现当end为-1时就会因为类型提升就变成最大的整数,就会出现卡死,所以这里选择的解决方案就是给end赋值时+1然后当end等于pos时就在这位置插入数据就OK了,如下方代码和图片所示。
void insert(size_t pos, char ch) { assert(pos <= _size); if (_size + 1 > _capacity) { reserve(2 * _capacity); } size_t end = _size+1; while (end > pos) { _str[end + 1] = _str[end]; --end; } _str[pos] = ch; ++_size; }
然后还没有去写插入字符串,所以这里是计算了字符串的长度,然后利用把长度和size都赋值给end然后在进行判断挪动,也就是利用while这个和上个原理差不多然后利用strncpy进行拷贝数据,就能正常插入了,如下方代码和图片所示。
void insert(size_t pos,const char* str) { assert(pos <= _size); size_t len = strlen(str); if (_size + len > _capacity) { reserve(2 * _capacity); } size_t end = _size + len ; while (end > pos + len - 1) { _str[end] = _str[end - len]; --end; } strncpy(_str+pos, str,len); _size+=len; }
三、erase
这里也是需要能删除字符串,然后上文中写的是只能删除字符,所以这里是先判断要删除大小是否大于size,如果大于就从pos这里位置向后全部删除,这里是利用了-1进行缺省传值,不大于的话就利用strcpy进行拷贝,把需要删除的数据覆盖就可以了,测试结果如图,代码如下。
void erase(size_t pos, size_t len = -1) { assert(pos < _size); if (len == -1 || pos + len >= _size) { _str[pos] = '\0'; _size = pos; } else { strcpy(_str + pos, _str + pos + len); _size -= len; } }
四、思维导图