zoukankan      html  css  js  c++  java
  • 数据结构 栈

    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("运算符有误~~~");
            }
        }
    }
    
    
  • 相关阅读:
    windows-如何免费让电脑自带的家庭中文版升级成专业版且不需要重装
    服务器管理-windows服务器如果让服务器自动定时重启
    International Olympiad In Informatics 2009 August 8 – 15, Plovdiv, Bulgaria Contest Day 1
    USACO 2008 FEB Eating Together
    POJ 2823 Sliding Window 滑动窗口 单调队列 Monotone Queue
    1st Junior Balkan Olympiad in Informatics Boats 船 DP
    USACO 2009 FEB Fair Shuttle 庙会班车 贪心
    USACO 2007 NOV Sunscreen 防晒霜 贪心
    JN 刷墙 过程DP
    Luogu
  • 原文地址:https://www.cnblogs.com/fxzemmm/p/14847943.html
Copyright © 2011-2022 走看看