C语言解题:破损的键盘

题目描述

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

输入

输入包含多组数据,每组数据占一行,包含不超过100000个字母、下划线、字符"["或者字符"]",其中字符"["表示Home键,"]"表示End键。

输出

每组输出占一行,输出正确的文本。

样例输入

This_is_a_[beijv]_text
[[]][][]Happy_Birthday_to_Tsinghua_University

样例输出

BeijvThis_is_a__text
Happy_Birthday_to_Tsinghua_University

做题算法思路 

(1)最简单的想法就是用数组保存这段文本,很可惜这样做代码会超时。因为这样改变字符在数组中的顺序会引起大量字符移动,非常消耗时间。

(2)用链表存储字符,链表之间的节点交换很轻松。

(3)数组实现链表方法更好,避免了查找链表数据的时候需要遍历链表,这道题不需要查找数据,所以两种方法都可以达到目的。

方法一:数组实现链表(简洁且难)

#include<cstdio>
#include<cstring>
const int maxn = 10000 + 5;
int last,cur,next[maxn];//光标位于cur号字符的后面
char s[maxn];

int main(){
	while(scanf("%s",s+1)==1){
		int n=strlen(s+1);//输入保存在s[1],s[2]--中
		last=cur=0;
		next[0]=0; 
		
		for(int i=1;i<=n;i++){
			char ch=s[i];
			if(ch=='[') cur=0;
			else if(ch==']') cur=last;
			else {
				next[i]=next[cur];
				next[cur]=i;
				if(cur==last) last=i;//更新"最后一个字符"的编号
				cur=i; 
			}
		}
		for(int i=next[0];i!=0;i=next[i])
			printf("%c",s[i]);
		printf("\n");	
	} 
	return 0;
}

方法二:链表

#include<stdio.h>
#include<stdlib.h>
typedef char Typement;//给char取别名,这处改,处处改。 
typedef struct ch{
	Typement c;
	struct ch *next;//下一个字符 
}CH;
void fun(){
	Typement a;
	CH *headnew=(CH*)malloc(sizeof(struct ch)); //分配内存
	CH *realhead=headnew;
	headnew->next=(CH*)malloc(sizeof(struct ch));//给头节点的下一个节点分配内存 
	CH *head=headnew->next;//headnew是头节点为空,head为第一个节点 
	int k=0;
	while(scanf("%c",&a)==1){//接收数据 
	
		if(a=='\n')
		break;
		if(a=='['){//如果是home回到头节点 
			k=1;
			headnew=realhead;//如果出现这种情况   [  [   [ ]  ]  ] 括号包围括号情况 
			//上条语句就是把节点指向头节点 
			continue;		 
		}
		else if(a==']'){//如果是end回到尾节点
			k=0;
			continue;
		} 
		if(k==1){ //前面插入数据 
			CH *h=(CH*)malloc(sizeof(struct ch));
			h->c=a;
			h->next=headnew->next;
			headnew->next=h;
			headnew=h;	
		}
		if(k==0){//后面插入数据 
			head->c=a;
			head->next=(CH*)malloc(sizeof(struct ch));
			head=head->next;
		}
	}
	while(realhead->next!=head){//输出数据,只有节点和 
		printf("%c",realhead->next->c);
		realhead=realhead->next;
	}
	printf("\n");
}
int main(){
	while(1){
		fun();
	}
}

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

算不出来没办法

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值