当前位置: 首页 > news >正文

Java编程实战20:设计一个文本编辑器

目录

  • 设计一个文本编辑器
    • 题目
      • 示例 1
      • 提示
    • 解答
      • 完整代码
        • 方法一:切片
        • 方法二:栈+双端队列(栈)
        • 方法三:双向链表

设计一个文本编辑器

题目

请你设计一个带光标的文本编辑器,它可以实现以下功能:

  • 添加:在光标所在处添加文本。
  • 删除:在光标所在处删除文本(模拟键盘的删除键)。
  • 移动:将光标往左或者往右移动。
    当删除文本时,只有光标左边的字符会被删除。光标会留在文本内,也就是说任意时候 0 < = c u r s o r . p o s i t i o n < = c u r r e n t T e x t . l e n g t h 0 <= cursor.position <= currentText.length 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 个字符。

提示

  • 1 <= text.length, k <= 40
  • text 只含有小写英文字母。
  • 调用 addText ,deleteText ,cursorLeft 和 cursorRight 的 总 次数不超过 2 ∗ 1 0 4 2 * 10^4 2104次。

解答

完整代码

方法一:切片

class TextEditor 
{
    Deque<Character> ll = new LinkedList<>();
    Deque<Character> rr = new LinkedList<>(); 

    public TextEditor() 
    {
    }
    
    public void addText(String text) 
    {
        for (int i = 0; i < text.length(); i ++)
        {
            ll.addLast(text.charAt(i));
        }
    }
    
    public int deleteText(int k) 
    {
        k = Math.min(ll.size(), k);
        for (int i = 0; i < k; i ++)
        {
            ll.pollLast();
        }
        return k;
    }
    
    public String cursorLeft(int k) 
    {
        k = Math.min(ll.size(), k);
        for (int i = 0; i < k; i ++)
        {
            char c = ll.pollLast();
            rr.addFirst(c);
        }

        StringBuilder SB = new StringBuilder();
        List<Character> tmp = new ArrayList<>();
        int Len = Math.min(ll.size(), 10);
        for (int i = 0; i < Len; i ++)
        {
            char c = ll.pollLast();
            SB.append(c);
            tmp.add(c);
        }
        for (int i = tmp.size() - 1; i > -1; i --)
        {
            ll.addLast(tmp.get(i));
        }
        return SB.reverse().toString();

    }
    
    public String cursorRight(int k) 
    {
        k = Math.min(rr.size(), k);
        for (int i = 0; i < k; i ++)
        {
            char c = rr.pollFirst();
            ll.addLast(c);
        }

        StringBuilder SB = new StringBuilder();
        List<Character> tmp = new ArrayList<>();
        int Len = Math.min(ll.size(), 10);
        for (int i = 0; i < Len; i ++)
        {
            char c = ll.pollLast();
            SB.append(c);
            tmp.add(c);
        }
        for (int i = tmp.size() - 1; i > -1; i --)
        {
            ll.addLast(tmp.get(i));
        }
        
        return SB.reverse().toString();
    }
}

/**
 * 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);
 */

方法二:栈+双端队列(栈)

class TextEditor 
{
    Deque<Character> ll = new LinkedList<>();
    Deque<Character> rr = new LinkedList<>(); 

    public TextEditor() 
    {
    }
    
    public void addText(String text) 
    {
        for (int i = 0; i < text.length(); i ++)
        {
            ll.addLast(text.charAt(i));
        }
    }
    
    public int deleteText(int k) 
    {
        k = Math.min(ll.size(), k);
        for (int i = 0; i < k; i ++)
        {
            ll.pollLast();
        }
        return k;
    }
    
    public String cursorLeft(int k) 
    {
        k = Math.min(ll.size(), k);
        for (int i = 0; i < k; i ++)
        {
            char c = ll.pollLast();
            rr.addFirst(c);
        }

        StringBuilder SB = new StringBuilder();
        List<Character> tmp = new ArrayList<>();
        int Len = Math.min(ll.size(), 10);
        for (int i = 0; i < Len; i ++)
        {
            char c = ll.pollLast();
            SB.append(c);
            tmp.add(c);
        }
        for (int i = tmp.size() - 1; i > -1; i --)
        {
            ll.addLast(tmp.get(i));
        }
        return SB.reverse().toString();

    }
    
    public String cursorRight(int k) 
    {
        k = Math.min(rr.size(), k);
        for (int i = 0; i < k; i ++)
        {
            char c = rr.pollFirst();
            ll.addLast(c);
        }

        StringBuilder SB = new StringBuilder();
        List<Character> tmp = new ArrayList<>();
        int Len = Math.min(ll.size(), 10);
        for (int i = 0; i < Len; i ++)
        {
            char c = ll.pollLast();
            SB.append(c);
            tmp.add(c);
        }
        for (int i = tmp.size() - 1; i > -1; i --)
        {
            ll.addLast(tmp.get(i));
        }
        
        return SB.reverse().toString();
    }
}

/**
 * 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);
 */

方法三:双向链表

class Node
{
    char val;
    Node prev;
    Node next;

    Node () {}
    Node (char val_)
    {
        val = val_;
    }

    Node insert(Node t)
    {
        t.prev = this;
        t.next = this.next;
        this.next = t;
        t.next.prev = t;
        return t;
    }

    void remove()
    {
        this.prev.next = this.next;
        this.next.prev = this.prev;
    }
}

class TextEditor 
{
    Node Head;
    Node p;

    public TextEditor() 
    {
        Head = new Node();
        Head.prev = Head;
        Head.next = Head;
        p = Head;
    }
    
    public void addText(String text) 
    {
        for (int i = 0; i < text.length(); i ++)
        {
            char c = text.charAt(i);
            p = p.insert(new Node(c));
        }
    }
    
    public int deleteText(int k) 
    {
        int cnt = 0;
        while (cnt < k && Head != p)
        {
            p = p.prev;
            p.next.remove();
            cnt ++;
        }
        return cnt;
    }
    
    public String cursorLeft(int k) 
    {
        int cnt = 0;
        while (cnt < k && Head != p)
        {
            p = p.prev;
            cnt ++;
        }

        StringBuilder SB = new StringBuilder();
        Node tmp = p;
        cnt = 0;
        while (cnt < 10 && Head != tmp)
        {
            SB.append(tmp.val);
            tmp = tmp.prev;
            cnt ++;
        }
        return SB.reverse().toString();
    }
    
    public String cursorRight(int k) 
    {
        int cnt = 0;
        while (cnt < k && p.next != Head)
        {
            p = p.next;
            cnt ++;
        }

        StringBuilder SB = new StringBuilder();
        Node tmp = p;
        cnt = 0;
        while (cnt < 10 && Head != tmp)
        {
            SB.append(tmp.val);
            tmp = tmp.prev;
            cnt ++;
        }
        return SB.reverse().toString();
    }
}

/**
 * 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);
 */

相关文章:

  • 嵌入式微功耗RTU的功能与特点介绍、技术参数详情
  • ubuntu 安装supervisord
  • C++11标准模板(STL)- 算法(std::prev_permutation)
  • 【Vue】利用v-model特性封装Dialog弹窗或可编辑窗口。
  • 微信公众号迁移,需要做些什么
  • 白话说Java虚拟机原理系列【第三章】:类加载器详解
  • C++——STL之list详解
  • 【Numpy基础知识】结构化数组
  • Android实现戴口罩人脸检测和戴口罩识别(附Android源码)
  • 作为码农的我,要怎么提高自己的收入?
  • SpringBoot系列之整合框架JUnit
  • 实测 | 海纳百川,华为OceanStor Pacific分布式存储为多元算力应用带来更优选择...
  • 如何在 Git 存储库中查找和恢复已删除的文件?
  • 终于有人把性能优化讲清楚了!阿里架构师推荐的Java性能权威指南
  • PS1文件执行
  • 获B轮融资 官栈如何打破薛定谔式“中式滋补”
  • 15、Mysql高级之并发参数调整
  • 智牛股_第9章_CEPH_Swift+文件上传与下载
  • 【Vue】源码—虚拟DOM和diff算法
  • R16 Dormant BWP