例题6-4 破损的键盘(悲剧文本) 单向链表

题目:破损的键盘

算法竞赛入门经典第二版 刘汝佳 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;
}

丢个图:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_42324771/article/details/87362475