前言
链表的应用类题目,熟悉C++ STL中list容器的相关接口。链表的特性回顾:
- 改查:顺序表支持随机访问,链表不可以随机访问,只能顺序访问。
- 增删:顺序表在头部和中部增删需要移动数据,效率低。链表在任意位置支持O(1)增删。
一、题目分析
实现一个带光标的文本编辑器,光标可能处于文本的任何位置,即光标前后可以存在或不存在文本。实现TextEditor类,并实现以下接口:
上述接口总结起来就是需要对记录文本的容器的指定位置进行插入、删除操作。频繁对容器某个位置的前后进行插入和删除操作,考虑采用链表实现该类,采用STL中的list容器(双向链表)。
二、代码实现
class TextEditor{
list<char> l;
list<char>::iterator cur; //指向光标后一位字符
public:
TextEditor():cur(l.begin()){}
void addText(string text){
for(char ch : text){
l.insert(cur, ch);
}
}
int deleteText(int k){
int count = 0;
for(; cur != l.begin() && count < k; ++count){
l.erase(prev(cur));
}
return count;
}
string toString(){
string res;
list<char>::iterator tmp = cur;
for(int k = 10; tmp != l.begin() && k > 0; --k){
res.push_back(*(prev(tmp)));
tmp = prev(tmp);
}
reverse(res.begin(), res.end());
return res;
}
string cursorLeft(int k) {
for(; cur != l.begin() && k > 0; --k){
--cur;
}
return toString();
}
string cursorRight(int k) {
for (; cur != l.end() && k > 0; --k)
cur = next(cur);
return toString();
}
};
三、STL list接口
- 指定位置插入新节点
list.insert(it, val); //在it指向位置前面插入值为val的新节点
list.insert(it, n, val); //在it指向位置前面插入n个值为val的新元素
- 删除指定位置/指定范围的节点
iterator erase(iterator it);
iterator erase(iterator first, iterator last); //范围左闭右开
函数返回删除节点的下一个节点的迭代器。
四、迭代器相关操作
- 获取当前迭代器前方相距n位的迭代器
BidirectionalIterator prev(BidirectionalIterator it, typename iteraor_traits<BidirectionalIterator>::differnect_type n =1);
- 获取当前迭代器后方相距n位的迭代器
ForwardIterator next(FrowardIterator it, typename iterator_traits<ForwardIterator>::difference_type n = 1);
- 将迭代器向前/后移动n位
void advance(InputIterator& it, Distance n);
n为负数时迭代器向前移动。