1. 程式人生 > >Expression Expression tree Expression evaluation

Expression Expression tree Expression evaluation

題目地址

http://dsalgo.openjudge.cn/binarytree/7/

題目大意

表示式·表示式樹·表示式求值
描述
眾所周知,任何一個表示式,都可以用一棵表示式樹來表示。例如,表示式a+b*c,可以表示為如下的表示式樹:

+
/ \
a *
/ \
b c

現在,給你一箇中綴表示式,這個中綴表示式用變數來表示(不含數字),請你將這個中綴表示式用表示式二叉樹的形式輸出出來。

輸入
輸入分為三個部分。
第一部分為一行,即中綴表示式(長度不大於50)。中綴表示式可能含有小寫字母代表變數(a-z),也可能含有運算子(+、-、*、/、小括號),不含有數字,也不含有空格。
第二部分為一個整數n(n < 10),表示中綴表示式的變數數。
第三部分有n行,每行格式為C x,C為變數的字元,x為該變數的值。
輸出
輸出分為三個部分,第一個部分為該表示式的逆波蘭式,即該表示式樹的後根遍歷結果。佔一行。
第二部分為表示式樹的顯示,如樣例輸出所示。如果該二叉樹是一棵滿二叉樹,則最底部的葉子結點,分別佔據橫座標的第1、3、5、7……個位置(最左邊的座標是1),然後它們的父結點的橫座標,在兩個子結點的中間。如果不是滿二叉樹,則沒有結點的地方,用空格填充(但請略去所有的行末空格)。每一行父結點與子結點中隔開一行,用斜槓(/)與反斜槓(\)來表示樹的關係。/出現的橫座標位置為父結點的橫座標偏左一格,\出現的橫座標位置為父結點的橫座標偏右一格。也就是說,如果樹高為m,則輸出就有2m-1行。
第三部分為一個整數,表示將值代入變數之後,該中綴表示式的值。需要注意的一點是,除法代表整除運算,即捨棄小數點後的部分。同時,測試資料保證不會出現除以0的現象。
樣例輸入
a+b*c
3
a 2
b 7
c 5
樣例輸出
abc*+
+
/ \
a *
/ \
b c
37

Code

#include <iostream>
#include <stack>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <map>
#include <algorithm>
#define INF 0x3fffffff
#define MAXROW 70
#define MAXCOL 300

using namespace std;

int layers;
char bl[128];
char buf[512
][512]; map<char, int> mci; struct Node { char v; Node* l; Node* r; Node() { l = NULL; r = NULL; } Node(char c) { v = c; l = NULL; r = NULL; } }; void get_bl(string s) { memset(bl, 0, sizeof(bl)); int j = 0; stack<char
>
sc; for (int i = 0; i < s.size(); i++) { if (isalpha(s[i])) { bl[j++] = s[i]; } else if (s[i] == '(') { sc.push(s[i]); } else if (s[i] == ')') { while ((!sc.empty()) && (sc.top() != '(')) { bl[j++] = sc.top(); sc.pop(); } sc.pop(); } else if (s[i] == '+' || s[i] == '-') { while ((!sc.empty()) && (sc.top() != '(')) { bl[j++] = sc.top(); sc.pop(); } sc.push(s[i]); } else { while ((!sc.empty()) && (sc.top() == '*' || sc.top() == '/')) { bl[j++] = sc.top(); sc.pop(); } sc.push(s[i]); } } while (!sc.empty()) { bl[j++] = sc.top(); sc.pop(); } bl[j] = '\0'; } Node* build_tree() { stack<Node*> sn; for (int i = 0; i < strlen(bl); i++) { if (isalpha(bl[i])) { Node* node = new Node(bl[i]); sn.push(node); } else { Node* node = new Node(bl[i]); node->r = sn.top(); sn.pop(); node->l = sn.top(); sn.pop(); sn.push(node); } } return sn.top(); } int calculate(Node* root){ if (isalpha(root->v)) return mci[root->v]; if (root->v=='+') return calculate(root->l)+calculate(root->r); if (root->v=='-') return calculate(root->l)-calculate(root->r); if (root->v=='*') return calculate(root->l)*calculate(root->r); if (root->v=='/') return calculate(root->l)/calculate(root->r); } int cal(int a, int b, char c) { switch (c) { case '+': return a+b; break; case '-': return a-b; break; case '*': return a*b; break; case '/': return a/b; break; } } void calculate2() { // cal2 stack<int> si; for (int i = 0; i < strlen(bl); i++) { if (isalpha(bl[i])) { si.push(mci[bl[i]]); } else { int x = si.top(); si.pop(); int y = si.top(); si.pop(); int z = cal(y, x, bl[i]); si.push(z); } } cout << si.top(); } int get_layer(Node *root) { if (root == NULL) { return 0; } int left = get_layer(root->l); int right = get_layer(root->r); return max(left+1, right+1); } void print_tree(Node * root, int root_x, int root_y, int space){ int left_child, right_child; if (!root) return; buf[root_y][root_x-1] = root->v; if (root->l){ buf[root_y+1][root_x-2] = '/'; print_tree(root->l,root_x-space,root_y+2,space>>1); } if (root->r){ buf[root_y+1][root_x] = '\\'; print_tree(root->r,root_x+space,root_y+2,space>>1); } } void print(Node* root) { layers = get_layer(root); memset(buf, ' ', sizeof(buf)); int b = INF; print_tree(root, pow(2,layers-1), 0, pow(2,layers-2)); for (int i = 0; i < 2*layers-1; i++) { for (int j = 300; j >= 0; j--) { if (buf[i][j] != ' ') { buf[i][j+1] = '\0'; break; } } } for (int i = 0; i < 2*layers-1; i++) { printf("%s\n", buf[i]); } } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif string s; int n; char c; int v; cin >> s; cin >> n; for (int i = 0; i < n; i++) { cin >> c >> v; mci[c] = v; } get_bl(s); printf("%s\n", bl); Node *root = build_tree(); print(root); int ans = calculate(root); //cout << ans << endl; calculate2(); return 0; }

參考