#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