每日一题2296. 设计一个文本编辑器
2296. 设计一个文本编辑器
https://leetcode.cn/problems/design-a-text-editor/description/
好久没写了,感觉写的很屎 请你设计一个带光标的文本编辑器,它可以实现以下功能:
添加:在光标所在处添加文本。 删除:在光标所在处删除文本(模拟键盘的删除键)。 移动:将光标往左或者往右移动。 当删除文本时,只有光标左边的字符会被删除。光标会留在文本内,也就是说任意时候 0 <= cursor.position <= currentText.length 都成立。
请你实现 TextEditor 类:
TextEditor() 用空文本初始化对象。 void addText(string text) 将 text 添加到光标所在位置。添加完后光标在 text 的右边。 int deleteText(int k) 删除光标左边 k 个字符。返回实际删除的字符数目。 string cursorLeft(int k) 将光标向左移动 k 次。返回移动后光标左边 min(10, len) 个字符,其中 len 是光标左边的字符数目。 string cursorRight(int k) 将光标向右移动 k 次。返回移动后光标左边 min(10, len) 个字符,其中 len 是光标左边的字符数目。
示例 1: 输入: [“TextEditor”, “addText”, “deleteText”, “addText”, “cursorRight”, “cursorLeft”, “deleteText”, “cursorLeft”, “cursorRight”] [[], [“leetcode”], [4], [“practice”], [3], [8], [10], [2], [6]] 输出: [null, null, 4, null, “etpractice”, “leet”, 4, “”, “practi”]
解释:
TextEditor textEditor = new TextEditor(); // 当前 text 为 “ ” 。(’ ’ 字符表示光标) textEditor.addText(“leetcode”); // 当前文本为 “leetcode ” 。 textEditor.deleteText(4); // 返回 4 >// 当前文本为 “leet ” 。>// 删除了 4 个字符。 textEditor.addText(“practice”); // 当前文本为 “leetpractice ” 。 textEditor.cursorRight(3); // 返回 “etpractice” >// 当前文本为 “leetpractice ”. >// 光标无法移动到文本以外,所以无法移动。>// “etpractice” 是光标左边的 10 个字符。 textEditor.cursorLeft(8); // 返回 “leet” >// 当前文本为 “leet practice” 。>// “leet” 是光标左边的 min(10, 4) = 4 个字符。 textEditor.deleteText(10); // 返回 4 >// 当前文本为 “ practice” 。>// 只有 4 个字符被删除了。 textEditor.cursorLeft(2); // 返回 “” >// 当前文本为 “ practice” 。>// 光标无法移动到文本以外,所以无法移动。>// “” 是光标左边的 min(10, 0) = 0 个字符。 textEditor.cursorRight(6); // 返回 “practi” >// 当前文本为 “practi ce” 。>// “practi” 是光标左边的 min(10, 6) = >6 个字符。
我觉得这种困难难度主要在各种混合使用上,光标是我们日常生活中经常见到的,算是第一时间有思路的题 首先是写的操作,我最开始写错了,我天真的直接string+string拼接,后面才意识到应该是从光标开始的地方插入的,既然知道是插入就很简单了
void addText(string text) {
context.insert(pointer, text);
pointer = pointer + text.size();
}
接下来是删除操作,最一开始我记得有e开头的函数处理但是拼错了,后面干脆用substr,但是用substr又出现错误我不想改,才发现我一直忘记的是erase,erase填下标的情况是开始位置以及删除的数目
int deleteText(int k) {
int deleteNUM = min(k,pointer);
context.erase(pointer-deleteNUM,deleteNUM);
pointer -= deleteNUM;
return deleteNUM;
}
使用substr会超时
int deleteText(int k) {
int deletenum = min(k, pointer);
if (pointer == context.size()) {
context = context.substr(0, pointer - deletenum);
} else {
string contact_string1 = context.substr(0, pointer - deletenum);
string contact_string2 = context.substr(pointer);
context = contact_string1 + contact_string2;
}
pointer -= deletenum;
return deletenum;
}
左右移动光标的操作,还要输出其固定的内容,主要在于判断固定内容是输出多少
string cursorLeft(int k) {
pointer = max(0, pointer - k);
int start = max(0, pointer - 10);
return context.substr(start, pointer - start);
}
string cursorRight(int k) {
pointer = min(pointer + k, (int)context.size());
int start = max(0, pointer - 10);
return context.substr(start, pointer - start);
}
通过max来判断输出的起始位置(指针之前存不存在十位),而指针位置的判断不同,如果你是左移,则要找出最大的那个(自己脑子里想象一下,他是一个大于0的数),右移则是小于最小长度的数 整体代码
class TextEditor {
public:
string context;
int pointer = 0;
TextEditor() : context(""), pointer(0) {
}
void addText(string text) {
context.insert(pointer, text);
pointer = pointer + text.size();
}
int deleteText(int k) {
int deleteNUM = min(k,pointer);
context.erase(pointer-deleteNUM,deleteNUM);
pointer -= deleteNUM;
return deleteNUM;
}
string cursorLeft(int k) {
pointer = max(0, pointer - k);
int start = max(0, pointer - 10);
return context.substr(start, pointer - start);
}
string cursorRight(int k) {
pointer = min(pointer + k, (int)context.size());
int start = max(0, pointer - 10);
return context.substr(start, pointer - start);
}
};
/**
* Your TextEditor object will be instantiated and called as such:
* TextEditor* obj = new TextEditor();
* obj->addText(text);
* int param_2 = obj->deleteText(k);
* string param_3 = obj->cursorLeft(k);
* string param_4 = obj->cursorRight(k);
*/
Enjoy Reading This Article?
Here are some more articles you might like to read next:
- Google Gemini updates: Flash 1.5, Gemma 2 and Project Astra
- Displaying External Posts on Your al-folio Blog
- Graph RAG with Milvus —— 纯向量库造图的多跳推理
- Hierarchical Indices 层级索引 —— 先粗后细的两级检索
- HyDE 与 HyPE —— 假设检索技术的两个方向
- 二叉树刷题总结
- RAG 技术体系化分类——从 Pipeline 阶段到失败模式
- MemoRAG 记忆增强型 RAG 总结
- Microsoft GraphRAG 基于知识图谱的 RAG 总结
- Multimodal RAG with Captioning 图像描述型多模态 RAG 总结