算法入门经典第六章 例题6-4 破损的键盘

你在输入文章的时候,键盘上的Home键和End键出了问题,会不定时的按下。

给你一段按键的文本,其中’[‘表示Home键,’]’表示End键,输出这段悲剧的文本。

思路:使用链表来模拟,遇到Home键,就将后边的文本插入到这段文本的最前边,遇到

End键,就插入到这段文本的最后边。但是用链表会用到指针,过程比较繁琐。这里用一个

Next数组模拟指向,Next[i]表示当前显示屏中s[i]右边的字符下标。再用一个cur表示当前

光标的位置,last表示最后一个字符的记录位置,这样遇到End键,就能直接找到光标下一

个指向的字符位置了。

Sample Input
This_is_a_[Beiju]_text
[[]][][]Happy_Birthday_to_Tsinghua_University
 
 
Sample Output
BeijuThis_is_a__text
Happy_Birthday_to_Tsinghua_University
//借助于链表的思想,设定一个next,使得每个元素与下一个元素有一定的关联,传统意义上的链表多用指针来表示,但是在算法竞赛中,使用指针实在不是上上之选,而且也过于麻烦,因此我们这样假定:
//s[ ]:输入的样本为字符数组,s[0]设为0,字符从s[1]开始输入
//s[ ]:输入的样本为字符数组,s[0]设为0,字符从s[1]开始输p[ ]:输出的样本为字符数组next[ ]:s[next[i]]=p[i+1]
//cur=0表示当前光标位置
//光标位于cur号字符的前面
//为了方便起见,常常在链表第一个元素之前放一个虚拟节点

#include <stdio.h>
#include <stdlib.h>
#include<cstring>
using namespace std;
const int maxn=10000+5;
int last,cur,nextt[maxn];
char s[maxn];
int main()
{
    while(scanf("%s",s+1)==1)
    {
        int n=strlen(s+1);
        last=cur=0;
        nextt[0]=0;//next[i]存储的是s[i]右边的字符编号
    for(int i=1;i<=n;i++)
    {
        char ch=s[i];
        if(ch=='[') cur=0;//光标移到位置0
        else if(ch==']') cur=last;//光标移到位置last
            else{
                nextt[i]=nextt[cur];//把现在光标所在位置的编号传给nextt    没有遇到[以前,这里i=cur+1;
                nextt[cur]=i;//记录之前光标cur的位置放在next[i],next[cur]赋值为输出字符的编号 
                if(cur==last) last=i;
                cur=i;//移动光标
            }
        }
        for(int i=nextt[0];i!=0;i=nextt[i])  
            printf("%c",s[i]);  
        printf("
");  
    }
         
        return 0;
    }  

 

原文地址:https://www.cnblogs.com/is-Tina/p/7405387.html