《算法竞赛入门经典》一破损的键盘(又名:悲剧文本)(Broken Keyboard)

 问题描述:

       你有一个破损的键盘。键盘上所有的键都可以正常工作,但有时候Home键或者End键会自动按下。你并不知道键盘存在这一问题,而是专心打稿子,甚至连显示器都没打开。当你打开显示器后,展现在你面前的是一段悲剧文本。你的任务是在打开显示器之前计算出这段悲剧文本。

       输入包含多组数据。每组数据占一行,包含不超过100000个字母、下划线、字符“【”或者“】”。其中字符“【”表示Home键,“】”表示End键。输入结束标志为文件结束符(EOF)。输入文件不超过5MB。对于每组数据,输出一行,即屏幕上的悲剧文本。

样例输入:

This_is_a_[Beiju]_text

样例输出:

BeijuThis_is_a_text

分析:(数据结构一链表的简单实现)

1.本题最简单的想法就是直接开数组保存,再用pos保存光标位置,但是由于数组中插入元素操作的时间复杂度为O(n),当数据量过大时时间复杂度爆炸。

2.因此我们可以运用数组模拟链表来保存字符。创建一个next数组来保存输出的顺序,cur表示模拟当前光标的位置,last表示文本末端。

这道题我当时对着书上的代码看了半天,也用手模拟着跑过好几次,感觉也是很玄乎Orz..

 话不多说,直接上代码

复制代码
 1 #include <stdio.h> 2 #include <string.h> 3 #define MAX 100005 4 char s[MAX];  5 int next[MAX];  6 int main()  7 {  8     while(scanf("%s",s+1)!=EOF)  9     { 10         int i,cur=0,last=0,len=strlen(s+1);             11         next[0]=0; 12         for(i=1;i<=len;i++) 13         { 14             char ch=s[i]; 15             if(ch=='[') cur=0; 16             else if(ch==']') cur=last; 17             else 18             { 19                 next[i]=next[cur];                //类似于  i->next=cur->next;cur->next=i; 20                 next[cur]=i; 21                 if(cur==last) last=i; 22                 cur=i; 23             } 24         } 25         for(i=next[0];i!=0;i=next[i])        //类似于通过i=next[i]来访问数组26             printf("%c",s[i]); 27         printf("\n"); 28     } 29     return 0; 30     31 } 
关键字:
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信