第四次程序设计作业 C++计算器计算及命令行的使用 前缀表达式方法实现

来源:互联网 发布:mac cf 编辑:程序博客网 时间:2024/05/16 18:23

关键词:前缀中缀后缀表达式 波兰式 命令行

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
1 0
原创粉丝点击