算术表达式的转换及求值(数据结构课程设计)

问题描述:

主要涉及的知识与技能有:堆栈的应用,要求对包含+、-、*、/、括号运算符的任意四则运算表达式进行求解。对中序输入串转换为后缀表达式(逆波兰式),计算后缀表达式的值 ,输出后缀表达式及计算结果。
例:输入:

4+3*(2-1)

输出:

后缀表达式为:4321-*+  运算结果:7

算法说明:

中缀表达式转化为后缀表达式算法:

1)首先将左括号“(”压进栈,作为栈底元素;
2) 从左到右对算数表达式进行扫描,每次读入一个字符s1[i];
3)若遇到数字,依次存入串s2中,若遇算数运算符,将“ ”(空格)追加到s2后面;
4)遇到左括号“(”则把他压入栈中;
5)若遇算术运算符,如果它们的优先级比栈顶元素高,则直接进栈,否则弹出栈顶元素追加到s2后面,直到新栈顶元素的优先级比它低,然后将它压栈;
6)若遇到右括号“)”,则将栈顶元素追加到s2后面,直到栈顶元素为“(”,然后相互抵消;
7)若到了该串的末尾,则将栈中的运算符全部输出到s2[i],并删除栈顶元素。

后缀表达式求值算法:

  1. 读入无括号的后缀表达式;
    2) 若为数字则将其入栈(存放操作数);
    3) 若为运算符,让栈顶元素和次顶元素与次运算符进行相应的运算,运算结果打印并入栈;
    4) 重复2)3)步骤,直到该字符串的末尾,则此时栈中的结果便是所追求的表达式的值。

数值转换为实数的算法描述:

1) 若为数字,则将其减去’0’的ASCII码后就得到该数的数值,并暂存于一个变量sum上;
2) 若继续为数字,也将其减去’0’的ASCII码后就得到该数的数值,并将其值加上已存的sum * 10 后的值再存于sum;
3) 重复2)步骤直到遇到“ ”(空格),即表示此时已完成转换。

C语言实现

/*************************************************************************
	> File Name: suan算术表达式求值.cpp
	> Author: kwh 
	> Mail: 
	> Created Time: 2019年12月15日 星期日 10时42分31秒
 ************************************************************************/

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <stack>
#include <queue>
#include <algorithm>
using namespace std;

stack <char> s;
stack <int> str1;

int fun (char x, int a, int b) {
    int num;
    switch (x) {
        case '+' : num = b + a; break;
        case '-' : num = b - a; break;
        case '*' : num = b * a; break;
        case '/' : num = b / a; break;
        default : break;
    }
    return num;
}

int prio (char op) {
    int priority;
    if (op == '*' || op == '/') {
        priority = 2;
    }
    if (op == '+' || op == '-') {
        priority = 1;
    }
    if (op == '(') {
        priority = 0;
    }
    return priority;
}

int main() {
    string s1, s2;
    cin >> s1;
    for (int i = 0; i < s1.size(); i++) {
        if (s1[i] >= '0' && s1[i] <= '9') {
            if (s1[i + 1] > '9' || s1[i + 1] < '0') {
                //s2 = s2 + s.top() + ' ';
                s2 += s1[i];
                s2 += ' ';
               //* cout << s1[i] << ' ';
            } else {
                //*cout << s1[i];
                s2 += s1[i];
            } //cout << s1[i];
        } else {
            if (s.empty()) {
                s.push (s1[i]);
            } else if (s1[i] == '(') {
                s.push(s1[i]);
            } else if (s1[i] == ')') {
                while (s.top() != '(') {
                    //s2 = s2 + s.top() + ' ';
                    s2 += s.top();
                    s2 += ' ';
                    //*cout << s.top() << ' ';
                    s.pop();
                }
                s.pop();
            } else {
                //cout << s.top() << endl;
                while (prio(s1[i]) <= prio(s.top())) {
                    s2 = s2 + s.top() + ' ';
                    //s2 += s.top();
                    //s2 += ' ';
                    //*cout << s.top() << ' ';
                    s.pop();
                    if (s.empty()) break;
                } 
                s.push(s1[i]);
            }
        }
    }
    
    while (!s.empty()) {
        s2 = s2 + s.top() + ' ';
        //s2 += s.top();
        //s2 += ' ';
        //*cout << s.top() << ' ';
        s.pop();
    }
    cout << '\n';
    cout << "后缀表达式为:  ";
    cout << s2 << endl;
    //cout << "&&       " << s2 << endl;
    
    //string s;
    //getline(cin, s);
    int num, sum = 0;
    for (int i = 0; i < s2.size(); i++) {
        if (s2[i] >= '0' && s2[i] <= '9') {
            if (s2[i] != ' ') {
                sum = sum * 10 + s2[i] - '0';
            }
        } else if (s2[i] == '+' || s2[i] == '-' || s2[i] == '*' || s2[i] == '/') {
            //cout << str1.top() << endl;
            int a = str1.top();
            str1.pop();
            int b = str1.top();
            str1.pop();
            num = fun (s2[i], a, b);
            str1.push(num);
        } else if (s2[i] == ' ') {
            if (sum) {
                str1.push(sum);
                sum = 0;
            }
        }
    }
    cout << "运算结果:   ";
    cout << str1.top() << endl;
    return 0;
}


oop实现

/*************************************************************************
	> File Name: 4.cpp
	> Author: kwh 
	> Mail: 
	> Created Time: 2019年12月21日 星期六 09时49分10秒
 ************************************************************************/

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2

typedef int Status;
typedef char SElemType;

#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10

class SqStack {
    private :
        SElemType *base;
        SElemType *top;
        int stacksize;
    public :
        Status InitStack (SqStack *S);
        Status StackEmpty (SqStack *S);
        Status GetTop (SElemType &e);
        Status Push (SqStack *S, SElemType e);
        Status Pop (SqStack *S, SElemType &e);
};

typedef int SElemType_1;

class SqStack_1 {
    private :
        int *base;
        int *top;
        int stacksize;
    public :
        Status InitStack_1 (SqStack_1*S);
        Status GetTop_1 (SqStack_1 *S, SElemType_1 &e);
        Status Push_1 (SqStack_1 *S, SElemType_1 e);
        Status Pop_1 (SqStack_1 *S, SElemType_1 &e);
}; //分号

//初始化
Status SqStack_1 :: InitStack_1 (SqStack_1 *S) {
    base = (SElemType_1 *) malloc (STACK_INIT_SIZE * sizeof (SElemType_1));
    if (!base) exit(OVERFLOW);
    top = base;
    stacksize = STACK_INIT_SIZE;
    return OK;
}

Status SqStack_1 :: GetTop_1 (SqStack_1 *S, SElemType_1 &e) {
    if (top == base) return ERROR;
    e = *(top - 1);
    return OK;
}

//入栈
Status SqStack_1 :: Push_1 (SqStack_1 *S_1, SElemType_1 e) {
    if (top - base >= stacksize) {
        base = (SElemType_1 *) realloc (base, (stacksize + STACK_INIT_SIZE) * sizeof (SElemType_1));
        if (!base) exit (OVERFLOW);
        top = base + stacksize;
        stacksize += STACKINCREMENT;
    }
    *top++ = e;
    return OK;
}

//删除栈顶元素
Status SqStack_1 :: Pop_1 (SqStack_1 *S_1, SElemType_1 &e) {
    if (top == base) return ERROR;
    e = * --top;
    return OK;
}

/***************************************************************************/

//初始化
Status SqStack :: InitStack (SqStack *S) {
    base = (SElemType *) malloc (STACK_INIT_SIZE * sizeof (SElemType));
    if (!base) exit(OVERFLOW);
    top = base;
    stacksize = STACK_INIT_SIZE;
    return OK;
}

//判断是否为空栈
Status SqStack :: StackEmpty (SqStack *S) {
    if (base == top) return TRUE;
    else return FALSE;
}

Status SqStack :: GetTop (SElemType &e) {
    if (top == base) return ERROR;
    e = *(top - 1);
    return OK;
}

//入栈
Status SqStack :: Push (SqStack *S, SElemType e) {
    if (top - base >= stacksize) {
        base = (SElemType *) realloc (base, (stacksize + STACK_INIT_SIZE) * sizeof (SElemType));
        if (!base) exit (OVERFLOW);
        top = base + stacksize;
        stacksize += STACKINCREMENT;
    }
    *top++ = e;
    return OK;
}

//删除栈顶元素
Status SqStack :: Pop (SqStack *S, SElemType &e) {
    if (top == base) return ERROR;
    e = * --top;
    return OK;
}

int fun (char x, int a, int b) {
    double num;
    switch (x) {
        case '+' : num = b + a; break;
        case '-' : num = b - a; break;
        case '*' : num = b * a; break;
        case '/' : num = b / a; break;
        default : break;
    }
    return num;
}

int prio (char op) {
    int priority;
    if (op == '*' || op == '/') {
        priority = 2;
    }
    if (op == '+' || op == '-') {
        priority = 1;
    }
    if (op == '(') {
        priority = 0;
    }
    return priority;
}

char data;

int main() {
    SqStack s;
    s.InitStack(&s); //定义后不要忘了初始化!!!!!!!!!!!
    SqStack_1 str1;
    str1.InitStack_1(&str1);
    string s1, s2;
    cin >> s1;

    for (int i = 0; i < s1.size(); i++) {
        if (s1[i] == '/' && s1[i + 1] == '0') {
            cout << "输入错误!" << endl; exit(0);
        }
    }

    for (int i = 0; i < s1.size(); i++) {
        if (s1[i] >= '0' && s1[i] <= '9') {
            if (s1[i + 1] > '9' || s1[i + 1] < '0') {
                s2 += s1[i];
                s2 += ' ';
            } else {
                s2 += s1[i];
            } 
        } else {
            if (s.StackEmpty(&s)) {
                s.Push (&s, s1[i]);
            } else if (s1[i] == '(') {
                s.Push(&s, s1[i]);
            } else if (s1[i] == ')') {
                while (s.Pop(&s, data)) {
                    if (data == '(') break;
                    //s2 = s2 + s.top() + ' ';
                    s2 += data;//GetTop(s, data);
                    s2 += ' ';
                }
            } else {
                s.GetTop(data);
                while (prio(s1[i]) <= prio(data)) {
                    s2 = s2 + data + ' ';//GetTop(s, data) + ' ';
                    s.Pop(&s, data);
                    if (s.StackEmpty(&s)) break;
                }
                s.Push(&s, s1[i]);
            }
        }
    }
    while (s.Pop(&s, data)) {
        s2 = s2 + data + ' ';
    }

    cout << '\n';
    cout << "后缀表达式为:  ";
    cout << s2 << endl;

    int data_1;
    int num, sum = 0;
    for (int i = 0; i < s2.size(); i++) {
        if (s2[i] >= '0' && s2[i] <= '9') {
            if (s2[i] != ' ') {
                sum = sum * 10 + s2[i] - '0';
            }
        } else if (s2[i] == '+' || s2[i] == '-' || s2[i] == '*' || s2[i] == '/') {
            str1.GetTop_1(&str1, data_1);
            int a = data_1;
            str1.Pop_1(&str1, data_1);

            str1.GetTop_1(&str1, data_1);
            int b = data_1;
            str1.Pop_1(&str1, data_1);
            num = fun (s2[i], a, b);
            str1.Push_1(&str1, num);
        } else if (s2[i] == ' ') {
            if (sum) {
                //str1.push(sum);
                str1.Push_1(&str1, sum);
                sum = 0;
            }
        }
    }
    cout << "运算结果:   ";
    str1.GetTop_1(&str1, data_1);
    cout << data_1 << endl;

    return 0;
}

运行结果截图

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44123547/article/details/103718029
今日推荐