1-3 表达式转换 (25分)

1-3 表达式转换 (25分)

算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。

输入格式:

输入在一行中给出不含空格的中缀表达式,可包含+、-、*、\以及左右括号(),表达式不超过20个字符。

输出格式:

在一行中输出转换后的后缀表达式,要求不同对象(运算数、运算符号)之间以空格分隔,但结尾不得有多余空格。

输入样例:

2+3*(7-4)+8/4

输出样例:

2 3 7 4 - * + 8 4 / +

思路如下:
堆栈应用:表达式求值
👆浙大数据结构讲解中缀表达式如何转换为后缀表达式
👇一个博主整理的还应注意的点
参考链接
二者加持,过了…

总结
从头到尾读取中缀表达式的每个对象,对不同对象按不同情况处理
1)运算数 直接输出
2)运算符号
*左括号:压入堆栈
*右括号:将栈顶的运算符弹出并输出直到遇到左括号(出栈但不输出)
*其他:若优先级大于栈顶运算符压栈否则将栈顶运算符弹出并输出,再比较新的栈顶运算符直到该运算符大于栈顶运算符为止,然后将该运算符压栈
3)对象处理完毕,若堆栈不空把残留运算符全部输出


1)数字可能是小数、负数(负号和数字是一起输出的)或带正号的数字
2)由于嵌套括号的存在,所以不能直接输出i=0时候的字符,有可能为嵌套括号
在这里插入图片描述

代码如下:

#include<bits/stdc++.h>
using namespace std;
stack<char> st;
map<char,int> mp;
int main(){
	mp['+'] = mp['-'] = 1;  //定义运算符的优先级
	mp['*'] = mp['/'] = 2;
	string s="";
	cin >> s;
	int flag = 1;

	for(int i=0;i<s.length();++i){
		if(isdigit(s[i]) || s[i]=='.' || ((!i||s[i-1]=='(')&&(s[i]=='+'||s[i]=='-')) ){  //处理操作数 
			if(!flag) cout << " ";
			else flag = 0;
			if(s[i]!='+') cout << s[i];
			while(s[i+1]=='.'||isdigit(s[i+1])) cout << s[++i];  //小数继续往后读
		}else{  //处理运算符 
			if(s[i]=='(') st.push(s[i]);  //(:压栈
			else if(s[i]==')'){  //):将栈顶的运算符弹出并输出,直到遇到左括号(出栈,不输出)
				while(!st.empty()&&st.top()!='('){
					cout << " " << st.top();
					st.pop();
				}
				st.pop();
			}
			else if(st.empty()||mp[s[i]]>mp[st.top()]) st.push(s[i]);  //s[i]的优先级比栈顶元素的大
			else{  
				while(!st.empty()&&st.top()!='('){  //s[i]的优先级比栈顶元素的小或等
					cout << " " << st.top();
					st.pop();
				}
				st.push(s[i]);
			}
		}
	}
	while(!st.empty()){
		cout << " " << st.top();
		st.pop();
	} 
	return 0;
}
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是通过二叉链表遍历将算术表达式转换为二叉树并求值的 C 语言代码,包含注释说明: ```c #include <stdio.h> #include <stdlib.h> // 定义二叉树节点结构体 typedef struct TreeNode { char data; // 节点数据 struct TreeNode *left; // 左子节点 struct TreeNode *right; // 右子节点 } TreeNode; // 定义栈结构体 typedef struct Stack { TreeNode **items; // 存储节点指针的数组 int top; // 栈顶指针 int size; // 栈的最大容量 } Stack; // 创建一个新的栈 Stack *createStack(int size) { Stack *stack = (Stack *) malloc(sizeof(Stack)); stack->items = (TreeNode **) malloc(size * sizeof(TreeNode *)); stack->size = size; stack->top = -1; return stack; } // 判断栈是否为空 int isEmpty(Stack *stack) { return stack->top == -1; } // 判断栈是否已满 int isFull(Stack *stack) { return stack->top == stack->size - 1; } // 入栈操作 void push(Stack *stack, TreeNode *item) { if (isFull(stack)) { printf("Error: Stack is full\n"); return; } stack->items[++stack->top] = item; } // 出栈操作 TreeNode *pop(Stack *stack) { if (isEmpty(stack)) { printf("Error: Stack is empty\n"); return NULL; } return stack->items[stack->top--]; } // 获取栈顶元素 TreeNode *peek(Stack *stack) { if (isEmpty(stack)) { printf("Error: Stack is empty\n"); return NULL; } return stack->items[stack->top]; } // 判断一个字符是否是操作符 int isOperator(char c) { return c == '+' || c == '-' || c == '*' || c == '/'; } // 通过二叉链表遍历将算术表达式转换为二叉树 TreeNode *constructTree(char postfix[]) { int i = 0; Stack *stack = createStack(strlen(postfix)); while (postfix[i] != '\0') { char c = postfix[i]; if (isOperator(c)) { TreeNode *node = (TreeNode *) malloc(sizeof(TreeNode)); node->data = c; node->right = pop(stack); node->left = pop(stack); push(stack, node); } else { TreeNode *node = (TreeNode *) malloc(sizeof(TreeNode)); node->data = c; node->left = NULL; node->right = NULL; push(stack, node); } i++; } TreeNode *root = pop(stack); return root; } // 求二叉树的值 int evaluateTree(TreeNode *root) { if (root == NULL) { return 0; } if (root->left == NULL && root->right == NULL) { return root->data - '0'; // 将字符转换为数字 } int leftValue = evaluateTree(root->left); int rightValue = evaluateTree(root->right); switch (root->data) { case '+': return leftValue + rightValue; case '-': return leftValue - rightValue; case '*': return leftValue * rightValue; case '/': return leftValue / rightValue; default: printf("Error: Invalid operator %c\n", root->data); return 0; } } // 测试代码 int main() { char postfix[] = "23+45+*"; // 后缀表达式 "2+3*4+5" TreeNode *root = constructTree(postfix); int result = evaluateTree(root); printf("Result: %d\n", result); // 输出结果 25 return 0; } ``` 以上代码实现了通过二叉链表遍历将算术表达式转换为二叉树并求值的功能,具体实现过程包括: 1. 定义二叉树节点结构体 `TreeNode`,包含节点数据和左右子节点指针; 2. 定义栈结构体 `Stack`,使用数组存储节点指针,并实现入栈、出栈、获取栈顶元素等操作; 3. 实现判断一个字符是否是操作符的函数 `isOperator`; 4. 实现通过二叉链表遍历将算术表达式转换为二叉树的函数 `constructTree`,遍历表达式字符串,遇到操作数创建节点并入栈,遇到操作符弹出两个节点作为左右子节点创建新节点并入栈; 5. 实现求二叉树的值的函数 `evaluateTree`,递归遍历二叉树,遇到操作数返回该节点的值,遇到操作符递归计算左右子节点的值并根据操作符进行运算; 6. 在 `main` 函数中测试代码。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值