损坏的键盘(又名:悲剧文本)(Broken Keyboard)
在显示屏上盲打一段文字,在这过程中由于键盘的问题,Home键与end键会自动按下,显有一段文本,其中‘[’表示Home键按下,‘]’表示End键按下,求出显示屏上的文字排序
示例输入
This_is_a_[Beiju]_text
[[]][][]Happy_Birthday_to_Tsinghua_University
示例输出
BeijuThis_is_a__text
Happy_Birthday_to_Tsinghua_University
分析
解决方案是采用链表。
每输入一个字符就把他储存起来,设输入字符串是s[1~n],则可以用 nex[i] 表示在当前显示屏中**s[i]**右边的字符编号(即在s中的下标)。
为了方便起见,假设字符串s的最前面还有一个虚拟的 s[0] ,则 nex[0] 就可以表示显示屏中最左边的字符。 再用一个变量 cur 表示光标位置: 即当前光标位于 s[cur] 的右边。 cur = 0 说明光标位于“虚拟字符” s[0] 的右边, 即显示屏的最左边。
为了移动光标,还需要用另一个变量 last 表示显示屏的最后一个字符 s[last]
提示
常常在链表的第一个元素之前放一个虚拟结点。
源代码:
#include<iostream>
#include<cstring>
using namespace std;
const int maxn = 100000 + 5;
char s[maxn];
int last, cur, nex[maxn];
int main()
{
while (scanf("%s", s + 1) == 1)
{
memset(nex, 0, sizeof(nex));
int n = strlen(s + 1);
last = cur = 0;
for (int i = 1; i <= n; i++)
{
if (s[i] == '[')
{
cur = 0;
}
else if (s[i] == ']')
{
cur = last;
}
else
{
nex[i] = nex[cur];
nex[cur] = i;
if (cur == last)
{
last = i;
}
cur = i;
}
}
for (int i = nex[0]; i != 0; i = nex[i])
cout << s[i];
cout << endl;
}
return 0;
}