华为OD机试 2024D卷题库疯狂收录中,刷题点这里
专栏导读
本专栏收录于《华为OD机试(JAVA)真题(D卷+C卷+A卷+B卷)》。
刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。
一、题目描述
已知火星人使用的运算符号为 # 、$
他们与地球人的等价公式如下:
- x#y = 4x+3y+2
- x$y = 2*x+y+3
其中 x y 是无符号整数
地球人公式按照 C 语言规则进行计算
火星人公式中 # 符优先级高于 $
相同的运算符按从左到右的顺序运算
二、输入描述
火星人字符串表达式结尾不带回车换行。
输入的字符串说明:
字符串为仅有无符号整数和操作符组成的计算表达式
- 用例保证字符串中操作数与操作符之间没有任何分隔符
- 用例保证操作数取值范围为 32 位无符号整数
- 保证输入以及计算结果不会出现整型溢出
- 保证输入的字符串为合法的求值报文 例如: 123#4$5#76$78
- 保证不会出现非法的求值报文
例如:
- #4$5 这种缺少操作数;
- 4$5# 这种缺少操作数;
- 4#$5 这种缺少操作数;
- 4 $5 有空格;
- 3+4-5*6/7 有其他操作符;
- 12345678987654321$54321 32 位整数溢出
三、输出描述
根据火星人字符串输出计算结果,结尾不带回车换行
1、输入
7#6$5#12
2、输出
157
3、说明
7#6$5#12=(47+36+2)$5#12
=48KaTeX parse error: Expected 'EOF', got '#' at position 2: 5#̲12 =48(45+312+2)
=48$58
=2*48+58+3
=157
四、解题思路
为了求解火星人的运算表达式,我们需要解析并按优先级进行计算。具体步骤如下:
- 解析表达式:
- 使用两个栈,一个用于存储操作数,另一个用于存储操作符。
- 遇到操作数时,直接压入操作数栈。
- 遇到操作符时,依据操作符的优先级进行计算。
- 计算优先级:
- 定义 # 优先级高于 $。
- 遇到操作符时,如果当前操作符的优先级高于栈顶操作符,则压入操作符栈。
- 如果当前操作符优先级不高于栈顶操作符,则先进行栈顶操作符的计算,然后将当前操作符压入栈。
- 计算过程:
- 遇到操作符时,从操作数栈中弹出两个操作数进行计算,将结果压入操作数栈。
- 在遍历完整个表达式后,依次计算剩余的操作符,直到栈为空。
五、Java算法源码
public class Test01 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 读取火星人运算表达式
String expression = scanner.nextLine();
scanner.close();
// 计算并输出表达式的结果
System.out.print(evaluateExpression(expression));
}
public static long evaluateExpression(String expression) {
Stack<Long> nums = new Stack<>(); // 用于存储操作数
Stack<Character> ops = new Stack<>(); // 用于存储操作符
int len = expression.length();
for (int i = 0; i < len;) {
if (Character.isDigit(expression.charAt(i))) {
// 解析操作数
long num = 0;
while (i < len && Character.isDigit(expression.charAt(i))) {
num = num * 10 + expression.charAt(i) - '0';
i++;
}
nums.push(num); // 将操作数压入栈中
} else {
// 解析操作符
while (!ops.isEmpty() && precedence(ops.peek()) >= precedence(expression.charAt(i))) {
// 如果栈顶操作符优先级大于等于当前操作符,进行计算
long num2 = nums.pop(); // 弹出第二个操作数
long num1 = nums.pop(); // 弹出第一个操作数
char op = ops.pop(); // 弹出操作符
nums.push(applyOp(num1, num2, op)); // 计算并将结果压入操作数栈中
}
ops.push(expression.charAt(i)); // 将当前操作符压入操作符栈
i++;
}
}
// 处理剩余的操作符
while (!ops.isEmpty()) {
long num2 = nums.pop(); // 弹出第二个操作数
long num1 = nums.pop(); // 弹出第一个操作数
char op = ops.pop(); // 弹出操作符
nums.push(applyOp(num1, num2, op)); // 计算并将结果压入操作数栈中
}
return nums.pop(); // 返回最终结果
}
// 返回操作符的优先级
private static int precedence(char op) {
if (op == '#') return 2; // '#' 优先级为2
if (op == '$') return 1; // '$' 优先级为1
return 0;
}
// 根据操作符对操作数进行计算
private static long applyOp(long num1, long num2, char op) {
if (op == '#') {
return 4 * num1 + 3 * num2 + 2;
} else if (op == '$') {
return 2 * num1 + num2 + 3;
}
return 0;
}
}
六、效果展示
1、输入
7#6$5#12
2、输出
157
3、说明
🏆下一篇:华为OD机试 - 简易内存池 - 逻辑分析(Java 2024 C卷 200分)
🏆本文收录于,华为OD机试(JAVA)真题(D卷+C卷+A卷+B卷)
刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。