第六次作业
假期有事,实在没时间,这两天熬夜补出来
toget函数,用来将两个整书数组和符号数组汇集
void equation::toget() { strcpy_s(eq, n); int y = 0; while (m[y] != 0) y++; len = strlen(eq) + y; for (int i = 0;i= 0;j--) { eq[j + 1] = eq[j]; } eq[i] = '|'; len++; } if ((eq[i] == '(' || eq[i] == '+') || eq[i] == '-' || eq[i] == '*' || eq[i] == '/') { if (eq[i + 1] != '(') { for (int j = len - 1;j>i;j--) { eq[j + 1] = eq[j]; } eq[i + 1] = '|'; len++; } } }}
用栈计算:
主要代码:double equation::result()//读取并计算表达式直到结束为止{ do { readdata(); } while (readop()); calremain(); //处理栈中剩余的运算符 return v;}void equation::readdata() //在该出现数据的时候可能出现'(' { // 如1+((2*3)) 左括号可能是多个 while (1) //读取数据失败,此时读取应该是'(',而v为double类型 { op = eq[cnt1]; if ( op == '|') { cnt1++; v = m[cnt2++]; break; } ops.push(op); //左括号入栈 cnt1++; } ds.push(v);}bool equation::readop() //读取运算符,可能出现右括号或者换行符(表达式结束) { //如(2*(3+4/(4-5))),右括号可能是多个 while (1) { op = eq[cnt1++]; if (op != ')') break; while (ops.top() != '(') { rh = ds.top(); //取左操作数 ds.pop(); lh = ds.top();//取右操作数 ds.pop(); ds.push(cal(lh, ops.top(), rh)); //计算并入栈 ops.pop(); //取走运算符 } ops.pop(); //丢弃'(' } if (op == '=') { return false; } if (strchr("+-*/", op) == NULL) //无效运算符 { throw string("无效运算符") + op; } while (!ops.empty() && ops.top() != '(' && !prior(op, ops.top())) { rh = ds.top(); ds.pop(); lh = ds.top(); ds.pop(); ds.push(cal(lh, ops.top(), rh)); //计算并入栈 ops.pop(); //取走运算符 } ops.push(op); return true;}void equation::calremain(){ while (!ops.empty()) { rh = ds.top(); ds.pop(); lh = ds.top(); ds.pop(); ds.push(cal(lh, ops.top(), rh)); //计算并入栈 ops.pop(); //取走运算符 } if (ds.size() != 1) { throw string("无效的表达式"); } v = ds.top(); ds.pop(); return;}double equation::cal(double lh, char op, double rh){ return op == '+' ? lh + rh : op == '-' ? lh - rh : op == '*' ? lh*rh : lh / rh;}bool equation::prior(char o1, char o2)//若o1比o2优先级高返回true,否则返回false { return o1 != '+' && o1 != '-' && o2 != '*' && o2 != '/';}
运行截图
感想
赶出来的,有点累,理解起来有点难,不过我还是尽努力理解,并将计算方法和算输出联系起来。