利用栈实现字符串表达式计算

栈的基本机构

1、栈典型的结构,先进者后出,后进者先出,从操作特性上来看,栈是一种“操作受限”的线性表,只允许在一端插入和删除数据。

2、用数组实现的栈叫做顺序栈,用链表实现的栈,我们叫做链式栈;

栈的简单实现:

 

// 基于数组实现的顺序栈

public class ArrayStack {

  private String[] items;  // 数组

  private int count;       // 栈中元素个数

  private int n;           // 栈的大小

  // 初始化数组,申请一个大小为 n 的数组空间

  public ArrayStack(int n) {

    this.items = new String[n];

    this.n = n;

    this.count = 0;

  }

  // 入栈操作

  public boolean push(String item) {

    // 数组空间不够了,直接返回 false,入栈失败。

    if (count == n) return false;

    // 将 item 放到下标为 count 的位置,并且 count 加一

    items[count] = item;

    ++count;

    return true;

  }

  

  // 出栈操作

  public String pop() {

    // 栈为空,则直接返回 null

    if (count == 0) return null;

    // 返回下标为 count-1 的数组元素,并且栈中元素个数 count 减一

    String tmp = items[count-1];

    --count;

    return tmp;

  }

}

3、入栈和出栈的空间复杂度是O(1),时间复杂度也是O(1)

4、栈在函数调用中的应用,比较经典的应用场景就是函数调用栈

笔者利用Java栈写了一个简单的计算字符串表达式的程序:、

import javax.script.ScriptEngine;

import javax.script.ScriptEngineManager;

import javax.script.ScriptException;

import java.util.HashMap;

import java.util.Map;

import java.util.Stack;

 

/**

* @author haochajin

* @version : CalculateString.java, v 0.1 2019-09-11 10:37

*/

public class CalculateString {

    private static double calTwoNumbers(char ch, double a, double b) {

        if(ch == '+'){

            return b + a;

        } else if(ch == '-') {

            return b - a;

        }else if(ch == '*') {

            return b * a;

        }else if(ch == '/') {

            return b / a;

        }

        return 0;

    }

 

    private static double calExp(String exp){

        Stack<Double> numStack = new Stack<>();

        Stack<Character> oprStack = new Stack<>();

        Map<Character,Integer> oprMap = new HashMap<>();

        oprMap.put('+',1);

        oprMap.put('-',1);

        oprMap.put('*',2);

        oprMap.put('/',2);

        for (int i=0; i<exp.length(); i++){

            char ch = exp.charAt(i);

            if(Character.isDigit(ch)) {

                numStack.push(Double.valueOf(ch - '0'));

            } else if (oprMap.containsKey(ch)){

                if(oprStack.empty() || oprMap.get(ch) > oprMap.get(oprStack.peek())){

                    oprStack.push(ch);

                }else {

                    while (!oprStack.empty() && oprMap.get(ch) <= oprMap.get(oprStack.peek())){

                        double a = numStack.pop();

                        double b = numStack.pop();

                        numStack.push(calTwoNumbers(oprStack.pop(),a,b));

                    }

                    oprStack.push(ch);

                }

            }

        }

        while (!oprStack.empty()){

            double a = numStack.pop();

            double b = numStack.pop();

            numStack.push(calTwoNumbers(oprStack.pop(),a,b));

        }

 

        return numStack.pop();

    }

    public static void main(String[] args) throws ScriptException {

        String exp = "3/5*2-5/1*2+6*6";

        ScriptEngineManager manager = new ScriptEngineManager();

        ScriptEngine engine = manager.getEngineByName("js");

        Object ob = engine.eval(exp);

        System.out.println(calExp(exp));

        System.out.println(ob);

    }

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个简单的实现表达式求值的C语言代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #define STACK_SIZE 100 // 定义结构体 typedef struct { int top; int data[STACK_SIZE]; } Stack; // 初始化 void init(Stack *s) { s->top = -1; } // 判断是否为空 int is_empty(Stack *s) { return s->top == -1; } // 判断是否已满 int is_full(Stack *s) { return s->top == STACK_SIZE - 1; } // 入 void push(Stack *s, int x) { if (is_full(s)) { printf("Stack overflow!\n"); exit(1); } s->top++; s->data[s->top] = x; } // 出 int pop(Stack *s) { if (is_empty(s)) { printf("Stack underflow!\n"); exit(1); } int x = s->data[s->top]; s->top--; return x; } // 获取顶元素 int peek(Stack *s) { if (is_empty(s)) { printf("Stack empty!\n"); exit(1); } return s->data[s->top]; } // 判断字符是否为操作符 int is_operator(char c) { return c == '+' || c == '-' || c == '*' || c == '/'; } // 获取操作符的优先级 int precedence(char c) { if (c == '+' || c == '-') { return 1; } else if (c == '*' || c == '/') { return 2; } else { return 0; } } // 表达式求值 int evaluate(char *expr) { Stack num_stack, op_stack; init(&num_stack); init(&op_stack); int len = strlen(expr); for (int i = 0; i < len; i++) { if (isspace(expr[i])) { continue; } else if (isdigit(expr[i])) { int num = 0; while (i < len && isdigit(expr[i])) { num = num * 10 + (expr[i] - '0'); i++; } i--; push(&num_stack, num); } else if (is_operator(expr[i])) { while (!is_empty(&op_stack) && precedence(peek(&op_stack)) >= precedence(expr[i])) { int num2 = pop(&num_stack); int num1 = pop(&num_stack); char op = pop(&op_stack); switch (op) { case '+': push(&num_stack, num1 + num2); break; case '-': push(&num_stack, num1 - num2); break; case '*': push(&num_stack, num1 * num2); break; case '/': push(&num_stack, num1 / num2); break; } } push(&op_stack, expr[i]); } else { printf("Invalid character: %c\n", expr[i]); exit(1); } } while (!is_empty(&op_stack)) { int num2 = pop(&num_stack); int num1 = pop(&num_stack); char op = pop(&op_stack); switch (op) { case '+': push(&num_stack, num1 + num2); break; case '-': push(&num_stack, num1 - num2); break; case '*': push(&num_stack, num1 * num2); break; case '/': push(&num_stack, num1 / num2); break; } } return pop(&num_stack); } // 测试 int main() { char expr[100]; printf("Enter an expression: "); fgets(expr, 100, stdin); printf("Result: %d\n", evaluate(expr)); return 0; } ``` 该代码主要利用了两个实现表达式求值,一个用来存储操作数,另一个用来存储操作符。遍历表达式字符串,如果遇到数字字符,则将其转换为整数并入操作数;如果遇到操作符,则与操作符顶元素比较优先级,如果当前操作符优先级较低,则将操作符顶元素弹出并将操作数顶的两个元素进行计算,结果再入操作数。最后,将操作符中的剩余操作符依次弹出并进行计算,直到操作符为空,最后操作数中剩余的元素即为表达式的值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值