/**基本思路, 先把表达式转化成表达树表示, 然后根据查询, 找子树
可能导致Wrong answer 的原因: 乘幂算符号是右结合的?**/
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#define EXPR 1
#define TERM 2
#define FACTOR 3
#define PER 4
#define PARENTHESE 5
using namespace std;
struct ExprNode{
char value;
vector<ExprNode*> *children;
};
char lookAhead;
ExprNode* expr();
ExprNode* term();
ExprNode* factor();
ExprNode* per();
bool match(char c)
{
if (lookAhead == c) {
lookAhead = getchar(); return true; }
else return false;
}
ExprNode* expr()
{
ExprNode *p;
p = (ExprNode*) malloc(sizeof(ExprNode));
p->children = new vector<ExprNode*>();
p->children->push_back( term() );
p->value = '+';
while (lookAhead == '+' )
{
match('+');
p->children->push_back( term() );
}
return p;
}
ExprNode* term()
{
ExprNode *p;
p = (ExprNode*) malloc(sizeof(ExprNode));
p->children = new vector<ExprNode*>();
p->children->push_back( factor() );
p->value = '*';
while( lookAhead == '*' )
{
match('*');
p->children->push_back( factor() );
}
return p;
}
ExprNode* factor()
{
ExprNode *p;
p = (ExprNode*) malloc(sizeof(ExprNode));
p->children = new vector<ExprNode*>();
p->value = '^';
p->children->push_back( per() );
while ( lookAhead == '^' )
{
match('^');
p->children->push_back( per() );
}
return p;
}
ExprNode* per()
{
ExprNode *p;
p = (ExprNode*) malloc(sizeof(ExprNode));
p->children = new vector<ExprNode*>();
if (match('(')) {
p->value = PARENTHESE; p->children->push_back( expr()); match(')');
}
else
{
p->value = lookAhead;
match(lookAhead);
}
return p;
}
//“中序”遍历树
void inOrder(ExprNode* p)
{
if (p->value == PARENTHESE) printf("(");
if (p->children->size())
inOrder(p->children->at(0));
else if (p->value != PARENTHESE)
printf("%c", p->value);
for (int i = 1; i < p->children->size(); i++)
{
printf("%c",p->value);
inOrder(p->children->at(i));
}
if (p->value == PARENTHESE) printf(")");
}
void freeTree(ExprNode* p)
{
for (int i = 0; i < p->children->size(); i++)
freeTree(p->children->at(i));
delete p->children;
free(p);
}
//读入一个整数, 如果到行末, 返回false;
#define SPACE ' ';
bool getNum(int&d)
{
char c;
d = 0;
while ( isdigit(c = getchar()) )
{
d = d*10 + c - '0';
}
return c == SPACE;
}
//查找第 d 个子树
ExprNode* getExpr(ExprNode* p, int d)
{
if (d == 1)
{
while (p->children->size() < 2)
{
if (p->value == '+' || p->value == '*' || p->value == '^')
p = p->children->at(0);
else break;
}
return p->children->size() == 0 ? p : p->children->at(0);
}
while (p->children->size() < 2)
{
p = p->children->at(0);
}
//if (p->children->size() < d) printf("Error!/n");
return p->children->at(d-1);
}
//把整数转换成string
string toString(int d)
{
string s;
while(d > 0)
{
s.append(1, (char)(d%10+'0'));
d/=10;
}
reverse(s.begin(), s.end());
return s;
}
int main(int argc, char *argv[])
{
char name;
int n, d;
int t = 0;
while(true)
{
name = getchar();
if (name == '*') break;
//读 :=
getchar();getchar();
//构建树结构
lookAhead = getchar();
ExprNode *expression = expr();
//Test case 间加空行
if (t==0){ t++; }
else printf("/n");
printf("Expression %c:/n", name);
//inOrder(expression); printf("/n");
//e: 要查找的子树
ExprNode * e;
scanf("%d", &n);
getchar(); //newline char
for (int i = 0; i < n; i++)
{
//ss: 查询串
string ss;
ss.append(1,name);
e = expression;
//flag : 指示是否到行尾
bool flag;
do
{
flag = getNum(d);
e = getExpr(e, d);
string s("op(");
s.append(toString(d));
s.append(","+ss+")");
ss = s;
}while (flag);
cout<<ss<<"=";
inOrder(e);
printf("/n");
}
freeTree(expression);
}
}