第四次程序设计作业 C++计算器计算及命令行的使用 前缀表达式方法实现
关键词:前缀中缀后缀表达式 波兰式 命令行
myGithub
一.前言
很有意思的开发和学习经历,从刚刚开始看到作业思考半天到现在的Debug过程,对我来说都或多或少有所提升。
也许这个时候自己挺迷茫的,想未来的路在哪里。一转眼,自己就走出去了很远,白驹过隙,时光荏苒。
二.本次作业的步骤梳理
- 1.Windows系统下的cmd命令行操作
- 2.输入字符串input过程中的特判负号
- 3.计算过程中符号优先级的判断
- 4.输入错误的判断
- 5.总结与反馈
这里我的解决步骤是:2->4->3->1->5。本篇博客主要介绍第3步和第1步。
三.计算的实现
代码:
calculation.h
//==============================//
//文件名称:calculation.h
//作者:031502209
//更新时间:2016/4/7
//博客:qq952693358
//==============================//
#ifndef CALCULATION_H
#define CALCULATION_H
#include<stack>
#include<queue>
#include<iostream>
#include<stdlib.h>
#include<string>
using namespace std;
//===============================//
//class:Calculation
//包含:执行计算函数carryout
//函数类型:int
//===============================//
class Calculation
{
public:
int carryout(queue<string> que);
};
#endif // CALCULATION_H
calculation.cpp
//==============================//
//代码主体部分:calculation
//文件名称:calculation.cpp
//作者:031502209
//更新时间:2016/4/7
//博客:qq952693358
//==============================//
//==================================//
//说明:该部分分为两大块
//1.把原来的式子转换成为前缀表达式
//2.前缀表达式的计算
//==================================//
#include "calculation.h"
#include<stack>
#include<queue>
#include<iostream>
#include<stdlib.h>
#include<string>
#include<sstream>
//======priority=======//
//说明:用于判断优先级
//=====================//
int priority(string s)
{
if(s=="(" || s== ")")return 0;
if(s=="+" || s=="-")return 1;
if(s=="*" || s=="/")return 2;
if(s=="#")return -1;
}
//======calculate======//
//说明:用于计算
//=====================//
int calculate(string s,int a,int b)//double
{
if(s=="+")return b+a;
if(s=="-")return b-a;
if(s=="*")return b*a;
if(s=="/" && a!=0)return b/a;
else return 0;
}
//========代码主体========//
int Calculation::carryout(queue<string> que)
{
//判断是否出错
if(que.empty())
{
cout<<"error"<<endl;
return 0;
}
stack<string> sign1,sign2;
stack<string> signstore;//倒序
string s;
string que_s;
string sign1_top;
//==========================//
//从'='开始从右向左遍历
//所以用一个栈signstore实现
//==========================//
while(!que.empty())
{
signstore.push(que.front());
que.pop();
}
//-------------------------BEGIN-------------------------//
//======部分1======//
//转换为前缀表达式
//=================//
while(!signstore.empty())
{
s=signstore.top();
signstore.pop();
if(s=="=")continue;
if(s=="+" || s=="-" || s=="*" || s=="/" || s=="(" || s==")")
{
//=============说明=============//
//如果存在以下情况:
//(1)s的优先级大于sign1栈顶元素
//(2)s==")"
//(3)sign1为空栈
//则:s直接push进sign1
//==============================//
//sign1为空栈
if(sign1.empty())
{
sign1.push(s);
continue;
}
//s==")"
if(s==")")
{
sign1.push(s);
continue;
}
//=============说明=============//
//如果遇到左括号:
//把sign1里面的字符push进sign2
//直至遇见右括号
//==============================//
if(s=="(")
{
while(sign1.top()!=")")
{
sign2.push(sign1.top());
sign1.pop();
}
sign1.pop();//右括号出栈
continue;
}
//s的优先级大于sign1栈顶元素 //
if(priority(s) > priority(sign1.top()))
{
sign1.push(s);
continue;
}
//s的优先级小于sign1栈顶元素//
//==============说明===============//
//当遇到s的优先级小于栈顶元素时
//把sign1里面的字符从栈顶
// push进sign2
//直到栈顶元素优先级大于s
//=================================//
else if(priority(s) < priority(sign1.top()))
{
while(priority(s) < priority(sign1.top()))
{
sign1_top=sign1.top();
sign1.pop();
sign2.push(sign1_top);
}
sign1.push(s);
continue;
}
else //优先级相同 且非"("括号")"直接入sign1
{
if(s=="+" || s=="-" || s=="*" || s=="/")
sign1.push(s);
}
}
else //如果是数字的话 push进sign2
{
sign2.push(s);
continue;
}
}
//将sign1中剩余的部分按顺序push进sign2
while(!sign1.empty())
{
sign2.push(sign1.top());
sign1.pop();
}
//转换为前缀表达式 完成
//-------------------------END-------------------------//
//========部分2========//
//计算前缀表达式
//=====================//
//sign2逆序存放->sign_2
stack<string> sign_2;
while(!sign2.empty())
{
sign_2.push(sign2.top());
sign2.pop();
}
//使用stringstream 把字符串转换为数字
stringstream stream;
int number;
stack<int> numberstore;//存储数字的栈
string s2;
//计算部分
while(!sign_2.empty())
{
s2=sign_2.top();
sign_2.pop();
//遇到运算符 提取出numberstore栈顶两个元素进行计算
//结果push进numberstore
if(s2=="+" || s2=="-" || s2=="*" || s2=="/")
{
int number1;
number1=numberstore.top();
numberstore.pop();
int number2;
number2=numberstore.top();
numberstore.pop();
int cal_number;
cal_number=calculate(s2,number2,number1);
numberstore.push(cal_number);
continue;
}
else //遇到操作数 转换为数字之后入栈
{
stream.str(s2);
stream>>number;
numberstore.push(number);
stream.clear();
continue;
}
}
int value=0;
value=numberstore.top();//栈顶元素即最终结果
return value;
}
四.CMD命令行
以下是主函数的写法:
#include "calculation.h"
#include "calculator.h"
#include "print.h"
#include<string>
#include<string.h>
#include<queue>
#include<stdlib.h>
#include<iostream>
using namespace std;
int bitjudge=0;
int main(int argc,char*argv[]) //不通过命令行输入时通过Input类来输入
{
queue<string> que; // type:queue<string>
Scan Sc; // Define a "Scan" object:"Sc".
Print Put; // Define a "Print" object "Put".
Calculation Ca; // Define a "Calculation" object "Ca".
string str=argv[argc-1];
if(strcmp(argv[1],"-a")==0) //判断是否有输入'-a'
{
que.push(str);
Put.pout(que); // printf que.
}
while(!que.empty())que.pop(); // 清空que
que=Sc.ToStringQueue(argv[argc-1]);
cout<<Ca.carryout(que)<<endl;
return 0;
}
实现效果如下:
五.不足的地方(已做出改进)
我从我原来的代码进行了改进,在原来的要求下,我输出了整个式子,并且在之后进行了错误判断:<1>输入的式子左右括号匹配判断 <2>输入的数超过十位
但是如果使用命令行的话,在输入'-a'的时候会进行判断,但是没有'-a'的时候就会跳过(判断在调用的print.cpp内)。还有一个就是小数的处理。
这是美中不足的地方。
今天改进了一下:实现报错功能,处理了小数的情况,对主函数进行了修改。
六.数据处理(举两个例子):
1.(-3+(9-((10-8)+(9-8*6/2+3)-10*10))*(8-(1+8/4)+2))=830
2.(3+(-1+2*8)*2)+(9-8*1)=34
七.总结:
经过这些天的努力和尝试,把之前想象中异常困难的任务完成了。在我之前的代码上依照要求进一步的开发,学习了CMD命令行和sstream的使用,总体上对这些天的经历感到满意。但是我也看到了自己的不足和缺点,主要是:
1.自己的知识储备相对浅薄,仍然需要扩宽知识面,不断学习新的知识。
2.编程能力仍然需要提升。
3.提高阅读代码的能力,多去思索别人的想法和做法。
希望接下来的自己再接再厉,坚持下去。
2016/4/9
更新:(2016/4/11) 解决了开头为负号的特殊情况
第四次程序设计作业 C++计算器计算及命令行的使用 前缀表达式方法实现的更多相关文章
- 第五次程序设计作业 C++计算器雏形 调用文件输入输出
一.C++计算器作业系列链接 第三次作业:C++计算器雏形 第三次作业附加:代码规范 第四次作业:命令行的调用及计算 MyGithub 二.本次作业相关 要求:第五次程序设计作业 根据这一次的作业要求 ...
- 程序设计第三次作业--C++计算器初始部分
面向对象程序设计作业3--C++计算器初始部分 Github 链接:https://github.com/luojingzhao/object-oriented/tree/master/calcula ...
- casio计算器计算统计数据
http://blog.csdn.net/pipisorry/article/details/50257319 使用casio计算器计算输入数据均值.标准差和相关系数的方法,lz使用casio fx8 ...
- 20165220Java实验四 Android程序设计
一.实验报告封面 课程:Java程序设计 班级:1652班 姓名:葛宇豪 学号:20165220 指导教师:娄嘉鹏 实验日期:2018年5月14日 实验时间:13:45 - 15:25 实验序号:实验 ...
- 20172328《程序设计与数据结构》实验四 Android程序设计报告
20172328<程序设计与数据结构>实验四 Android程序设计报告 课程:<程序设计与数据结构> 班级: 1723 姓名: 李馨雨 学号:20172328 实验教师:王志 ...
- 20155303 实验四 Android程序设计
20155303 实验四 Android程序设计 目录 第24章:初识Android 任务一: 完成Hello World, 要求修改res目录中的内容,Hello World后要显示自己的学号 学习 ...
- 20169205实验四 Android程序设计
20169205实验四 Android程序设计 实验内容及步骤 (一)第一个android studio项目 android studio与eclipse的传统安卓开发有一些不同之处 android ...
- Python 迭代器&生成器,装饰器,递归,算法基础:二分查找、二维数组转换,正则表达式,作业:计算器开发
本节大纲 迭代器&生成器 装饰器 基本装饰器 多参数装饰器 递归 算法基础:二分查找.二维数组转换 正则表达式 常用模块学习 作业:计算器开发 实现加减乘除及拓号优先级解析 用户输入 1 - ...
- 实验四 Android程序设计 实验报告
实验四 Android程序设计 实验报告 目录 代码托管地址 Android程序设计-1 Android程序设计-2 Android程序设计-3 Android程序设计-4 Android程序设计-5 ...
随机推荐
- 7.MQTT网页客户端连接MQTT服务器的问题WebSocket connection to 'ws://XXX:1883/' failed: Connection closed before receiving a handshake response
问题描述:MQTT.js提供了连接MQTT的一套javascipt的方法,可供前端连接到MQTT服务器,也可以作为脚本测试.以脚本形式,用nodejs运行,是没有问题的,能够正常连接并且发送报文.但是 ...
- 安装HDF5及在VS下配置HDF5
最近要用到HDF5来存储数据,想要安装尝试用一下.发现网上有两种安装方式,一种是obtain518.html:获取最新的HDF5-1.8软件;另一种是cmakebuild518.html:使用CMAK ...
- [py]django第三方分页器django-pure-pagination实战
第三方分页模块: django-pure-pagination 是基于django的pagination做的一款更好用的分页器 参考 配置django-pure-pagination模块 安装 pip ...
- Python中的类属性、实例属性与类方法、静态方法
1.什么是类对象,实例对象 类对象:类名 实例对象:类创建的对象 2.类属性就是类对象所拥有的属性,它被所有类对象的实例对象所共有,在内存中只存在一个副本,这个和C++.Java中类的静态成员变量有点 ...
- Word AddIn编译出现LINK2001 _main
链接错误"unresolved external symbol _main" Article last modified on 2002-3-2 ------------- ...
- ios 工作日志
1.设计模式 1.1 想用一个controllerK控制多个页面的切换 但是每一个页面必须要引用这个controller,这样才能控制进度, 所以必须是弱引用.controller必须被某一个实例强引 ...
- VirtualBox 虚拟磁盘的UUID修改
个人测试环境,想构建一套Standby RAC环境,不想再重复去安装系统浪费时间,直接复制之前安装RAC前的一套VirtualBox的虚拟环境,不过打开时报错: 未能打开位于 Z:\Vbox\Stan ...
- Summary: Arrays vs. Collections && The differences between Collection Interface and Collections Class
转自http://www.anylogic.com/anylogic/help/index.jsp?topic=/com.xj.anylogic.help/html/code/Arrays_Colle ...
- C++Builder6.0 新建和打开项目软件死机
大清早上班打开C++Builder6.0软件,打开项目却卡死,甚是奇怪,然后尝试新建项目也同样卡死.尝试打开一个CPP文件,可以打开,再尝试打开项目.bpr文件,便打开了.至于原因为什么,那就不得而知 ...
- malloc 实现原理
1. Reference: 如何实现一个malloc http://blog.codinglabs.org/articles/a-malloc-tutorial.html 2.