火星报文翻译(运算符优先级)(华为od机考题)

一、题目

已知火星人使用的运算符为#、$,其与地球人的等价公式如下: 
x#y = 4*x+3*y+2  
x$y = 2*x+y+3  
2*26+12+3=5
1、其中x、y是无符号整数 
2、地球人公式按C语言规则计算 
3、火星人公式中,#的优先级高于$,相同的运算符,按从左到右的顺序计算 
现有一段火星人的字符串报文,请你来翻译并计算结果。

二、思路与代码过程

1.思路

将字符串报文转存为一栈整型数组stackNum和一栈字符数组stackOp。

在遇到“#”时,从stackNum中pop两个数字出来进行规定运算,并将结果push回stackNum;

遇到“$”时,将“$”pop进入TmpOp中,并从stackNum中pop栈顶数字到TmpNum中;

当stackOp空了(“#”处理完了),进入对TmpOp的处理(对“$”的处理);

当处理“$”时,先判断TmpNum中的元素数量,若多余2则压入stackNum,只留一位数;

对TmpNum.pop()与stcakNum.pop()进行“$”运算,并将结果压入TmpNum;

重复操作直到TmpOp为空,将最终结果压入stackNum,返回stackNum.peek()作为结果。

2.代码过程

①main函数

public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    System.out.println("请输入火星报文:");
    String[] s = sc.nextLine().split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)");//数字断和非数字断
    System.out.println(Arrays.toString(s));
    int result = Translate(s);
    System.out.println("翻译后的结果为:"+result);
    }

注意:

(例如:12#3$4#5,如果没有使用正则表达式进行区分就会存为:{1,2,#,3,$,4,#,5)

  • split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)"):使用正则表达式对读取的文本进行拆分。这里的正则表达式包含两个部分:
    • (?<=\\D)(?=\\d):这是一个零宽度断言的正则表达式,用于在一个非数字字符(\D)后面紧接着一个数字字符(\d)的地方进行拆分。
    • (?<=\\d)(?=\\D):这是另一个零宽度断言的正则表达式,用于在一个数字字符(\d)后面紧接着一个非数字字符(\D)的地方进行拆分。

这段代码会根据数字与非数字字符之间的边界进行拆分,从而将文本分割成多个子串,并将这些子串存储到字符串数组 s 中。

例如,对于输入 "abc123def456",分割后的结果将是 ["abc", "123", "def", "456"]

String[] s = sc.nextLine().split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)")

②全局变量

public static Stack<Integer> TmpNum = new Stack<>();
public static Stack<Character> TmpOp = new Stack<>();
public static Stack<Integer> stackNum = new Stack<>();
public static Stack<Character> stackOp = new Stack<>();

③Translate函数

private static int Translate(String[] s) {

        for (int i = s.length-1; i >=0; i--) {
            String ele = s[i];
            if (ele.equals("#")||ele.equals("$")) {
                stackOp.push(ele.charAt(0));
            }else {
                stackNum.push(Integer.parseInt(ele));
            }
        }
        while (!stackOp.isEmpty()) {
            if (stackOp.peek() == '#') {
                if (stackNum.size()>=2){
                    stackOp.pop();//#出来
                    stackNum.push(hashCalculate(stackNum.pop(),stackNum.pop()));//将num头两个算完放回stacknum
                }

            }else if (stackOp.peek() == '$') {
                TmpOp.push(stackOp.pop());//将$放入tmp
                TmpNum.push(stackNum.pop());//从stcaknum取出一个放入tmpnum
            }
        }
        while (!TmpOp.isEmpty()) {
            if (TmpOp.pop() == '$') {
                //解决倒序
                System.out.println(TmpNum);//1 2     7
                System.out.println(stackNum);//26    26

                if (TmpNum.size()>=2){
                    stackNum.push(TmpNum.pop());//sn:26 2 ,tn:1
                }


                System.out.println(stackNum);//sn:26 2      26
                System.out.println(TmpNum);//tn:1          7

                stackNum.push(dollarCalculate(TmpNum.pop(), stackNum.pop()));//tn: ,sn:

                System.out.println("----"+stackNum);//sn:26 2
                System.out.println(TmpNum);//

                if (TmpNum.size()==0&&stackNum.size()>=2){
                    TmpNum.push(stackNum.pop());
                }
                //存在倒序
                //eg:1$2$3#4,1去tn,$去to,2去tn,$去to,先算3#4=26存入sn;
                //算到$时,拿x=tn=2,y=sn=26,2$26=4+26+3=33存入sn;
                //再拿x=tn=1,y=sn=33,1$33=2+33+3=38.
                //正常:1$2$3#4,先算3#4=4*3+3*4+2=26
                //然后从左到右:1$2$26,先算1$2=2*1+2+3=7
                //最后7$26=2*7+26+3=43
            }
        }
        int result =stackNum.peek();
        return result;
    }

④dollarCalculate函数

 private static Integer dollarCalculate(Integer pop, Integer pop1) {
        int x =pop;
        int y = pop1;
        int result = 2*x + y+3;
        return result;
    }

⑤hashCalculate函数

private static Integer hashCalculate(Integer pop, Integer pop1) {
        int x = pop;
        int y = pop1;
        int result = 4*x+3*y+2 ;
        return result;
    }

三、运行结果

1.带数据分析完整代码

import java.util.Arrays;
import java.util.Scanner;
import java.util.Stack;

public class test17 {

    public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    System.out.println("请输入火星报文:");
    String[] s = sc.nextLine().split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)");//数字断和非数字断
    System.out.println(Arrays.toString(s));
    int result = Translate(s);
    System.out.println("翻译后的结果为:"+result);
    }

    public static Stack<Integer> TmpNum = new Stack<>();
    public static Stack<Character> TmpOp = new Stack<>();
    public static Stack<Integer> stackNum = new Stack<>();
    public static Stack<Character> stackOp = new Stack<>();
    private static int Translate(String[] s) {

        for (int i = s.length-1; i >=0; i--) {
            String ele = s[i];
            if (ele.equals("#")||ele.equals("$")) {
                stackOp.push(ele.charAt(0));
            }else {
                stackNum.push(Integer.parseInt(ele));
            }
        }
        //开始写函数
        while (!stackOp.isEmpty()) {
            if (stackOp.peek() == '#') {
                if (stackNum.size()>=2){
                    stackOp.pop();//#出来
                    stackNum.push(hashCalculate(stackNum.pop(),stackNum.pop()));//将num头两个算完放回stacknum
                }

            }else if (stackOp.peek() == '$') {
                TmpOp.push(stackOp.pop());//将$放入tmp
                TmpNum.push(stackNum.pop());//从stcaknum取出一个放入tmpnum
            }
        }
        while (!TmpOp.isEmpty()) {
            if (TmpOp.pop() == '$') {
                //解决倒序
                System.out.println(TmpNum);//1 2     7
                System.out.println(stackNum);//26    26

                if (TmpNum.size()>=2){
                    stackNum.push(TmpNum.pop());//sn:26 2 ,tn:1
                }


                System.out.println(stackNum);//sn:26 2      26
                System.out.println(TmpNum);//tn:1          7

                stackNum.push(dollarCalculate(TmpNum.pop(), stackNum.pop()));//tn: ,sn:

                System.out.println("----"+stackNum);//sn:26 2
                System.out.println(TmpNum);//

                if (TmpNum.size()==0&&stackNum.size()>=2){
                    TmpNum.push(stackNum.pop());
                }
                //存在倒序
                //eg:1$2$3#4,1去tn,$去to,2去tn,$去to,先算3#4=26存入sn;
                //算到$时,拿x=tn=2,y=sn=26,2$26=4+26+3=33存入sn;
                //再拿x=tn=1,y=sn=33,1$33=2+33+3=38.
                //正常:1$2$3#4,先算3#4=4*3+3*4+2=26
                //然后从左到右:1$2$26,先算1$2=2*1+2+3=7
                //最后7$26=2*7+26+3=43
            }
        }

        int result =stackNum.peek();
        return result;
    }

    private static Integer dollarCalculate(Integer pop, Integer pop1) {
        int x =pop;
        int y = pop1;
        int result = 2*x + y+3;
        return result;
    }

    private static Integer hashCalculate(Integer pop, Integer pop1) {
        int x = pop;
        int y = pop1;
        int result = 4*x+3*y+2 ;
        return result;
    }
}

2.运行截图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值