#P3019. 火星文计算(100分)
-
1000ms
Tried: 240
Accepted: 74
Difficulty: 1
所属公司 :
华为od
-
算法标签>栈
火星文计算(100分)
思路:栈模拟
有点类似LeetCode的计算器,但本题只有乘法和加法两种运算:面试题 16.26. 计算器 - 力扣(LeetCode)
可以将数字和操作符分别读入进来,解析成序列a 和 op
由于有优先级的区别,所以先第一遍扫描先计算#这个操作。
计算完#,剩下的都是$操作。所以可以直接从左往右扫描一遍,得到最终结果。
JavaScript
const readline = require('readline');
// 创建 readline 接口
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
let s = ''; // 保存读取的一行数据
let a = []; // 保存数字的数组
let op = []; // 保存操作类型的数组
let now = ''; // 保存当前读取的数字字符串
// 监听输入事件
rl.on('line', (line) => {
s = line.trim(); // 去除首尾空格
for (const x of s) {
if (/\d/.test(x)) { // 使用正则表达式检查字符是否是数字
now += x; // 如果是数字,追加到当前数字字符串
} else {
if (x === '#') {
op.push(1); // 如果是 '#',表示加法操作
} else {
op.push(0); // 否则表示数字入栈操作
}
a.push(now); // 将当前数字字符串转为数字并存入数组
now = ''; // 重置当前数字字符串
}
}
a.push(now); // 处理最后一个数字字符串
a = a.map(Number); // 将数组中的字符串转为数字
const n = op.length;
let i = 0;
const b = [];
while (i < n) {
if (op[i] === 1) {
const x = a[0];
const y = a[1];
const z = 4 * x + 3 * y + 2;
a.shift();
a.shift();
a.unshift(z);
i += 1;
} else {
b.push(a.shift());
i += 1;
}
}
a = [...b, ...a]; // 将 b 数组中的元素和 a 数组连接起来
const m = a.length;
for (i = 1; i < m; i++) {
const x = a[i - 1];
const y = a[i];
const z = 2 * x + y + 3;
a[i] = z;
}
console.log(a[m - 1]); // 输出最后一个元素
rl.close(); // 关闭 readline 接口
});
Java
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String s = scanner.next(); // 读取一行字符串
List<Integer> a = new ArrayList<>(); // 保存数字的数组
List<Integer> op = new ArrayList<>(); // 保存操作类型的数组
String now = ""; // 保存当前读取的数字字符串
// 遍历字符串的每个字符
for (char x : s.toCharArray()) {
if (Character.isDigit(x)) { // 如果是数字
now += x; // 追加到当前数字字符串
} else {
if (x == '#') {
op.add(1); // 如果是 '#',表示加法操作
} else {
op.add(0); // 否则表示数字入栈操作
}
a.add(Integer.parseInt(now)); // 将当前数字字符串转为数字并存入数组
now = ""; // 重置当前数字字符串
}
}
a.add(Integer.parseInt(now)); // 处理最后一个数字字符串
int n = op.size();
int i = 0;
List<Integer> b = new ArrayList<>();
// 进行一系列操作
while (i < n) {
if (op.get(i) == 1) {
int x = a.get(0);
int y = a.get(1);
int z = 4 * x + 3 * y + 2;
a.remove(0);
a.remove(0);
a.add(0, z);
i += 1;
} else {
b.add(a.remove(0));
i += 1;
}
}
b.addAll(a); // 将 b 数组中的元素和 a 数组连接起来
int m = b.size();
for (i = 1; i < m; i++) {
int x = b.get(i - 1);
int y = b.get(i);
int z = 2 * x + y + 3;
b.set(i, z);
}
System.out.println(b.get(m - 1)); // 输出最后一个元素
}
}
C++
#include <iostream>
#include <vector>
using namespace std;
int main() {
string s;
cin >> s; // 读取一行字符串
vector<int> a; // 保存数字的数组
vector<int> op; // 保存操作类型的数组
string now = ""; // 保存当前读取的数字字符串
// 遍历字符串的每个字符
for (char x : s) {
if (isdigit(x)) { // 如果是数字
now += x; // 追加到当前数字字符串
} else {
if (x == '#') {
op.push_back(1); // 如果是 '#',表示加法操作
} else {
op.push_back(0); // 否则表示数字入栈操作
}
a.push_back(stoi(now)); // 将当前数字字符串转为数字并存入数组
now = ""; // 重置当前数字字符串
}
}
a.push_back(stoi(now)); // 处理最后一个数字字符串
int n = op.size();
int i = 0;
vector<int> b;
// 进行一系列操作
while (i < n) {
if (op[i] == 1) {
int x = a[0];
int y = a[1];
int z = 4 * x + 3 * y + 2;
a.erase(a.begin(), a.begin() + 2);
a.insert(a.begin(), z);
i += 1;
} else {
b.push_back(a[0]);
a.erase(a.begin());
i += 1;
}
}
b.insert(b.end(), a.begin(), a.end()); // 将 b 数组中的元素和 a 数组连接起来
int m = b.size();
for (i = 1; i < m; i++) {
int x = b[i - 1];
int y = b[i];
int z = 2 * x + y + 3;
b[i] = z;
}
cout << b.back() << endl; // 输出最后一个元素
return 0;
}
Python
s = input() # 输入字符串表示的序列和操作符
a = [] # 存储解析后的数字序列
op = [] # 存储解析后的操作符序列
now = "" # 当前正在解析的数字
# 解析输入字符串,将数字和操作符分别存储在a和op中
for x in s:
if x.isdigit():
now += x # 如果是数字字符,添加到当前数字中
else:
if x == '#':
op.append(1) # 如果是'#'操作符,表示优先级高
else:
op.append(0) # 如果是'$'操作符,表示优先级低
a.append(now) # 将当前解析的数字添加到a中
now = "" # 重置当前数字
a.append(now) # 将最后一个数字添加到a中
a = [int(x) for x in a] # 将数字字符串转换为整数
n = len(op) # 操作符的个数
i = 0
b = [] # 存储中间计算结果的序列
# 第一遍扫描,计算'#'操作符
while i < n:
if op[i] == 1:
x = a[0]
y = a[1]
z = 4 * x + 3 * y + 2 # 计算中间结果
a.pop(0)
a.pop(0)
a = [z] + a # 更新数字序列a , 删除头两个,再把计算结果放在头部
# 这样就保证了a一直在开头运算
i += 1
else:
b.append(a.pop(0)) # 优先级低的操作符,直接添加到b中
i += 1
b += a # 将剩余的数字添加到b中
m = len(b)
for i in range(1, m, 1):
x, y = b[i - 1], b[i]
z = 2 * x + y + 3 # 计算最终结果
b[i] = z
print(b[-1]) # 输出最终结果
题目描述
已知火星人使用的运算符为 # ,$,其与地球人的等价公式如下:
x # y = 4 * x + 3 * y + 2
x $ y = 2 * x + y + 3
-
其中 x 、y 是无符号整数
-
地球人公式按 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 //有其他操作符
1234567897654321$54321 //32位整数计算溢出
输出描述
根据输入的火星人字符串输出计算结果(结尾不带回车换行)
样例1
输入
7#6$5#12
输出
157
说明:
示例:
7#6$5#12
=(4*7+3*6+2)$5#12
=48$5#12
=48$(4*5+3*12+2)
=48$58
=2*48+58+3
=157