c++四则运算
表达式计算
编写一个程序,可以计算算术表达式的值,对非法表达式要给出提示,并要求重新输入正确的表达式。(正确的表达式范例:123+45*6-78/9 或 (123+45)*(6-78)/9 等等)
题目要求:(1) 能正确计算出正确表达式的值。
(2) 要考虑表达式中的优先级。
相关知识:(1) 函数
(2) 结构
帮忙分析下。。
怎么用结构体?怎么构思。。
[解决办法]
结构应该知道是数据结构,堆栈之类的...
供参考
- C/C++ code
#include <cstring>#include <stdexcept>#include <iostream>using namespace std;template<class T = char, size_t SIZE = 256>class Stack {public: Stack (void) : m_uTop (0) {} void Push (const T& tData) { if (Full ()) throw overflow_error ("堆栈满!"); m_tData[m_uTop++] = tData; } T Pop (void) { if (Empty ()) throw underflow_error ("堆栈空!"); return m_tData[--m_uTop]; } const T& Top (void) const { if (Empty ()) throw underflow_error ("堆栈空!"); return m_tData[m_uTop-1]; } bool Full (void) const { return m_uTop >= SIZE; } bool Empty (void) const { return m_uTop == 0; }private: T m_tData[SIZE]; size_t m_uTop;};bool Prior (char cOp1, char cOp2) { return (cOp1 == '*' || cOp1 == '/') && (cOp2 == '+' || cOp2 == '-');}// 将中缀表达式转换为后缀(逆波兰)表达式string Infix2Suffix (const string& strInfix) { string strSuffix; string::size_type uLength = strInfix.length (); Stack<> stack; for (string::size_type i=0; i<uLength; i++) { // 数字和小数点 if (isdigit(strInfix[i])||strInfix[i]=='.') // 直接入表达式 strSuffix += strInfix[i]; // 左括号 else if (strInfix[i] == '(') // 直接入栈 stack.Push (strInfix[i]); // 右括号 else if (strInfix[i] == ')') { // 将相应左括号后的运算符栈入表达式 while (stack.Top () != '(') (strSuffix += ' ') += stack.Pop (); stack.Pop (); // 最后弹出左括号 } // 运算符 else if (strchr ("+-*/", strInfix[i])) { strSuffix += ' '; // 该运算符不优先于栈顶,栈入表达式 while (! stack.Empty () && stack.Top () != '(' && ! Prior (strInfix[i], stack.Top ())) (strSuffix += stack.Pop ()) += ' '; // 优者入栈 stack.Push (strInfix[i]); } } // 余者栈入表达式 while (! stack.Empty ()) (strSuffix += ' ') += stack.Pop (); return strSuffix;}// 从后缀表达式中提取运算数double ExtractOperand (const string& strSuffix, string::size_type& uPos) { double fOperand = 0; // 处理整数部分 for (; isdigit (strSuffix[uPos]); uPos++) fOperand = fOperand * 10 + strSuffix[uPos] - '0'; // 处理小数部分 if (strSuffix[uPos] == '.') { string::size_type uDecimals = 0; for (uPos++; isdigit (strSuffix[uPos]); uPos++) { fOperand = fOperand * 10 + strSuffix[uPos] - '0'; uDecimals++; } for (; uDecimals; uDecimals--) fOperand /= 10; } return fOperand;}double CalSuffix (const string& strSuffix) { string::size_type uLength=strSuffix.length (); Stack<double> stack; for (string::size_type i = 0; i<uLength;i++) { if (isdigit (strSuffix[i])) stack.Push(ExtractOperand(strSuffix,i)); else if (strchr (" \t\r\n", strSuffix[i])) i++; else if (strchr ("+-*/", strSuffix[i])) { double fOperand2 = stack.Pop (); double fOperand1 = stack.Pop (); switch (strSuffix[i]) { case '+': stack.Push(fOperand1+fOperand2); break; case '-': stack.Push(fOperand1-fOperand2); break; case '*': stack.Push(fOperand1*fOperand2); break; case '/': stack.Push(fOperand1/fOperand2); break; } i++; } } return stack.Top ();}double CalInfix (const string& strInfix) { return CalSuffix (Infix2Suffix (strInfix));}int main (void) { cout << Infix2Suffix ("2+3*4") << endl; cout << Infix2Suffix ("(2+3)*4") << endl; cout << CalSuffix (Infix2Suffix ("2+3*4")) << endl; cout << CalSuffix (Infix2Suffix ("(2+3)*4")) << endl; cout << CalInfix ("(3-6.2)*12.34/((28.88+12.3-9.2))*17.21-(13.2+3.14)*2.97") << endl; cout << (3-6.2)*12.34/((28.88+12.3-9.2))*17.21-(13.2+3.14)*2.97 << endl; return 0;}