数据结构 用栈实现四则混合运算
实验目的:
利用“栈”完成一定程度的四则混合运算,四则运算表达式应以字符串形式读入。该段程序要实现的基本功能是实现“十以内的加减乘除运算”,在实现四则运算的简单功能后,可以考虑让表达式的第一项为负数,还可以考虑括号、乘方运算,同时将数值范围从十以内的整数扩展到有理数,通过该计算器程序的编写更好的理解与运用栈。
实验思路:
![](/assets/blank.gif)
样例:
① 输入:-3.14+2*15-7^2+(12*3)
输出:13.860
②输入:-77+54*3^2-(19+3*5)
输出:375.000
③输入:79/4+51*(4.5*21+14^3)
输出:144783.250
实验代码:
/*
基础要求:以字符串形式输入一个包含加减乘除等运算符号的四则混合运算表达,
利用栈计算该表达式的值,表达式中的数值在0-9之间。
进阶:字符串中的一个字符为负号,运算符中增加括号、乘方等运算符,
表达式中的数值大于等于10,表达式中的数值为小数
范例:
①21*(5-17)+6^2
A:-216
*/
#include<stdlib.h>
#include<stdio.h>
#include <iostream>
#include <string>
#include <ctype.h>
#include <set>
#include <queue>//c++队列
#include <stack>// C++栈
#include <map>//C++中关联容器map ,本段代码中使用insert、find、empty函数
#include <math.h>//乘方运算中调用pow()
using namespace std;
//判断是否为操作符,操作符——true;否则——false;
bool is_operator(char ch) {set<char> operator_set;operator_set.insert('+');operator_set.insert('-');operator_set.insert('*');operator_set.insert('/');operator_set.insert('%');operator_set.insert('^');return operator_set.find(ch) != operator_set.end();
}
// 比较两个操作符的优先级
int compare_priority(char a, char b) {map<char, int> operator_priority;operator_priority.insert(make_pair('+', 1));operator_priority.insert(make_pair('-', 1));operator_priority.insert(make_pair('*', 2));operator_priority.insert(make_pair('/', 2));operator_priority.insert(make_pair('%', 2));operator_priority.insert(make_pair('^', 3));return operator_priority[a]-operator_priority[b];
}
//处理一元操作符 '+'和'-'
string preprocess(const string infix) {string result = infix;set<char> valid_char_set;for(int i=0; i<=9; i++) {valid_char_set.insert(i+'0');}valid_char_set.insert('+');valid_char_set.insert('-');valid_char_set.insert('*');valid_char_set.insert('/');valid_char_set.insert('%');valid_char_set.insert('^');valid_char_set.insert('(');valid_char_set.insert(')');valid_char_set.insert('.');//小数点for(int i=0; i<result.size(); i++) {//如果字符不在valid_char_set,说明有不能处理的字符,结束程序if(valid_char_set.find(result[i]) == valid_char_set.end()) {printf("存在非法字符!!!");exit(-1);}}//处理一元操作符for(int i=0; i<result.size(); i++) {char temp = result[i];if(temp != '+' && temp != '-') {continue;}if(i==0) result.insert(i, 1, 0+'0');else if(i-1>=0 && !isdigit(result[i-1]) && result[i-1]!=')') { //一元+-,紧跟着其他符号后面result.insert(i, "(0");int j = i+3;int bracket_count=0;//如果有括号,应包含括号for(; j<result.size(); j++) {if(isdigit(result[j]) || result[j]=='.') continue;else if(result[j]=='(') ++bracket_count;else if(result[j]==')'){if((--bracket_count) == 0)break;else if(bracket_count==0)break;}}i = j;result.insert(j, ")");}}return result;
}
//中缀表达式--后缀表达式
queue<string> infix_to_post(string infix) {queue<string> postfix;//后缀表达式队列stack<char> operator_stack;//转换过程中,用来存储操作符的栈set<char> valid_operand_set;//操作数中的字符for(int i=0; i<=9; i++) {valid_operand_set.insert(i+'0');}valid_operand_set.insert('.');for(int i=0; i<infix.size(); i++) {char ch = infix[i];if(infix[i]=='(') {//左括号operator_stack.push(infix[i]);} else if(infix[i]==')') {//右括号while(!operator_stack.empty() && operator_stack.top()!='(') {postfix.push(string(1, operator_stack.top()));operator_stack.pop();}operator_stack.pop();//将"("出栈} else if(is_operator(infix[i]) == true) { //是操作符(不包含 左、右括号)if(operator_stack.empty()) { //操作符栈为空operator_stack.push(infix[i]);continue;}//操作符栈非空char top_stack = operator_stack.top();//将栈中'较高和相等'优先级的操作符放到 后缀表达式中。//终止条件为:当前操作符>栈顶操作符优先级,或优先级相等、但栈顶操作符的结合性是“从右向左”。while(compare_priority(infix[i], top_stack)<=0) {//优先级相等,但栈顶操作符结合性为从右向左,这里特指'^'if(compare_priority(infix[i], top_stack)==0 && infix[i]=='^') { //因为'^'的结合性从右向左,所以单独处理break;}//当前操作符<=栈顶操作符优先级,当前操作符结合性为从左到右postfix.push(string(1, top_stack));operator_stack.pop();if(!operator_stack.empty()) {top_stack = operator_stack.top();} else break;}//将当前操作符入栈operator_stack.push(infix[i]);} else {//操作数string current_operator;int j=i;while(valid_operand_set.find(infix[j]) != valid_operand_set.end()) {current_operator += infix[j];++j;}postfix.push(current_operator);i=j-1;//因为for循环,每次都会执行i++}queue<string> temp_queue = postfix;while(temp_queue.size()>0) {temp_queue.front();temp_queue.pop();}}//最后将栈中内容全部取出来while(!operator_stack.empty()) {postfix.push(string(1, operator_stack.top()));operator_stack.pop();}return postfix;
}
//计算两个操作数
double calculate_two(double a, double b, string operand) {double result;if(operand == "+") {result = a+b;} else if(operand == "-") {result = a-b;} else if(operand == "*") {result = a*b;} else if(operand == "/") {if(b==0) {exit(-1);}result = a/b;} else if(operand == "%") {result = (static_cast<int>(a)) % (static_cast<int>(b));} else if(operand == "^") {result = pow(a, b);}return result;
}
//对后缀表达式,进行计算
double calculate_post(queue<string>& post) {stack <double> result_stack;while(!post.empty()) {string temp = post.front();post.pop();if(is_operator(temp[0])) { //是操作符if(result_stack.size()<2) {exit(-1);}double operand2 = result_stack.top();//从栈中取出两个元素result_stack.pop();double operand1 = result_stack.top();result_stack.pop();double m = calculate_two(operand1, operand2, temp);//计算并将结果压入栈中result_stack.push(m);} else { //操作数double temp_operand = atof(temp.c_str());result_stack.push(temp_operand);}}return result_stack.top();
}
int main(int argc, char **argv) {string infix;getline(cin, infix);//输入表达式 string result_infix = preprocess(infix);//处理一元操作符:‘+’‘-’ queue<string> result_post = infix_to_post(result_infix);//将表达式转换为计算机易于理解的后缀表达式 queue<string> temp = result_post;while(!temp.empty()) {temp.pop();}//判断是否栈空,若非空则弹出栈顶元素 double result = calculate_post(result_post);//对后缀表达式计算并将结果返回给result printf("计算结果为:%.3f",result);//输出结果 return 0;
}
数据结构 用栈实现四则混合运算相关推荐
- 【数据结构】支持四则混合运算的计算器(转)
1.给出两个数,用户再指定操作符,要求计算结果,这实现起来很容易: 2.多个数,但只涉及同一优先级的操作符,做起来也很容易: 3.多个数,不同优先级的操作符,怎么办呢? 想想就头痛,不过还好前 ...
- java实现四则混合运算
最近在看数据结构.想要实现四则混合运算.用栈来实现. 去网上看了好些代码(想偷懒来着)结果代码都不全.思路不清晰. 看的难受,最后觉得还是自己写吧.学习嘛,偷懒不得. 栈的本质就是个线性表.结构就是个 ...
- 使用堆栈实现对算数四则混合运算表达式的求值(C语言)
使用堆栈实现对算数四则混合运算表达式的求值(C语言) 很方便的目录 使用堆栈实现对算数四则混合运算表达式的求值(C语言) 一.问题分析 基本思路 算符优先级构建 二.算法描述 算法描述 堆栈运算过程的 ...
- C语言编程学习:写的秒速计算四则混合运算项目
C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构.C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现 ...
- java 四则混合运算_Java实现四则混合运算代码示例
使用栈来实现,可以处理运算优先级. 使用自然四则运算表达式即可,如:4+(3*(3-1)+2)/2.无需把表达式先转换为逆波兰等形式. package com.joshua.cal; import j ...
- c# 四则混合运算算法
对于四则混合运算其实在大三的时候就接触过,但是由于当时自己太菜,只顾着玩游戏跳课了.所以这个算法一直没有用代码实现过.当时学霸还给我简单的讲了一下方法,只因身为学渣的我,只想对学霸说一句,道理我都懂, ...
- 四则混合运算表达式分析程序的原理及其实现
意义: 四则混合运算表达式可以看作一定语言中的表达式分析及求值,虽然它很小,却是一个语法分析的很好的例子! 一.目标:可以对输入的四则混合运算表达式进行分析,并求出其结果.程序须支持:整数及小数运算. ...
- 四则混合运算c语言程序例,C++实现四则混合运算计算器
本文实例为大家分享了C++实现四则混合运算的计算器,供大家参考,具体内容如下 计算器是带括号的四则运算实际上利用的是栈后进先出的原则 转换思想: #define _CRT_SECURE_NO_WARN ...
- java四则混合运算_Java实现四则混合运算代码示例
使用栈来实现,可以处理运算优先级. 使用自然四则运算表达式即可,如:4+(3*(3-1)+2)/2.无需把表达式先转换为逆波兰等形式. package com.joshua.cal; import j ...
最新文章
- linux 搭建Tomcat
- PyQt5 技术篇-通过参数控制Dialog窗口增加?问号按钮
- ios mysql install_快速安装ngios
- Java Stringbuilder简单介绍
- 简单的计数器程序_javaweb
- 可视化Python设计工具
- 分离图片中的隐藏文件方法总结
- Asp.net動態添加控件(转)
- 针对十类数据从业人员,最好的工具推荐
- 增益比值 dB 以及 dBw-dBmv 等之详解
- Linux线程属性及优先级设置
- [转]厚积薄发,有的放矢--李开复博士给中国计算机系学生的建议
- PHP工具篇:PHPStorm IDE使用CodeSniffer代码规范化管理
- SIP - FreeSwitch 安装 编译
- 【visio】visio软件安装
- 联想l430主板图纸_L430开箱+拆机+换内存+换U+评测+拷机15小时,图多杀猫
- 优思学院|六西格玛管理的经典六步法
- tipask 修改,临时的(暂没进行很好的全面考虑,为上线用)
- 带你学微信小程序开发
- 复利计算器app发布