这是数据结构的实验~~
由于某些实验要上交,所以一部分的程序的代码改为英语注释了
这是实现中缀表达式求解,根据用户输入的算术表达式,求解表达式的值。
这里支持括号(),小数,多位数。
采用栈实现,采用了C++STL的stack类。
代码可能有点繁杂,因为也进行了对一些输入错误的判断。
Experiment.h 算术运算器的基本算法
/* Experiment.h */ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // 实验题 2.1 :算术运算器设计. // 问题描述 : // 设计一个模拟计算器功能的程序,它读入一个表达式, // 如果是一个正确的表达式(即它由操作数、圆括号 和+ 、 - 、 * 、 / 四种运算符组成), // 则求出该表达式的值;否则给出某种错误信息。 // // 提示: // 读入一个以字符序列形式给出的以等号( = )结尾的表达式; // 程序中应考虑运算符的优先级、运算的合法性。 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #include <cstdio> #include <stack> using namespace std; // - - - - base constant value - - - - - const int ERROR = 0x7f800000; // infinite inline int NUMBER(char a) // translate the char to number { return (a - '0'); } // - - - - data structure - - - - - // Operator set const char OP[7] = {'+', '-', '*', '/', '(', ')', '='}; // Operand set const char NUM[11] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.'}; // Priority table const char PRI[7][7] = { // '+' '-' '*' '/' '(' ')' '=' {'>', '>', '<', '<', '<', '>', '>'}, // '+' {'>', '>', '<', '<', '<', '>', '>'}, // '-' {'>', '>', '>', '>', '<', '>', '>'}, // '*' {'>', '>', '>', '>', '<', '>', '>'}, // '/' {'<', '<', '<', '<', '<', '=', '~'}, // '(' {'>', '>', '>', '>', '~', '>', '>'}, // ')' {'<', '<', '<', '<', '<', '~', '='}, // '=' }; // - - - - - - base functions - - - - - - bool IsOperator (const char c, const char OP[7]); bool IsNumber (const char num, const char NUM[11]); int Pos (const char op, const char OP[7]); char Precede (const char op1, const char op2, const char PRI[7][7]); float Operate (const float a, const char op, const float b); float EvaluateExpression(); // evaluate the arithmetic expression float EvaluateExpression() { // operator stack: OPND; operand stack: OPTR stack<float> OPND; stack<char> OPTR; // push the finishing char '=' OPTR.push('='); char op; float a; float b; // IsExtend: true if the number is a long number // fractionNumber: the decimal numbers bool IsExtend; int fractionNumber; IsExtend = false; // c used to read the expression char c; c = getchar(); // end when OPTR is empty and the expression is empty too while (c != '=' || OPTR.top() != '=') { // - - - - - deal with the operand - - - - - - - - - IsExtend = false; while (IsNumber(c, NUM)) { // deal with the first char of a number if (!IsExtend) { if(c == '.') { //error: '.' is ahead of the number return ERROR; } OPND.push(NUMBER(c)); c = getchar(); } // deal with the other char of a number else { // deal with the decimal fraction part if (c == '.') { c = getchar(); b = 0; fractionNumber = 0; while(IsNumber(c, NUM)) { if (c == '.') { //error: multi '.' in one number return ERROR; } b = b *10 + NUMBER(c); c = getchar(); fractionNumber++; } while (fractionNumber > 0) { b = b / 10; fractionNumber--; } a = OPND.top(); OPND.pop(); OPND.push(a + b); } // deal with the non-decimal fraction part else { a = OPND.top(); OPND.pop(); if (a == 0.0) { //error: number start with a zero return ERROR; } OPND.push(a * 10 + NUMBER(c)); c = getchar(); } } IsExtend = true; } // - - - - - deal with the operator - - - - - - - - - if(IsOperator(c, OP)) { // compare the priority switch(Precede(OPTR.top(), c, PRI)) { // push the operator case '<': OPTR.push(c); c = getchar(); break; // pop a operator case '=': OPTR.pop(); c = getchar(); break; // pop tow operands and a operator, operate them with the operator case '>': op = OPTR.top(); OPTR.pop(); b = OPND.top(); OPND.pop(); a = OPND.top(); OPND.pop(); OPND.push(Operate(a, op, b)); break; // '~' means an error case '~': return ERROR; break; default: return ERROR; break; } } else { //error: illegal letter in the expression return ERROR; } } return OPND.top(); } // return true when c is in the operator set OP[7] bool IsOperator(const char c, const char OP[7]) { int i; for (i=0; i<7; i++) { if (c == OP[i]) { return true; } } return false; } // return true when num is in the operand set NUM[11] bool IsNumber(const char num, const char NUM[11]) { int i; for (i=0; i<11; i++) { if (num == NUM[i]) { return true; } } return false; } // return the operator op's position in the operator set int Pos(const char op, const char OP[7]) { int i; for (i=0; i<7; i++) { if (op == OP[i]) { return i; } } return -1; } // return the priority of op1 and op2 char Precede(const char op1, const char op2, const char PRI[7][7]) { if (!IsOperator(op1, OP) || !IsOperator(op2, OP)) { return '~'; } int i; int j; i = Pos(op1, OP); j = Pos(op2, OP); return PRI[i][j]; } // return the result of a operate b with operator op float Operate(const float a, const char op, const float b) { if (!IsOperator(op, OP)) { return ERROR; } switch(op) { case '+': return a + b; break; case '-': return a - b; break; case '*': return a * b; break; case '/': if (b == 0.0) { return ERROR; } else { return a / b; } break; default: return ERROR; break; } }
test.cpp 应用算术运算器求解用户输入表达式
/* test.cpp */ #include "Experiment2_1.h" #include <iostream> using namespace std; int main() { cout<<"/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /"<<endl; cout<<"/ - 实验题2.1:算术运算器设计. - /"<<endl; cout<<"/ - - /"<<endl; cout<<"/ - 运算数规定: - /"<<endl; cout<<"/ - 支持浮点数的运算,运算数可以多位 - /"<<endl; cout<<"/ - - /"<<endl; cout<<"/ - 输入规则: - /"<<endl; cout<<"/ - 中缀表达式输入,输入过程中不能输入空格,回车,制表符 - /"<<endl; cout<<"/ - 表达式以‘=’为结束符,输入完成后按回车 - /"<<endl; cout<<"/ - 例:1.5*2+(12-8/6)= - /"<<endl; cout<<"/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /"<<endl; cout<<endl; float result; cout<<"/ - 请输入表达式:"; result = EvaluateExpression(); cout<<endl; if (result == ERROR) { cout<<"/ - 表达式不正确,请修正表达式。"<<endl; } else { cout<<"/ - 表达式的值 = "<<result<<endl; } cout<<endl; return 0; }