对于这道题,我使用了多个栈,如果可以将栈和队列一起使用,将变得简单许多。
算法解释:
举例:(1(2abc)),对于这个魔王语言,首先是处理内部括号,变为(12c2b2a2),再处理外括号,变为121a121b121c121,至此翻译完毕,这个题目的关键是从内部括号开始处理,我将使用栈的方法解决这一问题。
首先对于(1(2abc)),可以入先入栈(1),为))cba2(1(。
再将栈(1)中的内容入栈(2),遇到)时停止,同时将)出栈,则此时栈(1)中为),栈(2)中有(1(2abc。
此时我们找到了内部括号,再将栈(2)中的内容压入栈(3),至(停止,并且将(出栈,则栈(2)中为(1,栈(3)中为cba2。
此时我们找到了魔王语言中紧邻(的字符,借此,我们将可以利用第二条规则来解决问题,将栈(3)的内容根据要求压入栈(4),栈(4)中应为2a2b2c2。
至此解决了内部括号的翻译问题,再将栈(4)中的内容压入栈(3),即2c2b2a2(ps:如果会用队列,直接从对头出队列压入栈(1)更佳)。
再将 栈(3)和栈(2)的内容分步压入栈(1)。
则此时栈(1)中为)2a2b2c21(,重复上述操作即可,最后将完全翻译的栈(1)出栈打印即可。
PS:A,B要在处理完全部括号后处理,课本上的规则(1)(2)没有意义。
基本的思想是这样的,但是限于栈的功能,代码较为冗长。
吐槽:经过测试,xdoj中的测试点不仅没有任何特殊情况,如括号套括号问题,甚至只有一对括号,如果只是为了100分,可以采用更简单的方式。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct STNode//栈
{
char ch;
STNode* next;
}STNode, * LinkStack;
void Push(LinkStack* S, char c);
char Pop(LinkStack* S);
int main()
{
LinkStack S_1 = NULL;
LinkStack S_2 = NULL;
LinkStack S_3 = NULL;
LinkStack S_4 = NULL;
char a[100];
char ch;
int i = 0;
int flag = 1;
scanf("%s", a);
for (i = strlen(a) - 1; i >= 0; i--)
{
Push(&S_1, a[i]);
}
while (1)
{
while (S_1 != NULL)
{
if (S_1->ch == ')')
{
Pop(&S_1);
flag = 0;
break;
}
else
{
Push(&S_2, Pop(&S_1));
}
}
if (flag == 1)
{
break;
}
flag = 1;
while (S_2 != NULL)
{
if (S_2->ch == '(')
{
Pop(&S_2);
break;
}
else
{
Push(&S_3, Pop(&S_2));
}
}
if (S_3 != NULL)
{
ch = Pop(&S_3);
while (S_3 != NULL)
{
Push(&S_4, ch);
Push(&S_4, Pop(&S_3));
}
Push(&S_4, ch);
}
while (S_4 != NULL)
{
Push(&S_3, Pop(&S_4));
}
while (S_3 != NULL)
{
Push(&S_1, Pop(&S_3));
}
while (S_2 != NULL)
{
Push(&S_1, Pop(&S_2));
}
}
while (S_2 != NULL)
{
Push(&S_3, Pop(&S_2));
}
while (S_3 != NULL)
{
if (S_3->ch == 'B')
{
Pop(&S_3);
Push(&S_1, 't');
Push(&S_1, 'A');
Push(&S_1, 'd');
Push(&S_1, 'A');
}
else
Push(&S_1, Pop(&S_3));
}
while (S_1 != NULL)
{
if (S_1->ch == 'A')
{
Pop(&S_1);
Push(&S_2, 'e');
Push(&S_2, 'a');
Push(&S_2, 's');
}
else
Push(&S_2, Pop(&S_1));
}
while (S_2 != NULL)
printf("%c", Pop(&S_2));
return 0;
}
void Push(LinkStack* S, char c)//指向最后一个元素
{
LinkStack q = (LinkStack)malloc(sizeof(STNode));
q->ch = c;
q->next = (*S);
(*S) = q;
}
char Pop(LinkStack* S)
{
LinkStack q = (*S);
char c = q->ch;
(*S) = (*S)->next;
free(q);
return c;
}