火星文计算2 双端队列 计算正则表达式

已知火星人使用的运算符为#、$,其与地球人的等价公式如下:

x#y = 4x+3y+2
xKaTeX parse error: Expected 'EOF', got '#' at position 48: …C语言规则计算 火星人公式中,#̲的优先级高于,相同的运算符,按从左到右的顺序计算
现有一段火星人的字符串报文,请你来翻译并计算结果。

输入描述
火星人字符串表达式(结尾不带回车换行)

输入的字符串说明: 字符串为仅由无符号整数和操作符(#、$)组成的计算表达式。例如:

123#4$5#67$78

用例保证字符串中,操作数与操作符之间没有任何分隔符。

用例保证操作数取值范围为32位无符号整数。

保证输入以及计算结果不会出现整型溢出。

保证输入的字符串为合法的求值报文,例如:123#4$5#67$78

保证不会出现非法的求值报文,例如类似这样字符串:

#4$5 //缺少操作数

4$5# //缺少操作数

4#$5 //缺少操作数

4 $5 //有空格

3+4-5*6/7 //有其它操作符

12345678987654321$54321 //32位整数计算溢出

输出描述
根据输入的火星人字符串输出计算结果(结尾不带回车换行)

用例1
输入
7#6$5#12
输出
157
说明
7#6$5#12

=(47+36+2)$5#12

=48$5#12

=48$(45+312+2)

=48$58

=2*48+58+3

=157

import java.util.ArrayDeque;
import java.util.Scanner;

public class Main{
    public static void main(String[] args){
       Scanner in = new Scanner(System.in);
        String inString = in.next();
        inString += "$";
        // 末尾添加一个$  方便处理
        char[] charString = inString.toCharArray();
        ArrayDeque<String> arrayDeque = new ArrayDeque<String>();
        // 双端队列 取last作栈用  用了执行#运算 每次弹出一个#和一个左操作数
        // 等#都运算完了 试着运算$的时候 用First从左向右运算

        StringBuffer num2 = new StringBuffer("");
        int t = 0;
        while (t < charString.length) {
            char temp = charString[t];
            if (temp == '#' || temp == '$') {
                // 扫描到 运算符
                // 扫描到第一个运算符 栈空 num2存放着第一个操作数===>
                // 进入check函数 由于栈空 将此数入栈
                // num2清空 运算符入栈
                // 陆续扫描形成第二个操作数
                // 扫描到第二个运算符 栈不空 num2 存放着第二个操作数===>
                // 进入check函数 栈不空 若栈顶为# 则弹出运算符# 和 第一个操作数
                // 与num2 计算结果 将结果压栈
                // 若栈顶不为 # 则 直接将num2 压栈
                // check函数结束 num2清空  将第二个运算符压栈
                // 陆续扫描第三个操作数........
                check(arrayDeque, num2.toString());
                if (t + 1 == charString.length) {
                    // 当 t+1 == 数组长度的时候 t扫描到最后一个$ 这个$是自己添加到末尾的
                    break;
                } else {
                    num2.delete(0, num2.length());
                    // StringBuffer的delete方法 从0到末尾 输入的end+1,删除0-end的全部元素
                    String stringTemp = "" + temp;
                    arrayDeque.addLast(stringTemp);
                }
            } else {
                num2.append(temp);
            }
            t++; // t向前走
        }

        // 所有 # 运算都进行完了
        // 此时 栈中应该 只有 操作数(个数>=1) 和 运算符$(个数>=0)
        // x$y == 2*x+y+3
        // 用Long.valueOf 保证 精度不出问题
        long x = Long.valueOf(arrayDeque.pollFirst());
        // 从左到右计算$
        while (arrayDeque.size() > 1) {
            arrayDeque.pollFirst();// 弹出操作符
            long y = Long.valueOf(arrayDeque.pollFirst());
            // y 为做运算数
            x = 2 * x + y + 3;
        }
        System.out.print(x);
    }

    public static void check(ArrayDeque<String> arrayDeque, String num2) {
        if (!arrayDeque.isEmpty() && arrayDeque.getLast().equals("#")) {
            // 栈不空 且 栈顶为运算符#    计算#运算结果  将结果压入栈
            arrayDeque.pollLast();
            //弹出#
            String temp1 = arrayDeque.pollLast();
            long x = Long.valueOf(temp1);
            long y = Long.valueOf(num2);

            String tempAdd = "" + (4 * x + 3 * y + 2);
            arrayDeque.addLast(tempAdd);
        } else {
            // 栈顶元素不是#则操作数2入栈
            // 或者 栈空-->操作数1入栈
            arrayDeque.addLast(num2);
        }
    }
}
posted @ 2024-08-20 10:58  在天边偷看小天使  阅读(19)  评论(0)    收藏  举报  来源