表达式求值 (计算器)

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;

const int MAX=1505;
char data[MAX];         //存放输入的表达式
double num[MAX];        //存表达式中的数字
char sign[MAX];         //存表达式中的符号
int ntop,stop,w;          //ntop标记数字栈顶元素的位置,stop标记符号栈顶元素的位置
double sum;             //结果
int kk;
//菜单类
class menu
{
public:
    void getmenu();                 //菜单的构造函数
};
//菜单的构造函数的具体实现
void menu::getmenu()
{
    cout<<"========================================================\n";
    cout<<"=================这是一个计算器程序=====================\n";
    cout<<"========================================================\n";
    cout<<"* 说明:可以进行+ - * /    操作您还可以用括号输入您的表达式 *\n";
    cout<<"* 您输入表达式不需要输=号  例:您可输入(1+2)*3//4+5 然后回车 *\n";
    cout<<"========================================================\n\n";
    cout << "\t\t输入exit回车,结束程序运行\n\n";
}
//基本+-*/计算类
class dshn
{
    char * sign;
public:
    dshn()                    //类构造函数的具体实现
    {
        sign=NULL;            //把sign的指针初始化为空
    }
    void count(char * signs);  //实现基本+-*/运算的函数
};
//基本的+-*/运算函数的具体实现
void dshn::count(char * signs)
{

    sign=signs;

    if(sign[stop]=='+')      //判断符号栈栈顶符号
    {
        num[ntop-1]+=num[ntop];    //取当前数字栈栈顶前两数字进行该符号运算,结果存入栈顶前一个单元
        ntop--;        //抛掉数字栈顶元素,以便下一个新数字存入栈顶
    }
    else if(sign[stop]=='-')
    {
        num[ntop-1]-=num[ntop];
        ntop--;
    }
    else if(sign[stop]=='*')
    {
        num[ntop-1]*=num[ntop];
        ntop--;
    }
    else if(sign[stop]=='/')
    {
        if(num[ntop]==0)
        {
            kk=1;
        }
        else
        {
            num[ntop-1]/=num[ntop];
            ntop--;
        }
    }
    else if(sign[stop]!='\0'&&sign[stop]!='('&&sign[stop]!=')') //存在错误符号
    {
        kk=1;
    }

    stop--;      //抛掉符号栈顶元素,以便下一个新符号存入栈顶
}


int main()
{
    int len,m;  //记录表达式的长度
    menu menus; // 创建一个menu类型的实例
    menus.getmenu();//调用菜单构造函数显示菜单
    while(~scanf("%s",data))
    {
        w=1;    //判断是否出现‘-’代表负号的运算符
        kk=0;  //判断是否存在错误符号的标记初始化
        m=0;   //记录同时出现连续符号的个数
        if(!(strcmp(data,"exit")))   //退出
            break;
        dshn ob;    //创建一个menu类型的实例
        ntop=0;     //记录数字栈栈顶元素的位置
        stop=0;     //记录符号栈栈顶元素的位置
        int markn=0,marks=0,marknode=0;
        double ans=0,nodes;
        len=strlen(data);        //计算表达式的长度
        for(int i=0; i<=len; i++)
        {
            if(i!=len&&(data[i]>='0'&&data[i]<='9'||data[i]=='.'))  //找出表达式字符串中的数字并转化成数字
            {
                if(data[i]=='.')//小数
                {
                    marknode=1;//标记
                    nodes=0.1;
                }
                else
                {
                    if(marknode)  //小数
                    {
                        ans=ans+(data[i]-'0')*nodes;   //转化成数字
                        nodes=nodes*0.1;
                    }
                    else   //整数
                        ans=ans*10+data[i]-'0';
                    markn=1;   //标记得到一个数字
                }

            }
            else
            {

                if(markn)    //得到一个新数字
                {
                    num[++ntop]=ans;  //将新数字存到数字栈栈顶
                    markn=0;
                    marknode=0;
                    ans=0;
                }
                else  //若没有数字,则第一个为符号或者出现连续符号
                {
                    if(data[i]!='('&&data[i]!=')'&&data[i]!='\0')
                    {
                        m++;  //连续出现符号则m++记录下来
                        if(m==2)  //若出现连续的三个符号或开始就出现两个符号,则程序必定出错,跳出循环
                        {
                            kk=1;
                            break;
                        }
                        if(data[i]=='-')   //如果出现负符号,则w记录为-1
                        {
                            w=-1;
                            continue;
                        }
                        else if(data[i]=='+')  //如果出现正符号,则w不需要变化,无影响
                            continue;
                    }
                }
                if(i==len)
                {
                    if(w==-1)
                        num[ntop]=-num[ntop];
                    break;
                }
                //表达式已计算完跳出for循环
                if(w==-1)
                    num[ntop]=-num[ntop];
                if(data[i]=='-'||data[i]=='+')  //表达式当前元素为'+'或'-'
                {
                    while(stop&&sign[stop]!='(')   //计算当前可计算的部分
                    {
                        ob.count(sign);
                    }
                    sign[++stop]=data[i];  //将新符号压入栈顶
                }
                else if(data[i]=='*'||data[i]=='/')
                {
                    while(stop&&(sign[stop]=='*'||sign[stop]=='/'))  //计算当前可计算的部分
                    {
                        ob.count(sign);
                    }
                    sign[++stop]=data[i];   //将新符号压入栈顶
                }
                else if(data[i]==')')
                {
                    while(stop&&sign[stop]!='(')
                    {
                        ob.count(sign);
                    }
                    stop--;   //括号内的值已存到数字栈,删掉'('
                }
                else
                    sign[++stop]=data[i];   
                w=1;   //运算结束后重新标记为1
                m=0;    //出现数字后重新清0
            }
        }
        if(kk==1)
        {
            cout<<"error"<<endl;
            continue;
        }
        while(stop)
        {
            ob.count(sign);
        }
        ob.count(sign);
        if(kk==1)
            cout<<"error"<<endl;
        else
            printf("%.4lf\n",num[1]);
    }
}

 

posted @ 2015-08-22 17:18  Lincy*_*  阅读(505)  评论(0编辑  收藏  举报