Uva 11234 Expressions (二叉树的层次遍历)

Problem E: Expressions

Arithmetic expressions are usually written with the operators in between the two operands (which is called infix notation).
两个操作数之间夹着运算符(即所谓中缀式)。

For example, (x+y)*(z-w) is an arithmetic expression in infix notation.
例如,(X+Y)*(Z-W)是中缀式。

However, it is easier to write a program to evaluate an expression if the expression is written in postfix notation (also known as reverse polish notation).
但是,如果用后缀式(也称逆波兰式),它更容易编写一个程序来计算一个表达式的结果。

In postfix notation, an operator is written behind its two operands, which may be expressions themselves.
在后缀式中,操作符被写入它的两个操作数,在表达式本身的后面。

For example, x y + z w - * is a postfix notation of the arithmetic expression given above. Note that in this case parentheses are not required.
例如,XY+ZW-*是上面给出的算术表达式的后缀表示法。
请注意,在这种情况下不需要括号。

To evaluate an expression written in postfix notation, an algorithm operating on a stack can be used.
为了评估后缀式,堆栈操作的算法都可以使用。
A stack is a data structure which supports two operations:

堆栈是能支持两个操作的数据结构:


    push: a number is inserted at the top of the stack.

    push: 将一个数字压入栈顶
    pop: the number from the top of the stack is taken out.
    pop: 从栈顶弹出一个数

During the evaluation, we process the expression from left to right.
我们处理由左到右的表达。

If we encounter a number, we push it onto the stack.
如果我们遇到一个数字,我们要把它压入栈中


If we encounter an operator, we pop the first two numbers from the stack, apply the operator on them, and push the result back onto the stack.

如果我们遇到一个运算符,我们要从堆栈中弹出两个数字,经过运算后,再将结果推入堆栈。


More specifically, the following pseudocode shows how to handle the case when we encounter an operator O:

更具体地讲,下面的伪代码显示了如何处理的情况下,当我们遇到一个操作符O:

a := pop();  //弹出a
b := pop();  //弹出b
push(b O a);  //将b O a 压入栈中

The result of the expression will be left as the only number on the stack.
表达式的结果将被保留在堆栈中。


Now imagine that we use a queue instead of the stack.

现在想象你用一个队列替换堆栈


A queue also has a push and pop operation, but their meaning is different:

队列也是有push和pop,但是它和堆栈的意义不同。

    push: a number is inserted at the end of the queue.
    将一个数插入到队列的末尾。

    pop: the number from the front of the queue is taken out of the queue.

    将一个数从队列的开头弹出。

Can you rewrite the given expression such that the result of the algorithm using the queue is the same as the result of the original expression evaluated using the algorithm with the stack?

你可以重写一个的表达式,让使用队列算法的结果和使用该堆栈算法的原始表达式计算的结果一样吗?


Input Specification


The first line of the input contains a number T (T ≤ 200).
第一行包含输入的样例数T
The following T lines each contain one expression in postfix notation.
接下来输入T个后缀式
Arithmetic operators are represented by uppercase letters, numbers are represented by lowercase letters.
小写字母代表造作数,大写字母代表操作符。
You may assume that the length of each expression is less than 10000 characters.
 每个表达式不超过10000个字符


Output Specification


For each given expression, print the expression with the equivalent result when using the algorithm with the queue instead of the stack.
对于每一个给定的表达式(后缀式),输出与堆栈算法结果相等的,使用队列算法结果的表达式。
To make the solution unique, you are not allowed to assume that the operators are associative or commutative.
为了使解决方案独一无二的,你不能假设操作符是关联或交换。

Sample Input

2
xyPzwIM
abcABdefgCDEF

Sample Output


wzyxIPM

gfCecbDdAaEBF


题意:在翻译中写的很详细了。

解析:

如果遇到小写字母直接入栈,如果遇到大写弹出栈顶两个元素。将左指针和右指指向两个元素再入栈。

建立好树后,用二叉树的层次遍历就可以解决问题。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stack>
using namespace std;

struct Node{
	Node* left;
	Node* right;
	char ch;
};

const int N = 10010;

Node node[N]; //预先分配N个节点

Node* Q[N]; //建立队列用于二叉树的层次便

void bfs(Node* root) {
	Q[0] = root; //先将根节点给队列开头
	int front = 0;
	int rear = 1;
	while(front < rear) { //队列不为空

		Node* t = Q[front]->left;
		if(t != NULL) {
			Q[rear++] = t;
		}
		t = Q[front++]->right;
		if(t != NULL) {
			Q[rear++] = t;
		}
	}
	for(int i = rear-1; i >= 0; i--) {
		putchar(Q[i]->ch);
	}
	putchar('\n');
}

int main() {
	int t;
	string str;
	int len;

	while(cin >> t) {
		while(t--) {
			cin >> str;
			stack<Node*> st;
			len = str.size();
			
			for(int i = 0; i < len ; i++) {
				
				node[i].ch = str[i];
				
				if( str[i] >= 'a' && str[i] <= 'z') { //如果是小写字母则入栈
					st.push(&node[i]);
					node[i].left = NULL;
					node[i].right = NULL;
				}
				else { //如果是大写字母则弹出两个操作符赋给左子树和右子树再入栈
					node[i].right = st.top();
					st.pop();
					node[i].left = st.top();
					st.pop();
					st.push(&node[i]);
				}
			}
			Node* root = &node[len - 1];
			bfs(root); //宽搜根节点
		}
	}
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值