利用栈的数据结构特点完成加减乘除四则运算


//
//  main.cpp
//  利用栈的数据结构特点完成表达式的运算
//
//  Created by 柯木超 on 2018/12/4.
//  Copyright © 2018 柯木超. All rights reserved.
//

#include <iostream>

#define maxsize 20

/**
 解决思路:
 1、自左向右扫描表达式,凡是遇到操作数一律进操作数栈
 2、当遇到运算符时候,如果他的优先级比运算符栈的栈顶元素(它前面的那个操作符)的优先级低,就取出栈顶运算符和两个连续的操作数进行运算,并将结果存入操作数栈,然后继续比较该运算符与栈顶运算符(它前面的那个操作符)的优先级,反之,就进栈保存,继续往下扫描
 3、如果遇到左括号,一律进运算符栈,右括号一律不进运算符栈,而是取出运算符栈的栈顶运算符和操作数栈的两个操作数进行运算,并将结果押入操作数栈,直到取出左括号为止
 
 第一个例子:a + b * c,我们从前向后扫描,遇到a,压到操作数栈里,遇到 + ,压到操作符栈里,下一个是 b,此时,我们是不能像后缀表达式求值那样,直接计算 a + b,然后压栈的。因为我们不确定,b 是否会先参与后面的运算,所以我们只能把 b 先压栈,继续向后扫描。看到 * 以后,再把 * 压到操作符栈里;看到 c 以后,也要把 c 先压栈,理由与 b 压栈相同。接下来,再往下扫描,就发现已经到了末尾了。那我们就可以放心地从操作符栈里取出顶上的操作符,在这个例子中,就是 *,然后再从操作数栈里取出两个操作数,就是 b 和 c,然后把b和c的积,不妨记为d,放到操作数栈里。接下来,再去看操作符栈里,还有一个 +,那就把 + 取出来,然后去操作数栈里取出 a 和 d,计算它们的和,这就是最终的结果了。
 
 第二个例子:a + b + c,我们从前向后扫描,遇到a,压到操作数栈里,遇到 + ,压到操作符栈里,下一个是 b,压到操作数栈里。再下一个,又是 + ,由于加法的结合律,我们知道,先把a + b 的结果计算出来,或者后计算,都不会影响最终的结果。所以我们就把能做的化简先做掉。就是说,在扫描到第二个操作符是 + 以后,我们就把第一个操作符取出来,再把两个操作数取出来,求和并且把和送到操作数栈里。接下来的过程与第一个例子是相同的,不再赘述了
 
 总的来说就是:
 一个操作符究竟什么时候进行运算,并不取决于它前面的那个操作符是什么,而是取决于它后面的那个操作符是什么。更具体一点讲:如果后面的操作符的运算优化级比前面的操作符高,那么前面的操作符就必须延迟计算;如果后面的操作符优化级比前面的低或者相等,那么前面的操作符就可以进行计算了
 
 参考文章:https://zhuanlan.zhihu.com/p/24556103
 **/


// 数据栈
typedef struct {
    int data[maxsize];
    int top;
}dataStask, *seqDataStask;

// 运算符栈
typedef struct {
    int data[maxsize];
    int top;
}operatorStask, *seqOperatorStask;

// 创建空栈
seqDataStask createStask(){
    seqDataStask L = (seqDataStask)malloc(sizeof(dataStask));
    L->top = -1;
    return L;
}

//  设置空栈
seqDataStask setNULLStask(seqDataStask L){
    L->top = -1;
    return L;
}

// 元素入栈
seqDataStask pushStask(seqDataStask L, int data){
    
    L->data[L->top] = data;
    L->top++;
    
    return L;
}

// 元素出栈
seqDataStask popStask(seqDataStask L, int data){
    
    L->data[L->top] = data;
    L->top--;
    
    return L;
}

// 获取运算符的优先级
int getPri(char cp){
    switch (cp) {
        case '+':
        case '-':
            return 1;
            break;
        case '*':
        case '/':
            return 2;
        case '(':
            return 3;
        default:
            break;
    }
    return 0;
}

int main(int argc, const char * argv[]) {
    
    return 0;
}


// 未完,待续

猜你喜欢

转载自blog.csdn.net/s12117719679/article/details/84790442
今日推荐