TXT四则运算计算器

基本思想:使用getline函数从TXT文件中依次读出中缀表达式,将其转为后缀表达式后计算结果,并与用户结果比对。

整数、分数、小数的处理:将小数和整数都视为默认分母为1的分数.建立分数类,在中缀转换成后缀时将整数和小数转换为分数.

class Fenshu
{
    private:
        int fz;
        int fm;
    public:
        int getfz(){
        return fz;
        }
        int getfm(){
        return fm;
        }
        void setfz(int FZ){
        fz=FZ;
        }
        void setfm(int FM){
        if(FM!=0)
            fm=FM;
        else
            cout<<"分母不能为0\n";
        }
         Fenshu(){
        fz=-1;
        fm=-1;
        }
         Fenshu(int a,int b){
        fz=a;
        if(b!=0)
            fm=b;
        else cout<<"分母不能为0\n";
        }

         int gcd(int a, int b)//求最大公约数
        {
            if(b == 0)
                return a;
            return gcd(b, a % b);
        }
         
         void yuefen(){//约分
             int Gcd=1;
            Gcd=gcd(fz,fm);
            //cout<<"GCD:"<<Gcd<<endl;
            fz=fz/Gcd;
            fm=fm/Gcd;
    //        cout<<"results:";show();//test
         }

         Fenshu operator+(Fenshu F)
         {
             return Fenshu(fz*F.fm+F.fz*fm,fm*F.fm);
         }
          Fenshu operator-(Fenshu F)
         {
             return Fenshu(fz*F.fm-F.fz*fm,fm*F.fm);
         }
          Fenshu operator*(Fenshu F)
         {
             return Fenshu(fz*F.fz,fm*F.fm);
         }
         Fenshu operator/(Fenshu F)
         {
             return Fenshu(fz*F.fm,fm*F.fz);
         }
         void show(){
         cout<<fz<<"/"<<fm<<endl;
         }
};

关于求最大公约数所使用的辗转相除法在上一篇博文中已经写过。为了之后代码书写方便,使用了重载。

中缀转换成后缀的处理:使用栈作为数据结构.

template <class ElemType> class MyStack
{
public:
    const static  int MAXSIZE =100;
    ElemType data[MAXSIZE];
    int top;//栈顶脚标

public:
    void init();            // 初始化栈
    bool empty();            // 判断栈是否为空
    ElemType gettop();        // 读取栈顶元素(不出)
    void push(ElemType x);    // 进栈
    ElemType pop();            // 出栈
};

 

 

遇到的问题:

1.分数类定义是分子和分母作为int型变量,题目中出现的小数不能运算;

分析:要将小数转换成可存进分数的整数,小数点后每有一位,分子分母同乘10,

// 将数字字符串转变成相应的数字
Fenshu read_number(char str[],int *i)
{
    Fenshu x(0,1);
    int k = 0;
    while(str[*i] >='0' && str[*i]<='9')  // 处理整数部分
    {
        x.setfz(x.getfz()*10+(str[*i]-'0') );
        (*i)++;
    }

    if(str[*i]=='.') // 处理小数部分
    {
        (*i)++;
        while(str[*i] >= '0'&&str[*i] <='9')
        {
            x.setfz(x.getfz()*10+(str[*i]-'0'));
            x.setfm(x.getfm()*10);
            (*i)++;
            k++;
        }
    }
    return x;
}

 

2.对于存在负号'-'的题目提示栈为空;

分析:负号与减号的字符同为'-',导致在中缀转后缀时负号与减号进行了相同的操作(弹出两个栈顶的操作数)导致操作数错误操作;

解决方法:找出作为负号使用的'-',转换时替换成别的符号写入后缀表达式.计算后缀表达式时,将该符号后的数字作为0的减数压入栈

//修正负号的场合
             if (pre[i]=='-')    // 负号使用场合
            {
                if(pre[i-1]<'0' || pre[i-1]>'9' || pre[i-1]=='(' || i==0)
                {
                    post[j++]='_';
                    i++;
                    continue;
                }
            }

 

posted @ 2016-03-13 21:26  Yosha  阅读(619)  评论(0编辑  收藏  举报