#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; }
我是想写成面向过程的,但是不知道怎么设计类,望多多指教!
代码很多,重新写代码给你,有错误也不好,关键是掌握OOP的核心思想(封装、继承、多态)之封装。给你几个建议:
这个算法牵涉到两个需求:输入和输出。
在算法执行中,trans使用到输入并输出一个字符串,compute牵涉到一个输入字符串并输出计算结果。两个方法有一个共同的字符串,就是trans的输出与compute的输入,那么这个就可以封装到类里面。
此外,trans和compute都使用了一个完全相同的结构,那么这个结构是可以公用的。
你自己先写,逐步的贴出代码,我来帮你修改就好。
知道你的意思了,你可不可以大概写一下,我参考参考,不用具体的
@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: 能不能少少解释一下你的简单的代码,看看我又没有理解错
@d.aima:
1、把相关数据一private的方式定义了。
2、定义Computer方法(构造函数),接收要计算的原始表达式(这个定义方案,一个类实体只能针对一个表达式)
3、定义compile方法,用于编译(所谓编译就是你原本的trans方法的功能,对表达式进行简单的预处理)
4、定义compute方法执行计算操作,即你原始代码里ComValue方法的功能。
5、定义GetValue方法获取计算结果。这个方法在获取值的时候会检查表达式是否编译和计算,如果没有则顺序执行相应的操作。
自己封装下,网上找找《大话设计模式》中的简单工厂模式,这样程序解决了,你又学会种设计模式。
凡事用到if else, switch case的地方, 都能套所谓的设计模式... 只要你不怕麻烦。
能不能说得详细些?