数据结构 -- 算术运算器设计

这是数据结构的实验~~

由于某些实验要上交,所以一部分的程序的代码改为英语注释了

这是实现中缀表达式求解,根据用户输入的算术表达式,求解表达式的值。

这里支持括号(),小数,多位数。

采用栈实现,采用了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;
}

 

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值