Rational 类

#include <iostream>
#include <string>
#include <stack>

using namespace std;

const int MAX_ROW = 100;

class CRational
{
    int up, down;
    void Reduce();
public:
    CRational(int _up = 0, int _down = 0)
    {
        up = _up;
        down = _down;
        if(up*down!=0) Reduce();
    }

    void Set(int _up, int _down)
    {
        up = _up;
        down = _down;
        Reduce();
    }

    CRational operator + (int num)
    {
        this->up += this->down*num;
        Reduce();
        return *this;
    }

    CRational operator + (CRational r)
    {
        this->up *= r.down;
        r.up *= this->down;
        this->up += r.up;
        this->down *= r.down;
        Reduce();
        return *this;
    }

    CRational operator * (int num)
    {
        this->up *= num;
        Reduce();
        return *this;
    }

    CRational operator * (CRational r)
    {
        this->up *= r.up;
        this->down *= r.down;
        Reduce();
        return *this;
    }

    friend CRational operator + (int num, CRational r)
    {
        return (r.operator +(num));
    }

    friend CRational operator * (int num, CRational r)
    {
        return (r.operator *(num));
    }

    friend ostream &operator<<(ostream &out, CRational r)
    {
        out<<r.up<<"/"<<r.down;
        return
    }
};

void CRational::Reduce()
{
    int a, b, temp = 1;
    int m = up>0?up:-up;
    int n = down>0?down:-down;

    while (temp)
    {
        a=m>n?m:n;
        b=m<=n?m:n;
        temp=a%b;
        m=temp;
        n=b;
    }

    up = up/n;
    down = down/n;
}

class CElement
{
    CRational r;
    int n;
    bool bInt;
public:
    CElement(int up=0, int down=0, int _n=0): r(up,down)
    {
        n = _n;
        bInt = false;
    }

    void Set(int up, int down, int _n, bool _bInt)
    {
        bInt = _bInt;
        if(!bInt)
            r.Set(up,down);
        else
            n = _n;
    }

    void Set(CRational inR)
    {
        bInt = false;
        r = inR;
        n = 0;
    }

    CRational GetRational()
    {
        return r;
    }

    friend CRational operator + (CElement valueL, CElement valueR)
    {
        if(valueL.bInt && valueR.bInt)
            return CRational(valueL.n+valueR.n, 1);
        else if (valueL.bInt)
            return (valueL.n+valueR.r);
        else if (valueR.bInt)
            return (valueL.r+valueR.n);
        else
            return (valueL.r+valueR.r);
    }

    friend CRational operator * (CElement valueL, CElement valueR)
    {
        if(valueL.bInt && valueR.bInt)
            return CRational(valueL.n*valueR.n, 1);
        else if (valueL.bInt)
            return (valueL.n*valueR.r);
        else if (valueR.bInt)
            return (valueL.r*valueR.n);
        else
            return (valueL.r*valueR.r);
    }
};

bool IsNumber(char c)
{
    if(c=='+' || c=='*' || c=='\0')
        return false;
    else
        return true;
}

char Precede(char optrLeft, char optrRight)
{
    if(optrLeft=='#')
        return '<';
    if(optrLeft==optrRight)
        return '>';
    else if(optrLeft=='+' && optrRight=='*')
        return '<';
    else
        return '>';
}

CElement StringToValue(string exp, int &i)
{
    bool bPlus = true;
    bool bInterrupt = false;
    char token;
    int up, down;
    CElement elem;

    up = 0;
    token = exp[i];

    if (token == '-') { bPlus = false; token = exp[++i];}

    do
    {
        up = up*10+(token - '0');
        i++;
        if(i==exp.size()) break;
        token = exp[i];
        if(token == '/') bInterrupt = true;
    }
    while(!bInterrupt && IsNumber(token));

    if(!bPlus) up = -up;

    if(bInterrupt)
    {
        down = 0;
        token = exp[++i];
        do
        {
            down = down*10+(token - '0');
            i++;
            if(i==exp.size()) break;
            token = exp[i];
        }
        while(IsNumber(token));
        elem.Set(up, down, 0, false);
    }
    else
    {
        elem.Set(0, 0, up, true);
    }

    return elem;
}

int main()
{
    int rowNum, i;
    string exp;
    char token;
    char theta;
    CElement value, valueLeft, valueRight;
    stack <char> optr;
    stack <CElement> opnd;
    CRational result[MAX_ROW];

    rowNum = 0;
    cin >> exp;
    while (exp != "exit" && rowNum < MAX_ROW)
    {
        optr.push('#');
        i = 0;
        while((i<exp.size()) || optr.top()!= '#')
        {
            token = exp[i];
            if (IsNumber(token))
            {
                value = StringToValue(exp, i);
                opnd.push(value);
            }
            else
            {
                if ((Precede(optr.top(),token)) == '<')
                {
                    optr.push(token);
                    i++;
                }
                else
                {
                    theta = optr.top();
                    optr.pop();
                    valueLeft = opnd.top();
                    opnd.pop();
                    valueRight = opnd.top();
                    opnd.pop();
                    if(theta == '+')
                        value.Set(valueLeft+valueRight);
                    else if (theta == '*')
                        value.Set(valueLeft*valueRight);
                    else
                        value.Set(0, 0, 0, false);
                    opnd.push(value);
                }
            }
        }
        value = opnd.top();
        result[rowNum] = value.GetRational();
        opnd.pop();
        cin >> exp;
        rowNum++;
    }

    for (i=0; i<rowNum; i++)
        cout << result[i];
}

转载于:https://www.cnblogs.com/zhaos/archive/2010/12/29/1920402.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值