Broken Keyboard (a.k.a. Beiju Text)
You’re typing a long text with a broken keyboard. Well it’s not so badly broken. The only problem with the keyboard is that sometimes the “home” key or the “end” key gets automatically pressed (internally).
You’re not aware of this issue, since you’re focusing on the text and did not even turn on the monitor! After you finished typing, you can see a text on the screen (if you turn on the monitor). In Chinese, we can call it Beiju. Your task is to find the Beiju
text.
Input
There are several test cases. Each test case is a single line containing at least one and at most 100,000 letters, underscores and two special characters ‘[’ and ‘]’. ‘[’ means the “Home” key is pressed internally, and ‘]’ means the “End” key is pressed internally.
The input is terminated by end-of-file (EOF).
Output
For each case, print the Beiju text on the screen.
Sample Input
This_is_a_[Beiju]_text [[]][][]Happy_Birthday_to_Tsinghua_University
Sample Output
BeijuThis_is_a__text Happy_Birthday_to_Tsinghua_University
【题意】很好猜
【分析】数组的优势是可以随机存取和在末尾添加删除数据,而当插入数据时(本题中实现“[”的home功能,将数据插入到开头),需要移动大量的数据,时间效率非常低;而链表的优势是可以在O(1)删除和插入数据。所以在需要频繁移动数据时,可以使用链表。
【说明】太久没有用链表了,熟悉一下实现方式,见注释。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxn=100005;
char s[maxn];
int last,cur,nxt[maxn];
int main(){
int i,len;
while(scanf("%s",s+1)==1){
len=strlen(s+1);
last=cur=0;//cur是光标位置,是下一次操作的位置
nxt[0]=0;//s[0]是虚拟位置,用于指向开头,末尾也会指向s[0]
for(i=1;i<=len;i++){
if(s[i]=='['){
cur=0;//下一次在s[0]位置之后,即始端插入新数据
}
else if(s[i]==']'){
cur=last;//下一次在last位置之后,即末端插入新数据
}
else{
nxt[i]=nxt[cur];//将s[i]->cur指向的位置;
//当cur->0时代表光标位置是上一次操作的末尾,末尾指向s[0]
nxt[cur]=i;//将cur->s[i]
//这两步使得cur->x变为cur->s[i]->x
if(cur==last)
last=i;//更新last的位置为当前
cur=i;//将s[i]的位置定为新的cur光标位置
}
}
for(i=nxt[0];i!=0;i=nxt[i]){
printf("%c",s[i]);
}
printf("\n");
}
return 0;
}