题目大意:你在输入文章的时候,键盘上的Home键和End键出了问题,会不定时的按下。给你一段按键的文本,其中'['表示Home键,']'表示End键,输出这段悲剧的文本。
如:abc[de]f 则输出deabcf
分析:用next[k]来表示k的下一个字符的序号,cur表示当前字符序号,last表示最后一个字符序号。下面一步步来讲解怎么做
首先,为了方便起见,输入的字符串从s+1开始,即s[1]是第一个字符,且开始时,next[0]=0;
拿例子来说一下过程:
a b c [ d e ] f
0 1 2 3 4 5 6 7 8
i=1: next[1]=next[0]=0 ; next[0]=1 (此时0->1) last=1; cur=1
i=2: next[2]=next[0]=0 ; next[1]=2 (此时0->1->2) last=2; cur=2
i=3: next[3]=next[2]=0 ; next[2]=3 (此时0->1->2>3) last=3; cur=3
i=4: cur=0
i=5: next[5]=next[0]=1 ; next[0]=5 (此时0->5->1->2->3) last=3; cur=5
i=6: next[6]=next[5]=1 ; next[5]=6 (此时0->5->6->1->2->3) last=3; cur=6
i=7: cur=last=3
i=8: next[8]=next[3]=0 ; next[3]=8 (此时0->5->6->1->2->3->8) last=8; cur=8
在不是插入情况下(即i=1,2,3)时,每次处理i都先使next[i] = next[cur],这里是让next[i]为0,因为后面还没有数,然后next[cur] = i,是为了连接cur->i 这种情况下,要更新last和cur
在插入情况下(即i=5,6)时,cur变为0,可以理解为头节点,因为要在0和1之间插入5,相当于在头节点和第一个节点之间插入,这一步与链表的插入操作类似,即
next[5]=next[0],next[0]=5, i=6时同理
当出现]时,cur又变回last,再继续处理下一个字符时,因为之前next[last]一直都是为0(这时last=cur),所以又回到了不是插入情况下,next[i]=next[cur]=0,next[cur]=i
输出就从next[0]开始,然后i=next[i],一直到i=0,就说明这是最后一个字符
#include<cstring>
#include<iostream>
#define MAX 100005
using namespace std;
int main(){
char s[MAX];
int next[MAX];//在vj上提交next不能定义为全局数组,不然居然会编译错误
while(~scanf("%s", s+1)){//如果把~去掉居然会超时
int cur = 0, last = 0;
next[0] = 0;
int n = strlen(s+1);
for(int i = 1; i<=n; i++){
if(s[i] == '[') cur = 0;
else if(s[i] == ']') cur = last;
else{
next[i] = next[cur];
next[cur] = i;
if(last == cur) last = i;
cur = i;
}
}
for(int i = next[0]; i!=0; i = next[i]){
printf("%c", s[i]);
}
printf("\n");
}
return 0;
}