小明打字 (10分)
小明正使用Microsoft Word打一篇文档,文档只包含a-z的小写字母和空格,在打字过程中可能会一次或多次按下Home键、End键、←方向键、→方向键、Insert键、Backspace键。请编写程序,给定小明在键盘上按键的序列,输出小明屏幕上最终显示的文本。 提示:Home键会将当前光标移至文本开始位置,End键当前光标移至文本尾,←键和→键会使当前光标左移或右移一个位置(如果光标在文档头则无法左移,光标在文档尾则无法右移),Insert键会在插入和替换文本间切换(默认是插入状态),Backspace键会删除当前光标前的一个字符。
输入格式:
输入为不超过50000个字符,表示小明的按键序列。包含a-z的小写字母、空格以及字符[、]、{、}、-、=。其中字符“[”表示Home键,“]”表示End键,“{”表示←键,“}”表示→键,“-”表示Insert键,“=”表示Backspace键。
输出格式:
输出为在小明屏幕上最终显示的文本。最后一个字母后没有回车或换行。
样例
输入样例1:
jilin[i lofe{{-v-} ] universiti=y
输出样例1:
i love jilin university
输入样例2:
abcd[c-de
输出样例2:
cdecd
输入样例3:
[[]][][]happy=birthday
输出样例3:
happbirthday
输入样例4:
efg[bbb}}=}}}}=[{{{{a
输出样例4:
abbbe
限制
作者:朱允刚
单位:吉林大学
代码长度限制 : 16 KB
时间限制:25 ms
内存限制:10 MB
解题
题目时间限制为25毫秒,考察数据结构双向链表,解题过程注意维护好双向链表的删除与插入(特别注意首尾位置的删除与插入)
本题采用带空头节点的链表,方便在链表头的插入删除操作
代码
#include <algorithm> //7-1 小明打字 (10分)
#include <cstring>
#include <iostream>
using namespace std;
typedef struct LNode {
char ch;
LNode* next;
LNode* prev;
} * List;
int main() {
char ch;
List start, end, tmp; //带空头节点链表, 每次插入tmp后面
List L = new LNode();
start = L;
end = L;
tmp = L;
bool isInsert = true;
List ins;
while (scanf("%c", &ch) && ch != '\n') {
if (ch == '[') {
tmp = start;
} else if (ch == ']') {
tmp = end;
} else if (ch == '{') {
if (tmp->prev) tmp = tmp->prev;
} else if (ch == '}') {
if (tmp->next) tmp = tmp->next;
} else if (ch == '-') {
isInsert = !isInsert;
} else if (ch == '=') { //删除tmp
if (tmp->prev) {
List t = tmp;
tmp->prev->next = tmp->next;
if (tmp->next) {
tmp->next->prev = tmp->prev;
tmp = tmp->prev;
} else {
tmp = tmp->prev;
tmp->next = NULL;
}
delete t;
if (tmp->next == NULL) end = tmp; //如果是删除最后的, 更新end
}
} else { // tmp后面添加
ins = new LNode();
ins->ch = ch;
ins->next = tmp->next;
ins->prev = tmp;
tmp->next = ins;
tmp = ins;
if (tmp->next == NULL) end = tmp; //如果插入在最后, 更新end
if (!isInsert && tmp->next) { //如果是替换, 且tmp下一个存在, 再删除tmp下一个
List t = tmp->next;
if (t->next) {
tmp->next = t->next;
t->next->prev = tmp;
delete t;
} else { //删除元素在末尾
delete t;
end = tmp; //更新end
tmp->next = NULL;
}
}
}
// end->next = NULL; //保险, 但没必要
}
tmp = start->next;
while (tmp) {
printf("%c", tmp->ch);
tmp = tmp->next;
}
// 注意清理内存, 这里节省运行时间不清理
return 0;
}