C++ primer 练习9.52 适配器stack 中缀表达式
//调试环境 VS2015
//本人菜鸟一枚,不喜勿喷! 谢谢!!!
//主要思想引自 http://www.cnblogs.com/dolphin0520/p/3708602.html
//主要代码引自 https://blog.csdn.net/fengzhanghao23/article/details/47380793
//改动:1.可支持负数运算,但采用的是字符串string的find搜索操作和substr拷贝操作
// 2.循环操作采用c++11标准的范围for语句实现
// 3.输入采用文件输入,其文件名,存储地址及数据可自行修改
#include "stdafx.h"
#include<iostream>
#include<fstream>
#include<vector>
#include<string>
#include<stack>
using namespace std;
int priority(string opt)
{
int p = 0;
if (opt == "(")
p = 1;
if (opt == "+" || opt == "-")
p = 2;
if (opt == "*" || opt == "/")
p = 3;
return p;
}
void calculate(stack<double> &opdstack, string opt)
{
double ropd = 0;
double lopd = 0;
double result = 0;
if (opt == "+")
{
ropd = opdstack.top();
opdstack.pop();
lopd = opdstack.top();
opdstack.pop();
result = lopd + ropd;
opdstack.push(result);
}
if (opt == "-")
{
ropd = opdstack.top();
opdstack.pop();
lopd = opdstack.top();
opdstack.pop();
result = lopd - ropd;
opdstack.push(result);
}
if (opt == "*")
{
ropd = opdstack.top();
opdstack.pop();
lopd = opdstack.top();
opdstack.pop();
result = lopd * ropd;
opdstack.push(result);
}
if (opt == "/")
{
ropd = opdstack.top();
opdstack.pop();
lopd = opdstack.top();
opdstack.pop();
result = lopd / ropd;
opdstack.push(result);
}
}
double calExpression(vector<string> sv)
{
stack<double> stack_opd;
stack<string> stack_opt;
for (auto c : sv)
{
if (c == "+" || c == "-" || c == "*" || c == "/")
{
if (stack_opt.size() == 0)
stack_opt.push(c);
else
{
int c_p = priority(c);
string top_opt = stack_opt.top();
int opt_p = priority(top_opt);
if (c_p > opt_p)
stack_opt.push(c);
else
{
while (c_p <= opt_p)
{
calculate(stack_opd, top_opt);
stack_opt.pop();
if (stack_opt.size() > 0)
{
top_opt = stack_opt.top();
opt_p = priority(top_opt);
}
else
break;
}
stack_opt.push(c);
}
}
}
else if (c == "(")
stack_opt.push(c);
else if (c == ")")
{
while (stack_opt.top() != "(")
{
string top_opt = stack_opt.top();
calculate(stack_opd, top_opt);
stack_opt.pop();
}
stack_opt.pop();
}
else
{
if (c.find('-') == 0)
stack_opd.push(-stod(c.substr(c.find('-') + 1)));
else
stack_opd.push(stod(c));
}
}
while (stack_opt.size() != 0)
{
string top_opt = stack_opt.top();
calculate(stack_opd, top_opt);
stack_opt.pop();
}
return stack_opd.top();
}
int main()
{
cout << "------This is a function test of test_9_52------" << endl;
cout << "Caution!!! The data stored in file of test_9_52.txt" << endl;
ifstream ifs("test_9_52.txt");
string s;
vector<string> sv;
if (ifs)
{
while (ifs >> s)
sv.push_back(s);
}
else
cout << "The file is not open!!!" << endl;
cout << "The expression: ";
for (auto c : sv)
cout << c << " ";
cout << endl;
cout << "It's calculation results is: " << calExpression(sv) << endl;
cout << endl;
return 0;
}
C++ primer 练习9.52 适配器stack 中缀表达式的更多相关文章
- STL之容器适配器stack的实现框架
说明:本文仅供学习交流,转载请标明出处,欢迎转载! 一提到适配器(adapter).我们就想到了早期用电话线上网所用的调制解调器,俗称"猫"."猫"的作用是实现 ...
- 利用stack结构,将中缀表达式转换为后缀表达式并求值的算法实现
#!/usr/bin/env python # -*- coding: utf-8 -*- # learn <<Problem Solving with Algorithms and Da ...
- Python与数据结构[1] -> 栈/Stack[1] -> 中缀表达式与后缀表达式的转换和计算
中缀表达式与后缀表达式的转换和计算 目录 中缀表达式转换为后缀表达式 后缀表达式的计算 1 中缀表达式转换为后缀表达式 中缀表达式转换为后缀表达式的实现方式为: 依次获取中缀表达式的元素, 若元素为操 ...
- 中缀表达式转逆波兰式(后缀表达式)求值 C++ Stack
给一个包含小数的中缀表达式 求出它的值 首先转换为后缀表达式然后利用stack求出值 转换规则: 如果字符为'(' push else if 字符为 ')' 出栈运算符直到遇到‘(' else if ...
- C语言- 基础数据结构和算法 - 09 栈的应用_中缀表达式转后缀表达式20220611
09 栈的应用_中缀表达式转后缀表达式20220611 听黑马程序员教程<基础数据结构和算法 (C版本)>, 照着老师所讲抄的, 视频地址https://www.bilibili.com/ ...
- sicily 中缀表达式转后缀表达式
题目描述 将中缀表达式(infix expression)转换为后缀表达式(postfix expression).假设中缀表达式中的操作数均以单个英文字母表示,且其中只包含左括号'(',右括号‘)’ ...
- RPN-逆波兰计算器-中缀表达式转后缀表达式-javascript
1.利用栈(Stack)来存储操作数和操作符: 2.包含中缀表达式转后缀表达式的函数,这个是难点,也是关键点: 2.1.将输入字符串转为数组: 2.2.对转换来的字符进行遍历:创建一个数组,用来给存储 ...
- javascript使用栈结构将中缀表达式转换为后缀表达式并计算值
1.概念 你可能听说过表达式,a+b,a+b*c这些,但是前缀表达式,前缀记法,中缀表达式,波兰式,后缀表达式,后缀记法,逆波兰式这些都是也是表达式. a+b,a+b*c这些看上去比较正常的是中缀表达 ...
- ACM题目————中缀表达式转后缀
题目描述 我们熟悉的表达式如a+b.a+b*(c+d)等都属于中缀表达式.中缀表达式就是(对于双目运算符来说)操作符在两个操作数中间:num1 operand num2.同理,后缀表达式就是操作符在两 ...
随机推荐
- javascript对HTML字符转义与反转义
1.背景:在项目中,经常遇到一些字符需要进行转义后才能显示到界面上,如“&”,在界面中显示的是“&”,在html中书写“&”,显示在界面的中的依然是“&”. 这时候,就 ...
- YCRefreshView-自定义支持上拉加载更多,下拉刷新。。。
自定义支持上拉加载更多,下拉刷新,支持自由切换状态[加载中,加载成功,加载失败,没网络等状态]的控件,拓展功能[支持长按拖拽,侧滑删除]可以选择性添加 .具体使用方法,可以直接参考demo. 轻量级侧 ...
- Android Studio笔记之快捷键
Android Studio h2{ color: #4abcde; } pre{ background-color: #f8f8f8; border: solid 1px #ccc; border- ...
- 浅谈SQL Server中的事务日志(三)----在简单恢复模式下日志的角色
简介 在简单恢复模式下,日志文件的作用仅仅是保证了SQL Server事务的ACID属性.并不承担具体的恢复数据的角色.正如”简单”这个词的字面意思一样,数据的备份和恢复仅仅是依赖于手动备份和恢复.在 ...
- python在Android下的自动化测试用法
# This Python file uses the following encoding: utf-8from com.android.monkeyrunner import MonkeyRunn ...
- java中什么是上下文(servletContext)
找了很多大佬的博客,看了之后还不是很清楚上下文到底是怎么回事,我个人理解 所谓上下文,它是用来存储系统的一些初始化信息,例如在jboss中通过配置文件指定了数据源,那么在jboss启动的时候就把这个文 ...
- 关于移动App开发前端UI框架选择
问题:现在移动开发各种必须,而移动开发纠结在于怎样快速高效的开发出来. 做web开发有些年头了,成熟的前端套件(easyui,extjs,jqueryui)很是方便,可以开发出来规范一直的产品,各种组 ...
- 网络防火墙之iptables的前世今生和归宿
任何事物都有一个从无到有,再归于无的过程.是的,我这里用了一个绝对词:任何. 防火墙 在计算机领域中,防火墙(英文:Firewall)是一项协助确保信息安全的设备,会依照特定的规则,允许或是限制传输的 ...
- php入门到精通(复习笔记)
第一章:php语言基础 1,标记风格: ①<?php echo “hello”;?> ②<script language="php">echo " ...
- springMvc-入参对象
1.修改或者添加对象 2.多添件查询时候也会遇到 springMvc能够根据属性自动的封装pojo的对象并且支持关联的对象:大致的原理是在传入后台的时候把前台的属性和对象封装成json的形式传入后台, ...