逆波兰表达式 ——2017阿里校招题

由于在线笔试过程中,不能切出浏览器窗口,就没有采用本地 IDE 编程,直接在线徒手写.....
后来考试结束后,在本地 IDE 运行了一下,结果基本正确,放下来和大家分享一下.....(我也是试试水去的,见识到阿里的牛逼了,选择题基本不会写,就把两个编程题水了一下,这题是复制在剪切板上弄出来的)
blog.luyunfeng.cn

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/*一个对于一个单行的逆波兰表达式,由如下元素构成:
        数字:十进制数字字符构成的正整数,比如 223
        运算符:支持三种运算符^+和*,分别代表自增,加法和乘法
        分隔符:一个或者多个空格
        例如下面的字符串就是个逆波兰表达式
        2 3  4 * ^ 5 +

        逆波兰表达式在一个基于栈的虚拟机中求解,
        虚拟机的栈能保存16个整数,虚拟机从左向右扫描表达式,
        遇到整数就压栈,遇到表达式则从栈顶弹出若干个整数进行计算,
        计算结果重新压回栈中。其中运算符^从栈顶弹出一个整数,增加1之后压栈;
        运算符+和*从栈顶弹出两个整数,分别做相加和相乘运算后压栈。
        如果遇到运算符的时候,栈内没有足够的整数,称为下溢出,返回-1;
        把整数压栈的时候,如果栈没有足够的空间,称为上溢出,返回-2;
        如果整个计算过程中没有发生溢出,在整个表达式求解完成后,返回栈顶的整数。
 */
public class Main {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String line = in.nextLine();
        if (line != null && !line.isEmpty()) {
            int res = resolve(line.trim());
            //打印出结果
            System.out.println(String.valueOf(res));
        }
    }


    // 计算  放入栈前  检查是否上溢出,出栈的时候检查是否下溢出
    public static int resolve(String expr) {
        ArrayList inputs = func(expr);
        MyStack m = new MyStack();//生成逆波兰表达式的栈
        for (String s : inputs) {
            if (s.matches("\\d+")) {
                if (m.size() > 16) {
                    //上溢出
                    return -2;
                } else {
                    m.push(s);
                }

            } else if (s.equals("^")) {
                //下溢出
                if (m.size() == 0) {
                    return -1;
                } else {
                    int a = Integer.parseInt(m.pop());
                    a++;
                    m.push("" + a);
                }

            } else {
                if (m.size() < 2) {
                    //下溢出
                    return -1;
                } else {
                    int b = Integer.parseInt(m.pop());
                    int a = Integer.parseInt(m.pop());
                    if (s.equals("+")) {
                        a = a + b;
                    } else if (s.equals("*")) {
                        a = a * b;
                    }
                    m.push("" + a);
                }

            }
        }
        return Integer.parseInt(m.pop());

    }

    // 处理一下输入,将每个字符都放入数组中,
    public static ArrayList func(String expr) {
        ArrayList inputs = new ArrayList();
        String[] sa = expr.split(" ");
        for (int i = 0; i < sa.length; i++) {
            if (sa[i].equals("")) {
                continue;
            } else {
                inputs.add(sa[i]);
            }
        }
        return inputs;
    }
}


//自定义栈
class MyStack {
    private List list;
    private int size;
    public String top;

    public MyStack() {
        list = new ArrayList();
        size = 0;
        top = null;
    }

    public int size() {
        return size;
    }

    public void push(String s) {
        list.add(s);
        top = s;
        size++;
    }

    public String pop() {
        String s = list.get(size - 1);
        list.remove(size - 1);
        size--;
        top = size == 0 ? null : list.get(size - 1);
        return s;
    }
}

你可能感兴趣的:(逆波兰表达式 ——2017阿里校招题)