zoj 1014 ---未解决



/**基本思路, 先把表达式转化成表达树表示, 然后根据查询, 找子树



可能导致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);

    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值