首页 新闻 会员 周边

这是一段用面向过程的方式写的一个简单计算器,我C++基础不大好,怎么转换为面向对象的?

0
悬赏园豆:60 [已解决问题] 解决于 2014-09-03 15:16
#include <iostream>
#include <cmath>
#include <cstring>
using namespace std;
const int MaxSize = 300;
int trans(char *exp_old, char exp_new[])//算法核心:将中缀表达式转化为后缀表达式 ,其中exp_old为原表达式,exp_new为转化后的表达式
{
    struct
    {
        char data[MaxSize];//用于存放运算符
        int top;  
    } op; 

    int i = 0; //exp_new的下标
    int dh = 1;  
    op.top = -1;
    while (*exp_old != '\0')//一直循环直到检测到式子结束
    {
        switch (*exp_old)//检测输入表达式中的每一个字符
        {
        case '(': 
            op.top++;//top就变成了0
            op.data[op.top] = *exp_old;//检测到左括号时将左括号装进data数组的第一个元素里面
            dh = 1;
            exp_old++; break;//完成左括号的入栈之后就开始往后面检测
        case ')':
            while (op.data[op.top] != '(')
            {
                exp_new[i] = op.data[op.top];
                op.top--; i++;
            }
            op.top--; exp_old++; dh = 0; break;
        case '+':
        case '-':  
            if (dh == 1)   
            {
                if (*exp_old == '-')
                    op.top++; 
                    op.data[op.top] = '@';
                    exp_old++; break;
            }
            while (op.top != -1 && op.data[op.top] != '(')
            {
                exp_new[i] = op.data[op.top];
                op.top--;
                i++;
            }
            op.top++;
            op.data[op.top] = *exp_old;
            exp_old++; 
            dh = 0; break;
        case '*':
        case '/':   
            while (op.data[op.top] == '*' || op.data[op.top] == '/' || op.data[op.top] == 's')
            {
                exp_new[i] = op.data[op.top];
                op.top--;
                i++;
            }
            op.top++;
            op.data[op.top] = *exp_old;
            exp_old++;
            dh = 0; break;
        case '^':
            while (op.data[op.top] == '^')
            {
                exp_new[i] = op.data[op.top];
                op.top--;
                i++;
            }
            op.top++;
            op.data[op.top] = *exp_old;
            exp_old++; dh = 0; break;
        case '%':
            while (op.data[op.top] == '%')
            {
                exp_new[i] = op.data[op.top];
                op.top--;
                i++;
            }
            op.top++;
            op.data[op.top] = *exp_old;
            exp_old++;
            dh = 0; break;
        case '  ': exp_old++; break;
        case 's':
        case 'S':
            if ((*(exp_old + 1) == 'i' || *(exp_old + 1) == 'I') && (*(exp_old + 2) == 'n' || *(exp_old + 2) == 'N'))
            {
                op.top++;
                op.data[op.top] = 's';
                exp_old += 3;
                dh = 0;break;
            }
            else
            if ((*(exp_old + 1) == 'q' || *(exp_old + 1) == 'Q') && (*(exp_old + 2) == 'r' || *(exp_old + 2) == 'R') && (*(exp_old + 3) == 't' || *(exp_old + 3) == 'T'))
            {
                op.top++;
                op.data[op.top] = 'q';
                exp_old += 4;
                dh = 0;break;
            }
            else 
            {
                cout<<"\n有错误符号s";
                return 0;
            }

        case 'c':
        case 'C':
            if ((*(exp_old + 1) == 'o' || *(exp_old + 1) == 'O') && (*(exp_old + 2) == 's' || *(exp_old + 2) == 'S'))
            {
                op.top++;
                op.data[op.top] = 'c';
                exp_old += 3;
                dh = 0;break;
            }
            else 
            {
                cout<<"\n有错误符号s";
                return 0;
            }
        case 'T':
        case 't':
            if ((*(exp_old + 1) == 'a' || *(exp_old + 1) == 'A') && (*(exp_old + 2) == 'n' || *(exp_old + 2) == 'N'))
            {
                op.top++;
                op.data[op.top] = 't';
                exp_old += 3;
                dh = 0; break;
            }
            else 
            {
                cout<<"\n有错误符号s"; 
                return 0;
            }
        case 'e':
        case 'E':
            if ((*(exp_old + 1) == 'x' || *(exp_old + 1) == 'X') && (*(exp_old + 2) == 'p' || *(exp_old + 2) == 'P'))
            {
                op.top++;
                op.data[op.top] = 'e';
                exp_old += 3;
                dh = 0;break;
            }
            else 
            { 
                cout<<"\n有错误符号s"; 
                return 0;
            }
        case 'a':
        case 'A':
            if ((*(exp_old + 1) == 'b' || *(exp_old + 1) == 'B') && (*(exp_old + 2) == 's' || *(exp_old + 2) == 'S'))
            {
                op.top++;
                op.data[op.top] = 'a';
                exp_old += 3;
                dh = 0;break;
            }
            else 
            { 
                cout<<"\n有错误符号s"; 
                return 0;
            }
        case 'l':
        case 'L':
            if ((*(exp_old + 1) == 'o' || *(exp_old + 1) == 'O') && (*(exp_old + 2) == 'g' || *(exp_old + 2) == 'G'))
            {
                op.top++;
                op.data[op.top] = 'g';
                exp_old += 3;
                dh = 0;break;
            }
            else
            if ((*(exp_old + 1) == 'n' || *(exp_old + 1) == 'N'))
            {
                op.top++;
                op.data[op.top] = 'n';
                exp_old += 2;
                dh = 0;break;
            }
            else 
            {
                cout<<"\n有错误符号s"; 
                return 0; 
            }
        default:
            while (*exp_old >= '0' && *exp_old <= '9')
            {
                exp_new[i] = *exp_old; i++;
                exp_old++;
            }
            if (*exp_old == '.')
            {
                exp_new[i] = '.'; i++; exp_old++;
                while (*exp_old >= '0' && *exp_old <= '9')
                {
                    exp_new[i] = *exp_old; i++;
                    exp_old++;
                }
            }
            exp_new[i] = '#';  i++; dh = 0;
        }
    }
    while (op.top != -1)  
    {
        exp_new[i] = op.data[op.top];
        i++; op.top--;
    }
    exp_new[i] = '\0';   
    return 1;
}
double compvalue(char *exp_new) 
{
    struct
    {
        float data[MaxSize]; 
        int top;  
    }   st;    

    double d, x;

    st.top = -1;
    while (*exp_new != '\0') 
    {
        switch (*exp_new)
        {
        case '+':st.data[st.top - 1] = st.data[st.top - 1] + st.data[st.top];
            st.top--; break;
        case '-':st.data[st.top - 1] = st.data[st.top - 1] - st.data[st.top];
            st.top--; break;
        case '*':st.data[st.top - 1] = st.data[st.top - 1] * st.data[st.top];
            st.top--; break;
        case '/':
            if (st.data[st.top] != 0)
                st.data[st.top - 1] = st.data[st.top - 1] / st.data[st.top];
            else
            {
                cout<<"\n\t除数不能为零!\n";
                return 0;
            }
            st.top--; break;
        case '^':st.data[st.top - 1] = pow(st.data[st.top - 1], st.data[st.top]);
            st.top--; break;
        case '%':st.data[st.top - 1] = fmod(st.data[st.top - 1], st.data[st.top]);
            st.top--; break;
        case '@':st.data[st.top] = -(st.data[st.top]);
            break;
        case 's':st.data[st.top] = sin(st.data[st.top]);
            break;
        case 'c':st.data[st.top] = cos(st.data[st.top]);
            break;
        case 'q':
            if (st.data[st.top] >= 0)
                st.data[st.top] = sqrt(st.data[st.top]);
            else
            {
                cout<<"\n\t开方内的数不能小于零!\n";
                return 0;
            }
            break;
        case 'e':st.data[st.top] = exp(st.data[st.top]);
            break;
        case 't':st.data[st.top] = tan(st.data[st.top]);
            break;
        case 'a':st.data[st.top] = abs(st.data[st.top]);
            break;
        case 'g':
            if (st.data[st.top]>0)
                st.data[st.top] = log10(st.data[st.top]);
            else
            {
                cout<<"\n\tlog10内的数不能小于等于零!\n";
                return 0;
            }
            break;
        case 'n':
            if (st.data[st.top]>0)
                st.data[st.top] = log(st.data[st.top]);
            else
            {
                cout<<"\n\tln内的数不能小于等于零!\n";
                return 0;
            }
            break;
        default:
            d = 0; 
            while (*exp_new >= '0' && *exp_new <= '9')  
            {
                d = 10 * d + (*exp_new - '0');
                exp_new++;
            }
            x = 0.1;
            if (*exp_new == '.')
            {
                exp_new++;
                while (*exp_new >= '0' && *exp_new <= '9')   
                {
                    d = d + x*(*exp_new - '0');
                    x *= 0.1;
                    exp_new++;
                }
            }
            st.top++; st.data[st.top] = d;
        }
        exp_new++;
    }
    return st.data[st.top];
}
int main(int argc, char* argv[])
{
    char exp[300], exp_new[400];
    cout << "Please enter:";

    while (1)
    {
        cout << "请输入一个表达式:(按0结束本程序)\n";
        cin >> exp;
        if (strcmp(exp, "0") == 0)
            return 0;

        if (trans(exp, exp_new) == 1)
        {
            double res = compvalue(exp_new);
            cout << "=" << res << endl;
        }
    }
    return 0;
}


我是想写成面向过程的,但是不知道怎么设计类,望多多指教!

c++
d.aima的主页 d.aima | 初学一级 | 园豆:17
提问于:2014-08-25 13:40
< >
分享
最佳答案
0

代码很多,重新写代码给你,有错误也不好,关键是掌握OOP的核心思想(封装、继承、多态)之封装。给你几个建议:

这个算法牵涉到两个需求:输入和输出。

在算法执行中,trans使用到输入并输出一个字符串,compute牵涉到一个输入字符串并输出计算结果。两个方法有一个共同的字符串,就是trans的输出与compute的输入,那么这个就可以封装到类里面。

此外,trans和compute都使用了一个完全相同的结构,那么这个结构是可以公用的。

 

你自己先写,逐步的贴出代码,我来帮你修改就好。

收获园豆:60
519740105 | 大侠五级 |园豆:5810 | 2014-08-25 14:14

知道你的意思了,你可不可以大概写一下,我参考参考,不用具体的

d.aima | 园豆:17 (初学一级) | 2014-08-25 14:16

@d.aima: 

#define MAXSIZE 300
public class Computer
{
private:
    struct
    {
        char data[MAXSIZE];
        int top;
    } op;
    struct
    {
        float data[MAXSIZE];
        int top;
    } st;
    bool compiled;
    bool computed;
    char *expression;
    int result;
    int value;
public:
    void Computer(char* expression)
    {
        this.expression = expression;
    }
    void Compile()
    {
        //trans部分代码
        compiled = true;
    }
    void Compute()
    {
        //comvalue部分代码
        computed = true;
    }
    int GetValue()
    {
        if (!compiled)
        {
            compile();
        }
        if (!result && !computed)
        {
            compute();
        }
        if (result)
        {
            return value;
        }
        return -1;//错误
    }
};

大致就这样,我也好久不写C++了。

519740105 | 园豆:5810 (大侠五级) | 2014-08-25 14:28

@519740105: 能不能少少解释一下你的简单的代码,看看我又没有理解错

d.aima | 园豆:17 (初学一级) | 2014-08-28 01:58

@d.aima: 

1、把相关数据一private的方式定义了。

2、定义Computer方法(构造函数),接收要计算的原始表达式(这个定义方案,一个类实体只能针对一个表达式)

3、定义compile方法,用于编译(所谓编译就是你原本的trans方法的功能,对表达式进行简单的预处理)

4、定义compute方法执行计算操作,即你原始代码里ComValue方法的功能。

5、定义GetValue方法获取计算结果。这个方法在获取值的时候会检查表达式是否编译和计算,如果没有则顺序执行相应的操作。

519740105 | 园豆:5810 (大侠五级) | 2014-08-28 08:28
其他回答(2)
0

自己封装下,网上找找《大话设计模式》中的简单工厂模式,这样程序解决了,你又学会种设计模式。

伏草惟存 | 园豆:1420 (小虾三级) | 2014-08-25 18:08
0

凡事用到if else, switch case的地方, 都能套所谓的设计模式... 只要你不怕麻烦。

续写, | 园豆:73 (初学一级) | 2014-08-26 12:45

能不能说得详细些?

支持(0) 反对(0) d.aima | 园豆:17 (初学一级) | 2014-08-26 14:29
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册