每日一题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: