算法入门经典第六章 例题6-4 破损的键盘
你在输入文章的时候,键盘上的Home键和End键出了问题,会不定时的按下。
给你一段按键的文本,其中’[‘表示Home键,’]’表示End键,输出这段悲剧的文本。
思路:使用链表来模拟,遇到Home键,就将后边的文本插入到这段文本的最前边,遇到
End键,就插入到这段文本的最后边。但是用链表会用到指针,过程比较繁琐。这里用一个
Next数组模拟指向,Next[i]表示当前显示屏中s[i]右边的字符下标。再用一个cur表示当前
光标的位置,last表示最后一个字符的记录位置,这样遇到End键,就能直接找到光标下一
个指向的字符位置了。
Sample Input
This_is_a_[Beiju]_text
[[]][][]Happy_Birthday_to_Tsinghua_University
Sample Output
BeijuThis_is_a__text
Happy_Birthday_to_Tsinghua_University
//借助于链表的思想,设定一个next,使得每个元素与下一个元素有一定的关联,传统意义上的链表多用指针来表示,但是在算法竞赛中,使用指针实在不是上上之选,而且也过于麻烦,因此我们这样假定: //s[ ]:输入的样本为字符数组,s[0]设为0,字符从s[1]开始输入 //s[ ]:输入的样本为字符数组,s[0]设为0,字符从s[1]开始输p[ ]:输出的样本为字符数组next[ ]:s[next[i]]=p[i+1] //cur=0表示当前光标位置 //光标位于cur号字符的前面 //为了方便起见,常常在链表第一个元素之前放一个虚拟节点 #include <stdio.h> #include <stdlib.h> #include<cstring> using namespace std; const int maxn=10000+5; int last,cur,nextt[maxn]; char s[maxn]; int main() { while(scanf("%s",s+1)==1) { int n=strlen(s+1); last=cur=0; nextt[0]=0;//next[i]存储的是s[i]右边的字符编号 for(int i=1;i<=n;i++) { char ch=s[i]; if(ch=='[') cur=0;//光标移到位置0 else if(ch==']') cur=last;//光标移到位置last else{ nextt[i]=nextt[cur];//把现在光标所在位置的编号传给nextt 没有遇到[以前,这里i=cur+1; nextt[cur]=i;//记录之前光标cur的位置放在next[i],next[cur]赋值为输出字符的编号 if(cur==last) last=i; cur=i;//移动光标 } } for(int i=nextt[0];i!=0;i=nextt[i]) printf("%c",s[i]); printf("\n"); } return 0; }