数据结构 栈 (JAVA语言描述)

数据结构 栈 (JAVA语言描述)

栈(stack)是限定仅在表尾进行插入或者删除的线性表。对于栈来说,表尾端称为栈顶(top),表头端称为栈低(bottom)。不含元素的空表称为空栈。因为栈限定在表尾进行插入或者删除,所以栈又被称为后进先出的线性表

一些关于栈的方法及实现
大部分直接调用线性表的方法即可

    @Override
    public int size() {
        return list.size();
    }

    @Override
    public boolean isEmpty() {
        return list.isEmpty();
    }

    @Override
    public void push(E element) {
            list.add(element);
    }

    @Override
    public E pop() {
        return list.remove(list.size()-1);
    }

    @Override
    public E peek() {
            return list.get(list.size()-1);
    }

    @Override
    public void clear() {
            list.clear();
    }

    @Override
    public Iterator<E> iterator() {
        return list.iterator();
    }

中缀表达式的计算

  1. 从左到右扫描,如果扫描到的运算符优先级大于栈顶运算符优先级,则入栈,否则,出栈并运算。
  2. 如果遇到右括号,一直出栈,直到遇到左括号为止。并且每一次出栈的运算符都要做一次运算。
  3. 扫描完整个表达式后,S2栈中如果还有运算符剩余,则全部出栈,逐个计算即可。
public class InfixCalculator {
    public static void main(String[] args) {
        String s ="(10+20/2*3)/2+8";
        System.out.println(s);
      int res  =  evaluateString(s);
        System.out.println(res);
    }
    private static int evaluateString(String s){
        s= insertBlanks(s);
        String[] tokens = s.split(" ");
        ArrayStack<Character> operatorStack =new ArrayStack<>();
        ArrayStack<Integer> numberStack =new ArrayStack<>();
        for (String token: tokens) {

            if(token.length()==0){ //过滤空串
                continue;
                //遍历到加减号
            }else if (token.equals("+")||token.equals("-")){
                    while (!operatorStack.isEmpty()&&(operatorStack.peek() == '+'|| operatorStack.peek() == '-'||operatorStack.peek() == '*'||operatorStack.peek()=='/')){
                    //之前是 + - * /  需要弹栈 计算
                     processAnOperator(numberStack,operatorStack);
                    }
                    //如果操作符栈为空 或者不为空 但栈顶为 (
                    operatorStack.push((token.charAt(0)));
            }else if (token.equals("*")||token.equals("/")){ //遍历到乘除
                while (!operatorStack.isEmpty()&&(operatorStack.peek() == '*'||operatorStack.peek()=='/')){
                    processAnOperator(numberStack,operatorStack);
                }
                operatorStack.push((token.charAt(0)));
            }else if (token.equals("(")){
                operatorStack.push((token.charAt(0)));
            }else if (token.equals(")")){
                //只要操作符栈顶不是(挨个弹栈计算
                while (operatorStack.peek()!='('){
                    processAnOperator(numberStack,operatorStack);
                }
                operatorStack.pop();
            }else {
                numberStack.push(new Integer(token));
            }
        }
        while (!operatorStack.isEmpty()){
            processAnOperator(numberStack,operatorStack);
        }
        return numberStack.pop();
    }
    private static void processAnOperator(ArrayStack<Integer>numStack,ArrayStack<Character>operatorStack){
        char op=operatorStack.pop();
        int num1 =numStack.pop();
        int num2 =numStack.pop();
        if (op == '-') {
            numStack.push(num2-num1);
        }else if (op=='+'){
            numStack.push(num2+num1);
        }else if (op =='*'){
            numStack.push(num2*num1);
        }else if(op=='/'){
            numStack.push(num2/num1);
        }
    }
    //给所有非数字符号两边添加空格
    public static String insertBlanks(String S){
        StringBuilder sb = new StringBuilder();
        for(int i =0;i< S.length();i++){
            char c = S.charAt(i);
            if (c =='/'||c=='*'||c=='('||c==')'||c=='-'||c=='+'){
                sb.append(' ');
                sb.append(c);
                sb.append(' ');
            }else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

  • 中缀转后缀
 public static String infixTosuffix(String s) {
        s= insertBlanks(s);
        String[] tokens = s.split(" ");
        //操作符的栈
        ArrayStack<String> opStack = new ArrayStack<>();
        //后缀表达式的线性表
        ArrayList<String> suffixList = new ArrayList<>();
        for (String token: tokens) {
            if (token.length()==0){
                continue;
            }
            //判断操作符
            if (isOperator(token)){
                /*
                 如果栈为空进栈 栈顶为 ( 进栈 栈顶的操作符优先级比token小
                 栈顶的优先级大于等于token出栈
                */
                while (true){
                    if (opStack.isEmpty()||opStack.peek().equals("(")||priority(opStack.peek())<priority(token)){
                        opStack.push(token);
                        break;
                    }
                    suffixList.add(opStack.pop());
                }
            }else if (token.equals("(")){
                opStack.push(token);
            }else if (token.equals(")")){
                while (!opStack.peek().equals("(")){
                    suffixList.add(opStack.pop());
                }
                opStack.pop();
            }else if (isNumber(token)){
                suffixList.add(token);
            }else {
                throw new IllegalArgumentException("wrong char");
            }
        }
        while (!opStack.isEmpty()){
            suffixList.add(opStack.pop());
        }
        StringBuilder sb = new StringBuilder();
        for (int i =0;i<suffixList.size();i++){
            sb.append(suffixList.get(i));
            sb.append(' ');
        }
        return sb.toString();
    }

    private static int priority(String token) {
        if (token.equals("+")||token.equals("-")){
            return 0;
        }
        if (token.equals("*")||token.equals("/")){
            return 1;
        }
        return -1;
    }

    private static boolean isNumber(String token) {
        return token.matches("\\d+");
    }

    private static boolean isOperator(String token) {
        return token.equals("+")||token.equals("-")||token.equals("*")||token.equals("/");
    }

    //给所有非数字符号两边添加空格
    public static String insertBlanks(String S){
        StringBuilder sb = new StringBuilder();
        for(int i =0;i< S.length();i++){
            char c = S.charAt(i);
            if (c =='/'||c=='*'||c=='('||c==')'||c=='-'||c=='+'){
                sb.append(' ');
                sb.append(c);
                sb.append(' ');
            }else {
                sb.append(c);
            }
        }
        return sb.toString();
    }
}
  • 后缀计算器
public class SufixCalculator {
    public static void main(String[] args) {
        String s ="(10+20/2*3)/2+8";
     String c = InfixTosuffix.infixTosuffix(s);
     int res = evaluateSuffix(c);
        System.out.println(res);
    }

    private static int evaluateSuffix(String c) {
        ArrayStack<Integer> stack  = new ArrayStack<>();
        String[] tokens=  c.split(" ");
        for (String token: tokens) {
            if (token.length()==0){
                continue;
            }
            if (isNumber(token)){
                stack.push(new Integer((token)));
            }else {
                processAnOperator(stack,token);
            }
        }
        return stack.pop();
    }

    private static void processAnOperator(ArrayStack<Integer> stack, String token) {
        int num1 = stack.pop();
        int num2 =stack.pop();
        if (token.equals("+")){
            stack.push(num2+num1);
        }else if (token.equals("-")){
            stack.push(num2-num1);
        }else if (token.equals("*")){
            stack.push(num2*num1);
        }else if (token.equals("/")){
            stack.push(num2/num1);
        }
    }

    private static boolean isNumber(String token) {
        return token.matches("\\d+");
    }
}
  • 进制转换

十进制转十六进制

public class DecToHex {
    public static void main(String[] args) {
        int num=654321;
        ArrayStack<String> stack = new ArrayStack<>();
        while (num!=0){
            int a = num%16;
            if (a<10){
                stack.push(a+"");
            }else {
                stack.push((char)(a-10+'A')+"");
            }
            num/=16;
        }
        StringBuilder sb = new StringBuilder();
        while (!stack.isEmpty()){
            sb.append(stack.pop());
        }
        System.out.println(sb.toString());
    }
}

十六进制转十进制

public class HexToDec {
    public static void main(String[] args) {
        String hex ="9FBF1";
        ArrayStack<Character> stack = new ArrayStack<>();
        for (int i = 0;i<hex.length();i++){
            stack.push(hex.charAt(i));
        }
        int sum =0;
        int mi=0;
        while (!stack.isEmpty()){
            char c = stack.pop();
            sum+=getNumber(c)*Math.pow(16,mi);
            mi++;
        }
        System.out.println(sum);
    }

    private static int getNumber(char c) {
        if (!(c>='0'&&c<='9'||c>='A'&&c<='F')){
            throw new IllegalArgumentException("wrong char");
        }
        if (c>='0'&&c<='9'){
            return c-'0';
        }else {
            return c-'A'+10;
        }
    }
}
  • 判断回文串

用栈和双指针实现

public class Judging {
    public static void main(String[] args) {
        String text = "1234321";
        ArrayStack<Character> stack = new ArrayStack<>();
        //1 栈
        for (int i=0;i<text.length();i++){
            if (text.length()%2==1&&i==text.length()/2){
                continue;
            }
            char c =text.charAt(i);
            if (stack.isEmpty()){
                stack.push(text.charAt(i));
            }else {
                if (c!=stack.peek()){
                    stack.push(c);
                }else {
                    stack.pop();
                }
            }
        }
        System.out.println(stack.isEmpty());
        //2 双指针
        int i =0;
        int j =text.length()-1;
        while (true){
            if (text.charAt(i)==text.charAt(j)){
                i++;
                j--;
            }else {
                System.out.println("No");
                break;
            }
            if (j<=i){
                System.out.println("Yes");
                break;
            }
        }

    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值