这是数据结构的实验~~
由于某些实验要上交,所以一部分的程序的代码改为英语注释了
这是实现中缀表达式求解,根据用户输入的算术表达式,求解表达式的值。
这里支持括号(),小数,多位数。
采用栈实现,采用了C++STL的stack类。
代码可能有点繁杂,因为也进行了对一些输入错误的判断。
Experiment.h 算术运算器的基本算法
/* Experiment.h */
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// 实验题 2.1 :算术运算器设计.
// 问题描述 :
// 设计一个模拟计算器功能的程序,它读入一个表达式,
// 如果是一个正确的表达式(即它由操作数、圆括号 和+ 、 - 、 * 、 / 四种运算符组成),
// 则求出该表达式的值;否则给出某种错误信息。
//
// 提示:
// 读入一个以字符序列形式给出的以等号( = )结尾的表达式;
// 程序中应考虑运算符的优先级、运算的合法性。
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#include
#include
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 OPND;
stack 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
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;
}