PAT A1130 Infix Expression

PAT A1130 Infix Expression

在这里插入图片描述

Sample Input 1:

8
* 8 7
a -1 -1
* 4 1
+ 2 5
b -1 -1
d -1 -1
- -1 6
c -1 -1

Sample Output 1:

(a+b)*(c*(-d))

Sample Input 2:

8
2.35 -1 -1
* 6 1
- -1 4
% 7 8
+ 2 3
a -1 -1
str -1 -1
871 -1 -1

Sample Output 2:

(a*2.35)+(-(str%871))
  • 思路 1:
    中序遍历表达式树:
  1. 对每个双目运算符(除了根)都需要在子树两边+括号
  2. 单目运算符(本题只有-)要在根和右子树两边+括号
  3. 双目和单目右子树的情况是相同的
  4. 所以只需在中序遍历下,每次遍历左子树之前先判断下左子树前是否需要加"(",在遍历完右子树后需不需要加")"
  • code 1:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
const int maxn = 30;
bool has[maxn];
struct Node{
	string data;
	int lc, rc;
}node[maxn]; 
int r;
vector<string> v;
void inOrder(int ro){
	if(ro == -1) return;
	if((node[ro].lc != -1 || node[ro].data == "-" ) && ro != r) cout << "(";	//!!!Wrong 1:前面必须加括号 
	inOrder(node[ro].lc);
	cout << node[ro].data;
	inOrder(node[ro].rc);
	if(node[ro].rc != -1 && ro != r) cout << ")";
}
int main(){
	int n, lchild, rchild, root, idex = 0;
	string s;
	scanf("%d", &n);
	for(int i = 1; i <= n; ++i){
		cin >> s >> lchild >> rchild;
		node[i] = Node{s, lchild, rchild};
		if(lchild != -1) has[lchild] = true;
		if(rchild != -1) has[rchild] = true; 		
	}
	for(int i = 1; i <= n; ++i) if(!has[i]) root = i;
	r = root;
	inOrder(root);
	return 0;
}
  • TIPS 1:
    C语言中:||或运算符,只判断前半部分是否为true,若前半部分为true,就不继续看后面了

  • 思路 2:
    第一次好像想复杂了,除了根和叶子,其他所有节点都要左右加括号

  • T2 code:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 50;
struct Node{
	char data[15];
	int lc, rc;
}node[maxn];

bool Judge(int id, int r){
	return id == r || node[id].lc == -1 && node[id].rc == -1 ? false : true;
}

void InOrder(int id, int r){
	if(id == -1) return;
	if(Judge(id, r)) printf("(");
	InOrder(node[id].lc, r);
	printf("%s", node[id].data);
	InOrder(node[id].rc, r);
	if(Judge(id, r)) printf(")");
}
int main(){
	int n;
	scanf("%d", &n);
	int r = (n + 1) * n / 2 - (n + 1);
	for(int i = 1; i <= n; ++i){
		scanf("%s %d %d", &node[i].data, &node[i].lc, &node[i].rc);
		r -= node[i].lc + node[i].rc;
	}
	InOrder(r, r);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值