数据结构 栈

package com.数据结构;

import java.util.Scanner;

public class{
    public static void main(String[] args){
        boolean flag = true ;
        Stack stack = new Stack(5);
        Scanner sc = new Scanner(System.in);
        while(flag){
            System.out.println("p 表示入栈");
            System.out.println("P 表示出栈");
            System.out.println("l 表示遍历栈");
            System.out.println("k 表示获取栈顶元素");
            System.out.println("e 表示退出程序");
            char ch = sc.next().charAt(0);
            switch (ch){
                case 'p':{
                    int value = sc.nextInt();
                    try{
                        stack.push(value);
                    }catch (Exception e){
                        System.out.println(e.getMessage());
                    }
                    break;
                } case 'P':{
                    try{
                        System.out.println(stack.pop());
                    }catch (Exception e){
                        System.out.println(e.getMessage());
                    }
                    break;
                } case 'l':{
                    stack.list();
                    break;
                } case 'k':{
                    System.out.println(stack.peek());
                    break;
                } case 'e':{
                    flag = false ;
                    sc.close();
                    break;
                }
            }
        }
    }
}
class Stack{
    private int[] data ; //数组模拟栈
    private int length ; //栈的容量
    private int top = -1 ; //栈顶指针
    public Stack(int length){
        this.length = length ;
        data = new int[length]  ;
    }
    public void push(int data){ //入栈
        if(isFull()){ //判断是满了
            throw new RuntimeException("栈已满");
        }
        this.data[++top] = data ;
    }
    public int pop(){ //出栈
        if(isEmpty()){ //判断是否为空
            throw new RuntimeException("栈是空的");
        }
        int value = data[top--] ;
        return value ;
    }
    public boolean isFull(){ //是否是满的
        return top == this.length-1;
    }
    public boolean isEmpty(){//是否是空的
        return top == -1;
    }
    public int peek(){ //窥视 获取栈顶元素但不弹出
        return data[top];
    }
    public void list(){ //遍历栈
        for(int i=this.top-1;i>=0;i--){
            System.out.println(data[i]);
        }
    }
}

用栈计算中缀表达式 只含加减乘除的运算:

package com.数据结构;

import java.util.Scanner;

public class 栈_简易计算器 { //中缀表达式 只含加减乘除的运算
    public static void main(String[] srgs){
        Scanner sc = new Scanner(System.in);
        String str = sc.next();
        Stack1 num = new Stack1(10); //储存数字
        Stack1 ope = new Stack1(10);//储存运算符
        int index = 0;
        for(index = 0;index<str.length();){
            if(!ope.isOpe(str.substring(index,index+1).charAt(0))){ //这个位置不是运算符
                int i = 1;
                String temp = str.substring(index,index+1);
                while(index+i<str.length()&&!ope.isOpe(str.substring(index+i,index+i+1).charAt(0))){ //这些位置都是数字
                    temp+=str.substring(index+i,index+i+1);
                    i++;
                }
                index+=i;
                num.push(Integer.parseInt(temp));
            }else{ //运算符
                if(ope.isEmpty()){ //栈是空的 直接入栈
                    ope.push((int)str.substring(index,index+1).charAt(0));
                }else{
                    int pri1 = ope.pri(str.substring(index,index+1).charAt(0));
                    int pri0 = ope.pri((char)ope.peek());
                    if(pri1<=pri0){
                        int num1 = num.pop();
                        int num2 = num.pop();
                        int operr= ope.pop();
                        int ans = num.cal(num1,num2,(char)operr);
                        num.push(ans);
                        ope.push((int)str.substring(index,index+1).charAt(0));
                    }else{
                        ope.push((int)str.substring(index,index+1).charAt(0));
                    }
                }
                index++;
            }
        }
        while(!ope.isEmpty()){
            int num1 = num.pop();
            int num2 = num.pop();
            int oppp = ope.pop();
            int ans = num.cal(num1,num2,(char)oppp);
            num.push(ans);
        }
        num.list();
        sc.close();
    }
}
class Stack1{
    private int[] data ; //数组模拟栈
    private int length ; //栈的容量
    private int top = -1 ; //栈顶指针
    public Stack1(int length){
        this.length = length ;
        data = new int[length]  ;
    }
    public void push(int data){ //入栈
        if(isFull()){ //判断是满了
            throw new RuntimeException("栈已满");
        }
        this.data[++top] = data ;
    }
    public int pop(){ //出栈
        if(isEmpty()){ //判断是否为空
            throw new RuntimeException("栈是空的");
        }
        int value = data[top--] ;
        return value ;
    }
    public boolean isFull(){ //是否是满的
        return top == this.length-1;
    }
    public boolean isEmpty(){//是否是空的
        return top == -1;
    }
    public int peek(){ //窥视 获取栈顶元素但不弹出
        return data[top];
    }
    public void list(){ //遍历栈
        for(int i=this.top;i>=0;i--){
            System.out.println(data[i]);
        }
    }
    public int pri(char ch){ //获取运算符的优先级 假设只有加减乘除
        if(ch=='+'||ch=='-')
            return 0;
        else
            return 1;
    }
    public boolean isOpe(char ch){ //判断是否是运算符
        if(ch=='+'||ch=='-'||ch=='*'||ch=='/')
            return true ;
        return false;

    }
    public int cal(int num1,int num2,char ope) { //计算两个数的运算结果
        int ans = 0;
        if (ope == '+') {
            return num1 + num2;
        } else if (ope == '-') {
            return num2 - num1;
        } else if (ope == '*') {
            return num1 * num2;
        } else  {
            return num2 / num1;
        }
    }
}

package com.数据结构;

import java.util.*;
import java.util.Stack;

public class 栈_逆波兰计算器 {
    //一 :将中缀表达式转变为后缀表达式
    //二 :利用栈计算逆波兰表达式
    //例如: (3+4)×5-6 对应的后缀表达式就是 3 4 + 5 × 6 -
    //------------------------------------------------------------------
    // 针对后缀表达式求值步骤如下:
    // 1.从左至右扫描,将 3 和 4 压入堆栈;
    // 2.遇到+运算符,因此弹出 4 和 3(4 为栈顶元素,3 为次顶元素),计算出 3+4 的值,得 7,再将 7 入栈;
    // 3.将 5 入栈;
    // 4.接下来是×运算符,因此弹出 5 和 7,计算出 7×5=35,将 35 入栈;
    // 5.将 6 入栈;
    // 6.最后是-运算符,计算出 35-6 的值,即 29,由此得出最终结果
    //------------------------------------------------------------------

    public static void main(String[] args){
        System.out.println("请输入需要计算的中缀表达式");
        Scanner sc = new Scanner(System.in);
        String str = sc.next(); //读入中缀表达式

        List<String> list = toList(str);     //为了方便 我们把中缀表达式存在ArrayList中

        List<String> list1=ok(list);  //得到储存后缀表达式的List集合



        Stack<String> stack = new java.util.Stack<>();

        for(String s : list1) {
            if(s.matches("\\d+")){ //含一位之上的数字 这里我们用了正则表达式 简化了代码
               stack.push(s);
            }else{ //运算符
                int num1 = Integer.valueOf(stack.pop());
                int num2 = Integer.valueOf(stack.pop());
                char ope  = s.charAt(0);
               stack.push(String.valueOf(math(num1,num2,ope)));
            }
        }
        System.out.println(stack.pop());
    }
    public static List<String> ok(List<String > list){ //把list集合中的中缀表达式变为后缀表达式

        Stack<String> s1 = new Stack<>(); //储存运算符
        List<String>  s2 = new ArrayList<>();//因为整个过程中 s2并没有pop数据 而且我们最后需要逆序输出 所以我们直接用List集合储存

        for(String t : list){
            if(t.matches("\\d+")){ //该元素是数字
                s2.add(t);
            }else if(s1.isEmpty()||s1.peek().equals("(")){ //栈顶元素是( 或者栈空 直接入栈
                s1.push(t);
            }else if(t.equals("(")){//左括号
                s1.push(t);
            }else if(t.equals(")")){ // 右括号
                while(!s1.peek().equals("(")){
                    s2.add(s1.pop());
                }
                s1.pop();
            }else if(nb(t)>nb(s1.peek())){ //优先级比栈顶元素高
                s1.push(t);
            }else{
                s2.add(s1.pop());
                while(s1.size()!=0&&nb(t)<=nb(s1.peek())){
                    s2.add(s1.pop());
                }
                s1.push(t);
            }
        }
        while(s1.size()!=0){
            s2.add(s1.pop());
        }
        return s2 ;
    }
    public static List<String> toList(String str) { //将字符串存到List集合里
        List<String> list = new ArrayList<String>();
        int index = 0;
        String temp = "";
        while (index < str.length()) {
            temp = str.substring(index, index + 1);
            if (str.substring(index, index + 1).charAt(0) < '0' || str.substring(index, index + 1).charAt(0) > '9') { //运算符
                list.add(str.substring(index, index + 1));
            } else {
                int i = 1;
                while (index + i < str.length() && str.substring(index + i, index + i + 1).charAt(0) >= '0' && str.substring(index + i, index + i + 1).charAt(0) <= '9') {
                    temp += str.substring(index + i, index + i + 1);
                    i++;
                }
                list.add(temp);
                temp = "";
                index += i - 1;
            }
            index++;
        }
        return list ;
    }
    public static int nb(String str){ //获取运算符的优先级
        switch (str){
            case "+":
            case "-":
                return 1;
            case "*":
            case "/":
                return 2;
        }
        return 0;
    }
    public static int math(int a,int b,char c){
        if(c=='+'){
            return a+b;
        }else if(c=='*'){
            return a*b;
        }else if(c=='/'){
            return b/a;
        }else if(c=='-'){
            return b-a;
        }else{
            throw new RuntimeException("运算符有误~~~");
        }
    }
}

posted @ 2020-06-08 11:48  键盘_书生  阅读(45)  评论(0编辑  收藏  举报