一、题目
已知火星人使用的运算符为#、$,其与地球人的等价公式如下:
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;
}
}