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

10340 文本编辑器(vim)

经验值:1600

时间限制:1000毫秒

内存限制:512MB

经开区2023年信息学竞赛试题

 不许抄袭,一旦发现,直接清空经验!

题目描述 Description

李明正在学习使用文本编辑器软件 Vim。与 Word、VSCode 等常用的键鼠配合使用的文本编辑器不同,Vim 采用了键盘操控+模式切换的设计。初始时用户处于普通模式,此时用户可以通过键盘输入命令执行光标移动等操作,或者输入特定命令进入到编辑模式;而在编辑模式中,用户可以从当前光标位置开始,向文本输入内容,然后按 ESC 键切换回普通模式。
李明学习到了普通模式的如下指令。其中(r, c)为当前光标的位置,即第r行 第c列,Lr表示第r行当前的长度,R为当前文本总行数,数学符号min{x, y}表示x与y的最小值,例如min{2,4} = 2:

|指令按键

(注意大小写)操作
h若c > 1,即光标不在最左侧,则将光标左移一格至(r, c − 1)
j若r < R,即光标不位于最后一行,则将光标下移一格至(r + 1, min{c, Lr+1})
k若r > 1,即光标不位于第一行,则将光标上移一格至(r − 1, min{c, Lr-1})
l若c < Lr,即光标不在当前行的最右侧,则右移一格至(r, c + 1)
a切换至编辑模式,将输入内容插入到光标当前位置的右侧
i切换至编辑模式,将输入内容插入到光标当前位置的左侧
A将光标移至本行最右侧的字符处,然后切换至编辑模式,将输入内容插入到光标当前位置的右侧。等价于 lll…a。
I将光标移至本行最左侧的字符处,然后切换至编辑模式,将输入内容插入到光标当前位置的左侧。等价于 hhh…i。

       从编辑模式按 ESC 键切换回普通模式时,光标位置位于编辑模式插入的最后一个字符处(假定每次进入编辑模式后至少向文本中插入一个字符)。初始时,Vim 处于普通模式,光标位置为(1,1)。
       假设当前文本如下,光标位置用粗斜体+下划线+红色标注。李明的键盘输入序列为 jlliHello^kIWorld^,其中^用于表示 ESC 键:

image.png


       对于李明的键盘操作,jll 表示下移一格再右移两格,光标按 A→H→I→I 的顺序移动(其中第二次右移因为触及本行末尾无事发生)。此时光标位置为(2,2),即第 2 行第 2 列。Vim 编辑器界面如下:

image.png


       之后 iHello^表示从当前光标位置进入编辑模式,将插入的内容 Hello 置于此时光标位置 I 的左侧,然后按 ESC 键返回普通模式。此时光标位置为(2,6),指向此次插入内容 Hello 的最后一个字符 o,Vim 编辑器界面如下。另外需注意,指令按键(例如本段示例中的小写字母 l)仅在普通模式下才表示编辑器控制指令,在编辑模式中则作为文本内容输入:

image.png


       然后按 k 键将光标移至上一行。由于上一行的长度小于当前光标所在的列数,因此光标被移到了上一行的末尾。此时光标位置为(1,3):

image.png


       最后一段 IWorld^表示,按 I 键将光标移至本行最左侧的字母 A 处,进入编辑模式并将文本 World 插入到字母 A 的左端,然后按 ESC 退出编辑模式,光标停在插入的最后一个字母 d 处,坐标为(1,5)。

image.png


       已知文本编辑器的初始内容,以及李明的键盘操作序列,你需要输出操作结束后,Vim 编辑器中的文本内容,以及最终光标所在的位置。

输入描述 Input Description

第一行是一个正整数N,表示初始时编辑器中文本的行数;之后N行,每行一个仅包含大小写字母的字符串,表示改行初始时的内容;之后一行为一个仅包含大小写字母和^的字符串,表示李明的键盘操作序列。输入保证操作序列结束后 Vim 处于普通模式,每次进入编辑模式时至少插入一个字符。

输出描述 Output Description

共N + 1行。前N行依次为操作结束后文本编辑器中每一行的内容,最后一行为两个正整数r, c,表示操作结束后光标的位置。

样例输入 Sample Input

样例一: 3 ABC HI OPQRS jlliHello^kIWorld^ 样例二: 3 ABC HI OPQRS jlliHello^kIWorld^jAXyz^jhhaUvw^

样例输出 Sample Output

样例一: WorldABC HHelloI OPQRS 1 5 样例二: WorldABC HHelloIXyz OPQUvwRS 3 6

数据范围及提示 Data Size & Hint

初始时第i行的长度为Li,操作序列的总长度为Lc。所有数据均满足: 1 ≤ N ≤ 100, 1 ≤ Li ≤ 100, 1 ≤ Lc ≤ 10′000
测试数据的分布如下:

占比附加限制
40%普通模式不含 a,i,A,I 指令
30%普通模式不含 a,i,I 指令
20%普通模式不含 a,i 指令
10%

提示与说明:
       注意区分数字 1、小写字母 l 与大写字母 I。本题中光标右移指令为小写字母 l,行首插入的指令为大写字母 I。
       本题目的细节(例如光标的移动策略)与现实中的 Vim 编辑器存在差异,作答时以本题的描述为准。

#include <iostream>
#include <vector>
#include <string>using namespace std;// Vim编辑器类
class VimEditor {
private:vector<string> text; // 文本内容pair<int, int> cursor; // 光标位置public:VimEditor(vector<string> initial_text) {text = initial_text;cursor = make_pair(0, 0);}void executeCommand(char command) {int r = cursor.first, c = cursor.second;int R = text.size();int Lr = text[r].length();if (command == 'h') {if (c > 0) {cursor.second = c - 1;}} else if (command == 'j') {if (r < R - 1) {cursor.first = r + 1;cursor.second = min(c, (int)text[r + 1].length());}} else if (command == 'k') {if (r > 0) {cursor.first = r - 1;cursor.second = min(c, (int)text[r - 1].length());}} else if (command == 'l') {if (c < Lr - 1) {cursor.second = c + 1;}} else if (command == 'a') {text[r].insert(c + 1, 1, ' ');cursor.second = c + 1;} else if (command == 'i') {text[r].insert(c, 1, ' ');cursor.second = c;} else if (command == 'A') {cursor.second = Lr - 1;text[r].insert(Lr, 1, ' ');cursor.second = Lr;} else if (command == 'I') {cursor.second = 0;text[r].insert(0, 1, ' ');}}void processInput(string input) {for (char command : input) {if (command == '^') {// 切换到普通模式continue;}executeCommand(command);}}void printEditorState() {for (string line : text) {cout << line << endl;}cout << cursor.first + 1 << " " << cursor.second + 1 << endl;}
};int main() {int N;cin >> N;cin.ignore(); // 忽略换行符vector<string> initial_text(N);for (int i = 0; i < N; i++) {getline(cin, initial_text[i]);}string input;getline(cin, input);VimEditor editor(initial_text);editor.processInput(input);editor.printEditorState();return 0;
}


http://www.mrgr.cn/news/58594.html

相关文章:

  • Pandas模块之垂直或水平交错条形图
  • C++音视频02:环境搭建
  • 玩转C++内存管理:从新手到高手的必备指南
  • mysql 安装
  • NVR管理平台EasyNVR多品牌NVR管理工具/设备多协议兼容性:摄像头拉流RTSP和GB28181的区别
  • 纳斯达克大屏投放:为什么越来越多的企业要投放纳斯达克户外广告
  • Swift 是一种由苹果公司开发的强大而直观的编程语言,主要用于开发 iOS、macOS、watchOS 和 tvOS 等苹果平台的应用程序。
  • C++中如何使用文件系统路径
  • AcWing 89:a^b ← 快速幂
  • 136.只出现一次的数字
  • 【开源项目】经典开源项目数字孪生工地——开源工程及源码
  • fpga系列 HDL: 竞争和冒险 01
  • 计算机网络:网络层 —— IPv4 协议的表示方法及其编址方法
  • python 线程间通信用什么手段
  • 微软投资比特币:将总资产1%投资于BTC?股东投票决定最终结果!
  • 洛谷 P1060 [NOIP2006 普及组] 开心的金明
  • C++ 移动语义
  • Vue学习记录之二十 postcss自定义插件及Unocss的使用
  • 遇到这3种接口测试问题,其实,你可以这么办~
  • 混个1024勋章
  • 2023年12月中国电子学会青少年软件编程(图形化)等级考试试卷(二级)答案 + 解析
  • CMU生成式人工智能大模型:从入门到放弃(九)
  • CMU生成式人工智能大模型:从入门到放弃(八)
  • 电机的旋转原理和发电原理!
  • 永恒之蓝漏洞利用复现
  • Oracle故障诊断(一线DBA必备技能)之ADRCI(一)