Broken Keyboard (a.k.a. Beiju Text) 思路

时间:2023-03-09 06:27:06
Broken Keyboard (a.k.a. Beiju Text) 思路

问题:You’re typing a long text with a broken keyboard. Well it’s not so badly broken. The only problem with the keyboard is that sometimes the “home” key or the “end” key gets automatically pressed (internally). You’re not aware of this issue, since you’re focusing on the text and did not even turn on the monitor! After you finished typing, you can see a text on the screen (if you turn on the monitor). In Chinese, we can call it Beiju. Your task is to find the Beiju text.

输入:

There are several test cases. Each test case is a single line containing at least one and at most 100,000 letters, underscores and two special characters ‘[’ and ‘]’. ‘[’ means the “Home” key is pressed internally, and ‘]’ means the “End” key is pressed internally. The input is terminated by end-of-file (EOF).

输出:

For each case, print the Beiju text on the screen

示例输入

This_is_a_[Beiju]_text

[[]][][]Happy_Birthday_to_Tsinghua_University

示例输出

BeijuThis_is_a__text

Happy_Birthday_to_Tsinghua_University

题意:假如你在打字,home键和end键不定时就会被按下,用[代表home,用]代表end,最终打出来的结果是什么?

(home键功能:光标跳到行开始.end:光标跳到行末尾)

思路:

1.最简单的想法是用链表做,用一个指针记录当前输入光标,每读一个字母就加一个节点. 但是代码比较复杂,懒得敲,

另解2.

用字符串做.

假设 [ 是1, ] 是2,

定义一个变量mod存放这个状态,刚开始默认mod=2

把字符一个个的读到c数组.

如果再读到[ 或 ],就判断mod,

if(mod==2){
strcat (b,c);
更改mod为新状态;
memset将c置零;
} if(mod=1){
strcat(c,b);
strcpy(b,c);
更改mod为新状态;
memset将c置零;
}

 记得最后再多一步这个,把最后那段也放到b里.最后输出b即可.

另解3.确定字符串里哪部分先输出后输出

观察到输出时是最后面的 [后面的内容先输出,直到再遇到括号.其次是前一个[后面的内容,以此类推...等所有左括号的全输出完了,再把剩下的输出.

算法:

把字符串存到数组里:

Broken Keyboard (a.k.a. Beiju Text) 思路

先找到[字符的位置,存到b数组里,并把 [ 和] 都置0.注意,不要把]也存到b里.

Broken Keyboard (a.k.a. Beiju Text) 思路

然后根据b的索引,依次输出a[6]串,a[3]串,同时输出完就写0销毁,:

Broken Keyboard (a.k.a. Beiju Text) 思路

最后把剩下的输出即可,用putchar一个个的输出.

代码:

#include<stdio.h>
#include<string.h>
int main()
{
int b[100002];//存放 [ 的位置
char a[100002];//存放字符串
int k,i,lena;
while(gets(a)){//gets遇到EOF就返回0
k=1;
lena=strlen(a);
for(i=0;i<lena;i++){
if(a[i]=='['||a[i]==']'){
if(a[i]=='[') b[k++]=i; //把第K个 [ 的位置序号放到b[k]
a[i]='\0';//把[ ]位置写0
}
}
k--;//消去多加的那个 while(k){ //从最右边的 [ 开始,依次输出
printf("%s",a+b[k]+1);
memset(a+b[k]+1,0,strlen(a+b[k]+1));//输出完就写0销毁,防止下次重复输出
k--;
} for(i=0;i<lena;i++){//把剩下没有前置的字符全输出
if(a[i]!='\0') putchar(a[i]);
} putchar(10);//换行
}
return 0;
}

我用的第三种方法,注意memset的使用,以及循环的控制即可.