POJ-3367(队列建逆波兰表达式)

来源:互联网 发布:剑三七秀成女捏脸数据 编辑:程序博客网 时间:2024/06/12 04:12

题目:http://poj.org/problem?id=3367

一开始想不出什么东西来,看了看输入规模,肯定是O(n)级别的复杂度,在纸上上第二个sample的stack过程和queue过程写了一下,发现貌似有”左右括号层数不同则先算括号层数多的最内层、括号层数相同时先算右边括号最内层“的近似规律,看到题目中提到了polish notation、后缀表达式,就试着画了一下sample的后缀树,又发现这个规律实际上就是对后缀树从下到上、从右到左遍历,这才恍然大悟,1Y……

步骤:

(1)对逆波兰表达式建树

(2)分层遍历树

(3)将遍历结果逆序


#include <cstdio>#include <cctype>#include <cstring>#include <queue>#include <algorithm>using namespace std;#define MAX_LEN 10000char exp[MAX_LEN + 1];char res[MAX_LEN + 1], *ptr;struct Node{    char value;    Node* left;    Node* right;} arr[MAX_LEN];int index;Node* newNode(char c){    arr[index].value = c;    arr[index].left = arr[index].right = NULL;    return &arr[index++];}queue<Node*> q;int separate(int e){    --e;    for(int sum = 0; true; --e){        if(islower(exp[e])){            if(++sum == 1) break;        }        else --sum;    }    return e;}Node* build(int s, int e){    Node* p = newNode(exp[e]);    if(s == e) return p;    int m = separate(e);    if(m < e) p->right = build(m, e - 1);    if(m > s) p->left = build(s, m - 1);    return p;}void levelTraverse(Node* p){    ptr = res;    q.push(p);    while(!q.empty()){        p = q.front(); q.pop();        *ptr++ = p->value;        if(p->left) q.push(p->left);        if(p->right) q.push(p->right);    }    *ptr = '\0';    reverse(res, ptr);}int main(){    int test;    scanf("%d", &test);    while(getchar() != '\n') ;    while(test--){        index = 0;        levelTraverse(build(0, strlen(gets(exp)) - 1));        puts(res);    }    return 0;}

0 0
原创粉丝点击