题目:破损的键盘
算法竞赛入门经典第二版 刘汝佳 P145例题6-4
引入链表概念:
最简单的想法,用数组存储文本,遇到 ‘ [ ’时,插入到数组最前面,遇到‘ ] ’时,返回到数组最后面。
存在的问题:每插入一个字符可能会引起大量的字符移动,在数组中频繁移动元素是很低效的。
解决方法:链表
s[1~n]: 用于存储输入的字符串
next[i]: s[i]右边(下一个)字符的下标。以上题为例,如s[1]=‘T’,s[2]=‘h’,则next[1]=2。(s[2]的下标是2)
s[0]: 假设字符串s[1~n]的最前面有一个虚拟的s[0]。(为了方便,常在链表的第一个元素之前放一个虚拟结点)
next[0]: s[0]右边字符的下标,即第一个字符的下标
变量cur: 用于表示光标位置(当前位置)
s[cur]: 当前光标位置
s[last]: 最后一个字符
代码:
代码就是书上的原代码,只是注释自己加的(保佑我自己以后还看得懂)
#include<cstdio>
#include<cstring>
const int maxn=100000+5;
int last,cur,next[maxn];
char s[maxn];
int main()
{
while(scanf("%s",s+1)==1)//scanf("%s",s+1)等同于scanf("%s",&s[1])
{
int n=strlen(s+1);
last=cur=0;
next[0]=0;
for(int i=1;i<=n;i++)
{
char ch=s[i];
if(ch=='[')cur=0;//屏幕最左边
else if(ch==']')cur=last;//屏幕最右边
else
{
next[i]=next[cur];
next[cur]=i;
if(cur==last)last=i;
cur=i;//移动光标
}
}
for(int i=next[0];i!=0;i=next[i])
printf("%c",s[i]);
printf("\n");
}
return 0;
}
丢个图: