Broken Keyboard(悲剧文本)

你有一个键盘,键盘上所有的键都能正常使用,只是Home键和End键有时会自动按下。你并不知道这一情况,而是专心地打稿子,甚至连显示器都没开电源。当你打开显示器之后,展现在你面前的是一段悲剧文本。你的任务是根据给出的键盘上实际输入的内容,计算并输出这段悲剧文本(即显示器上展现的文本)

Input:

一行文本不超过1000000个字符,只包括字母、下划线、字符'['(表示Home键)和字符']'(表示End键盘)。

Output:

一个字符串,即符合题目描述的悲剧文本。

 

Example:

Input:

This_is_a_[Beijing]_tex

Output:

BeijingThis_is_a__text

___________________________________________________________________________________________________________

问题分析:

该问题最简单的想法是利用数组来保存这些数据,然后用一个变量来保存光标位置,输入一个字符相当于在数组中插入一个字符,但是没插入一个字符将要移动大量的数据,程序的开销会很大。

为了解决这个问题,我们可以利用静态链表解决这个问题

先用一个字符串将每个字符储存起来,s[1-n],对每个s[i]都会对应一个next[i]游标,储存的是下一个结点的下标,同时利用一个curr,表示光标位置,并用last记录最后元素位置,s[0]是一个虚拟字符,用作头结点。

#include<iostream>
#include<string>
using namespace std;

const int size=100000+1;

int last;       //显示屏上的最后一个字符
int cur;       //光标位置,总在当前s[i]的左方
char s[size];             //用以储存string

int main()
{
	int next[size]={0};           //每个s[i]的游标,初始化为0
	while(scanf("%s",s+1)==1)
	{
		//初始化
		int n=strlen(s+1); //真正的字符从s[1]开始,s[0]是一个虚拟字符
		last=0;                 
	    cur=0;
	    
		//重排next
		for(int i=1;i<=n;i++)
		{
			if(s[i]=='[')
				cur=0;      //home键
            else if(s[i]==']')
                cur=last;				//end键
     	    else
			{
				next[i]=next[cur];
				next[cur]=i;
			    if(cur==last)last=i;   //当从string的最后插入时,last要+1
				cur=i;
			}
		}
	
	    //输出
		for(int j=next[0];j!=0;j=next[j])  //依据next中指定的顺序输出
			cout<<s[j];
		cout<<endl;
	}
	
	return 0;
}

  

posted @ 2016-09-22 13:57  KennyRom  阅读(681)  评论(0编辑  收藏  举报