1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
| #include<iostream> #include<cstdlib> #include<cstring> #include<cmath> #include<stack> using namespace std; #define N_OPTR 9 #define Opr 100 typedef enum {ADD, SUB, MUL, DIV, POW, FAC, L_P, R_P, EOE} Operator;
const char pri[N_OPTR][N_OPTR] = {
'>', '>', '<', '<', '<', '<', '<', '>', '>', '>', '>', '<', '<', '<', '<', '<', '>', '>', '>', '>', '>', '>', '<', '<', '<', '>', '>', '>', '>', '>', '>', '<', '<', '<', '>', '>', '>', '>', '>', '>', '>', '<', '<', '>', '>', '>', '>', '>', '>', '>', '>', ' ', '>', '>', '<', '<', '<', '<', '<', '<', '<', '=', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '<', '<', '<', '<', '<', '<', '<', ' ', '=' }; void readNumber(char*& p, stack<float>& stk) { stk.push((float)(*p - '0')); while (isdigit(*(++p))){ float temp = stk.top(); stk.pop(); stk.push(temp * 10 + (*p - '0')); } if ('.' != *p) return ;
float fraction = 1; while (isdigit(*(++p))){ float temp = stk.top(); stk.pop(); stk.push(temp + (*p - '0')*(fraction /= 10)); } return ; } Operator optr2rank(char op) { switch (op) { case '+' : return ADD; case '-' : return SUB; case '*' : return MUL; case '/' : return DIV; case '^' : return POW; case '!' : return FAC; case '(' : return L_P; case ')' : return R_P; case '\0': return EOE; default : exit(-1); } } char orderBetween(char op1, char op2) { return pri[optr2rank(op1)][optr2rank(op2)]; }
void append(char*& rpn, float opnd) { char buf[64] = {0}; if (opnd != (float)(int)opnd) sprintf(buf, "%.2f \0", opnd); else sprintf(buf, "%d \0", (int)opnd);
if(rpn==NULL){ rpn = (char*) malloc(sizeof(char) * (strlen(buf) + 1)); strcpy(rpn,buf); } else{ int n = strlen(rpn); rpn = (char*) realloc(rpn, sizeof(char) * (n + strlen(buf) + 1)); strcat(rpn, buf); } return ; }
void append(char*& rpn, char optr) { if(rpn == NULL){ rpn = (char*) malloc(sizeof(char) * (3)); sprintf(rpn, "%c ", optr); rpn[2] = '\0'; } else{ int n = strlen(rpn); rpn = (char*) realloc(rpn, sizeof(char) * (n + 3)); sprintf(rpn + n, "%c ", optr); rpn[n + 2] = '\0'; } return ; } int calcu(char op, float data) { if((int)data == 0) return 0; int sum_data = 1; for(int i=1;i<=(int)data;i++) sum_data *= i; return sum_data; } float calcu(float opd1,char op, float opd2) { switch(op){ case '+': return opd1+opd2; break; case '-': return opd1-opd2; break; case '*': return opd1*opd2; break; case '/': return opd1/opd2; break; case '^': return pow(opd1,opd2); break; default: return 0; break; } } bool evaluate(char* S, char*& RPN, float &result) { stack<float> opnd; stack<char> optr; optr.push('\0'); while (!optr.empty()) { if (isdigit(*S)) { readNumber(S, opnd); append(RPN, opnd.top()); } else switch(orderBetween(optr.top(), *S)) { case '<': optr.push(*S); S++; break; case '=': optr.pop(); S++; break; case '>': { char op = optr.top(); optr.pop(); append(RPN, op); if ('!' == op) { float pOpnd = opnd.top(); opnd.pop(); opnd.push(calcu(op, pOpnd)); } else { float pOpnd2 = opnd.top(); opnd.pop(); float pOpnd1 = opnd.top(); opnd.pop(); opnd.push(calcu(pOpnd1, op, pOpnd2)); } break; } default: return false; } } result = opnd.top(); opnd.pop(); return true; } int main() { float ans = 0; char* RPN = NULL; char S[Opr] = {0}; cin >> S; if(evaluate(S,RPN,ans)) cout << "Ans = " << ans << endl; else cout << "Error!" << endl; cout << "Reverse Polish Notation:\n"; cout << RPN; return 0; }
|