diff --git a/Makefile b/Makefile index 29339df..4f131fb 100644 --- a/Makefile +++ b/Makefile @@ -8,9 +8,11 @@ fours.o: fours.cpp g++ -c -o fours.o fours.cpp numsys.o: numsys.cpp g++ -c -o numsys.o numsys.cpp +evaluate.o: evaluate.cpp + g++ -c -o evaluate.o evaluate.cpp -MathCalc.exe: main.o linar.o fours.o numsys.o - g++ -o MathCalc.exe main.o linar.o fours.o numsys.o +MathCalc.exe: main.o linar.o fours.o numsys.o evaluate.o + g++ -o MathCalc.exe main.o linar.o fours.o numsys.o evaluate.o exec: MathCalc.exe ./MathCalc.exe diff --git a/README.md b/README.md index 4e29362..4fb6a0e 100644 --- a/README.md +++ b/README.md @@ -18,9 +18,10 @@ - [ ] 矩阵的秩 - [x] 进制转换 - [x] R1 转换为 R2 -- [ ] 表达式计算 - - [ ] 四则运算 - - [ ] 乘方运算 +- [x] 表达式计算 + - [x] 四则运算 + - [x] 乘方运算 + - [x] 阶乘运算 - [ ] 对数函数 - [ ] 开方运算 @@ -34,5 +35,10 @@ > * Ver 2.0 重构了部分方法和文件结构 * ver 2.1 添加了完整的进制转换系统 +> * Ver 3.0 添加了表达式计算功能 + + + + diff --git a/evaluate.cpp b/evaluate.cpp new file mode 100644 index 0000000..ff4bb8f --- /dev/null +++ b/evaluate.cpp @@ -0,0 +1,185 @@ +#include +#include + +#include "Stack.h" + +#define N_OPTR 9 + +using namespace std; + + +const char pri[N_OPTR][N_OPTR] = { + '>','>','<','<','<','<','<','>','>', + '>','>','<','<','<','<','<','>','>', + '>','>','>','>','<','<','<','>','>', + '>','>','>','>','<','<','<','>','>', + '>','>','>','>','>','<','<','>','>', + '>','>','>','>','>','>',' ','>','>', + '<','<','<','<','<','<','<','=',' ', + ' ',' ',' ',' ',' ',' ',' ',' ',' ', + '<','<','<','<','<','<','<',' ','=', +}; // +,-,*,/,^,!,(,),\0 + +bool isdigit(char s){ + if((s <='9' && s >= '0') ||s == '.') + return true; + else return false; +} + +int power(int a,int b){ + int sum = 1; + while((b--) > 0) + sum *= a; + return sum; +} + +char * readNumber(char *s,Stack &num){ + float new_num = 0; + new_num += (*s) - 48; + while(isdigit(*(++s))){ + new_num = new_num * 10; + new_num += (*s - 48); + } + num.push(new_num); + return s; +} + +float calcu(char op,float p){ + int new_p = (int) p; + float sum = 1; + switch(op){ + case '!': + while(new_p != 0){ + sum *= new_p--; + } + break; + } + return sum; +} + +float calcu(float p1,char op,float p2){ + switch(op){ + case '+': + return p1 + p2; + case '-': + return p1 - p2; + case '*': + return p1 * p2; + case '/': + return p1 / p2; + case '^': + return power(p1,p2); + } + return 0; +} + +char orderBetween(char s1,char s2){ + int raw,col; + switch(s1){ + case '+': + raw = 0; + break; + case '-': + raw = 1; + break; + case '*': + raw = 2; + break; + case '/': + raw = 3; + break; + case '^': + raw = 4; + break; + case '!': + raw = 5; + break; + case '(': + raw = 6; + break; + case ')': + raw = 7; + break; + case '\0': + raw = 8; + break; + } + switch(s2){ + case '+': + col = 0; + break; + case '-': + col = 1; + break; + case '*': + col = 2; + break; + case '/': + col = 3; + break; + case '^': + col = 4; + break; + case '!': + col = 5; + break; + case '(': + col = 6; + break; + case ')': + col = 7; + break; + case '\0': + col = 8; + break; + } + return pri[raw][col]; +} + +float evaluate(char *S){ + Stack opnd; + Stack optr; + optr.push('\0'); + while(!optr.empty()){ + if(isdigit(*S)){ + S = readNumber(S,opnd); + }else{ + switch(orderBetween(optr.top(),*S)){ + case '>': + { + char op = optr.pop(); + if('!' == op){ + float pOpnd = opnd.pop(); + opnd.push(calcu(op,pOpnd)); + }else{ + float pOpnd2 = opnd.pop(); + float pOpnd1 = opnd.pop(); + opnd.push(calcu(pOpnd1,op,pOpnd2)); + } + } + break; + case '<': + optr.push(*S); + S++; + break; + case '=': + optr.pop(); + S++; + break; + } + } + + } + return opnd.pop(); +} + +void expression_calc(){ + while(true){ + char exp[100]; + char *pt = exp; + cout << ">>>Input your expression:"; + scanf("%s",exp); + if (exp[0] == 'q') return; + cout << "Answer: " << evaluate(exp) << endl; + } +} diff --git a/linar.cpp b/linar.cpp index e4d1531..434e3b3 100644 --- a/linar.cpp +++ b/linar.cpp @@ -71,7 +71,7 @@ void Box::inputbox() void Box::printbox() { - cout << ">>>Display your Box:" << endl <m; ++i) { for(int j = 0; j < this->n; ++j) @@ -192,6 +192,7 @@ void Linar() for(int i = 0; i < level - 1; ++i) box2 = box2 * box1; box2.printbox(); + continue; } Box box2 (createbox()); if(op_str == "+") diff --git a/main.cpp b/main.cpp index f9a8e15..68e83a6 100644 --- a/main.cpp +++ b/main.cpp @@ -2,19 +2,18 @@ #include #include "main.h" - +#include "Stack.h" using namespace std; -// double fourans(double a, double b,string str); -// int stringconvert(string str); int main() { string str; + while(true) { - cout << ">>>Input a command:(Linar,Numsys,q):"; + cout << ">>>Input a command:(Calc,Linar,Numsys,q):"; cin >> str ; if(str == "q") { break; @@ -25,9 +24,11 @@ int main() else if((str == "numsys") || (str == "Numsys")) { Numsys(); } + else if(str == "Calc" || str == "calc"){ + expression_calc(); + } else {cout << "Error input." << endl;} } return 0; } - diff --git a/main.h b/main.h index bf90c3b..a462fca 100644 --- a/main.h +++ b/main.h @@ -1,8 +1,8 @@ #ifndef MAIN_H #define MAIN_H - void Linar(); void Numsys(); +void expression_calc(); #endif diff --git a/numsys.cpp b/numsys.cpp index 1a2e79f..4e9bbd7 100644 --- a/numsys.cpp +++ b/numsys.cpp @@ -68,18 +68,18 @@ void Numsys() do { - cout << "Input number and R1:" ; + cout << ">>>Input number and R1:" ; cin >> former; if(former == "q") break; cin >> r1; if (r1 == 0) { - cout << "R1 shouldn't be 0." << endl; + cout << "Error:R1 shouldn't be 0." << endl; continue; } cout << "To R2:"; cin >> r2; if (r2 == 0) { - cout << "R2 shouldn't be 0." << endl; + cout << "Error:R2 shouldn't be 0." << endl; continue; } else if(r2 == 10){