仿LISP运算

仿LISP运算

真题目录: 点击去查看

E 卷 200分题型

题目描述

LISP 语言唯一的语法就是括号要配对。

形如 (OP P1 P2 …),括号内元素由单个空格分割。

其中第一个元素 OP 为操作符,后续元素均为其参数,参数个数取决于操作符类型。

注意:

参数 P1, P2 也有可能是另外一个嵌套的 (OP P1 P2 …) ,当前 OP 类型为 add / sub / mul / div(全小写),分别代表整数的加减乘除法,简单起见,所有 OP 参数个数均为 2 。

举例:

  • 输入:(mul 3 -7)输出:-21
  • 输入:(add 1 2) 输出:3
  • 输入:(sub (mul 2 4) (div 9 3)) 输出 :5
  • 输入:(div 1 0) 输出:error

题目涉及数字均为整数,可能为负;

不考虑 32 位溢出翻转,计算过程中也不会发生 32 位溢出翻转,

除零错误时,输出 “error”,

除法遇除不尽,向下取整,即 3/2 = 1

输入描述

输入为长度不超过512的字符串,用例保证了无语法错误

输出描述

输出计算结果或者“error”

用例1

输入

(div 12 (sub 45 45))

输出

error

说明

45减45得0,12除以0为除零错误,输出error

用例2

输入

(add 1 (div -7 3))

输出

-2

说明

-7除以3向下取整得-3,1加-3得-2

题解

思路:

纯逻辑题,难点在于将括号中的片段截取出来,我的处理方案是,遍历输入的每一个字符,当遇到")“时,则在其前面必然存在一个“(”,找到其前面第一个“(”,然后截取“(”和”)"之间的内容(从栈中截取走),进行计算,将结果回填如栈中。

c++

#include <iostream>
#include <stack>
#include <vector>
#include <sstream>
#include <cmath>using namespace std;int operate(const string& op, int p1, int p2) {if (op == "add") return p1 + p2;if (op == "sub") return p1 - p2;if (op == "mul") return p1 * p2;if (op == "div") {if (p2 == 0) throw runtime_error("error");return floor(1.0 * p1 / p2);  // 向下取整}throw runtime_error("error");
}string getResult(const string& s) {// 记录一个括号开始之前栈中元素个数stack<int> leftIdx;// 存储运算符和运算数字vector<string> stack;for (size_t i = 0; i < s.length(); ++i) {if (s[i] == ')') {int l = leftIdx.top();leftIdx.pop();vector<string> fragment(stack.begin() + l, stack.end());stack.erase(stack.begin() + l, stack.end());if (fragment.size() != 3) return "error";try {int p1 = stoi(fragment[1]);int p2 = stoi(fragment[2]);int res = operate(fragment[0], p1, p2);stack.push_back(to_string(res));} catch (...) {return "error";}} else if (s[i] == '(') {leftIdx.push(stack.size());} else if (s[i] != ' ') {string token;while (i < s.length() && s[i] != ' ' && s[i] != ')') {token += s[i];++i;}--i;stack.push_back(token);}}return stack.empty() ? "error" : stack[0];
}int main() {string s;getline(cin, s);try {cout << getResult(s) << endl;} catch (const exception& e) {cout << "error" << endl;}return 0;
}

JAVA

import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.println(getResult(sc.nextLine()));}public static String getResult(String s) {LinkedList<Character> stack = new LinkedList<>();LinkedList<Integer> leftIdx = new LinkedList<>();for (int i = 0; i < s.length(); i++) {char c = s.charAt(i);if (c == ')') {List<Character> fragment = stack.subList(leftIdx.removeLast(), stack.size());StringBuilder sb = new StringBuilder();for (int j = 1; j < fragment.size(); j++) sb.append(fragment.get(j));fragment.clear();String[] tmp = sb.toString().split(" ");String op = tmp[0];int p1 = Integer.parseInt(tmp[1]);int p2 = Integer.parseInt(tmp[2]);String res = operate(op, p1, p2);if ("error".equals(res)) {return "error";} else {for (int k = 0; k < res.length(); k++) stack.add(res.charAt(k));}} else if (c == '(') {leftIdx.add(stack.size());stack.add(c);} else {stack.add(c);}}StringBuilder ans = new StringBuilder();for (Character c : stack) ans.append(c);return ans.toString();}public static String operate(String op, int p1, int p2) {switch (op) {case "add":return p1 + p2 + "";case "sub":return p1 - p2 + "";case "mul":return p1 * p2 + "";case "div":return p2 == 0 ? "error" : (int) Math.floor(p1 / (p2 + 0.0)) + "";default:return "error";}}
}

Python

import math# 输入获取
s = input()def operate(op, p1, p2):p1 = int(p1)p2 = int(p2)if op == "add":return str(p1 + p2)elif op == "sub":return str(p1 - p2)elif op == "mul":return str(p1 * p2)elif op == "div":if p2 == 0:return "error"else:return str(int(math.floor(p1 / p2)))else:return "error"# 算法入口
def getResult():stack = []leftIdx = []for i in range(len(s)):if s[i] == ')':l = leftIdx.pop()fragment = stack[l:]del stack[l:]op, p1, p2 = "".join(fragment[1:]).split(" ")res = operate(op, p1, p2)if res == "error":return "error"else:stack.extend(list(res))elif s[i] == '(':leftIdx.append(len(stack))stack.append(s[i])else:stack.append(s[i])return "".join(stack)# 调用算法
print(getResult())

JavaScript

/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");const rl = readline.createInterface({input: process.stdin,output: process.stdout,
});rl.on("line", (line) => {console.log(getResult(line));
});function getResult(s) {const stack = [];const leftIdx = [];for (let i = 0; i < s.length; i++) {if (s[i] === ")") {const fragment = stack.splice(leftIdx.pop());const [op, p1, p2] = fragment.slice(1).join("").split(" ");const res = operate(op, p1 - 0, p2 - 0);if (res === "error") return "error";else stack.push(...String(res));} else if (s[i] === "(") {leftIdx.push(stack.length);stack.push(s[i]);} else {stack.push(s[i]);}}return stack.join("");
}function operate(op, p1, p2) {switch (op) {case "add":return p1 + p2;case "sub":return p1 - p2;case "mul":return p1 * p2;case "div":return p2 === 0 ? "error" : Math.floor(p1 / p2);}
}

Go

package mainimport ("bufio""fmt""math""os""strconv"
)// operate 计算加、减、乘、除运算
func operate(op string, p1, p2 int) (int, error) {switch op {case "add":return p1 + p2, nilcase "sub":return p1 - p2, nilcase "mul":return p1 * p2, nilcase "div":if p2 == 0 {return 0, fmt.Errorf("error") // 返回错误}return int(math.Floor(float64(p1) / float64(p2))), nildefault:return 0, fmt.Errorf("error") // 无效运算符}
}// getResult 解析 LISP 表达式并计算结果
func getResult(s string) string {var stack []stringvar leftIdx []int // 记录 '(' 在 stack 中的索引for i := 0; i < len(s); i++ {if s[i] == ')' {// 取出最近的 '(' 位置if len(leftIdx) == 0 {return "error"}l := leftIdx[len(leftIdx)-1]leftIdx = leftIdx[:len(leftIdx)-1]// 取出括号内的内容fragment := stack[l:]stack = stack[:l] // 移除括号内的内容if len(fragment) != 3 {return "error"}// 解析操作符和两个操作数p1, err1 := strconv.Atoi(fragment[1])p2, err2 := strconv.Atoi(fragment[2])if err1 != nil || err2 != nil {return "error"}// 执行计算res, err := operate(fragment[0], p1, p2)if err != nil {return "error"}// 结果存入 stackstack = append(stack, strconv.Itoa(res))} else if s[i] == '(' {leftIdx = append(leftIdx, len(stack))} else if s[i] != ' ' {// 读取完整的 tokentoken := ""for i < len(s) && s[i] != ' ' && s[i] != ')' {token += string(s[i])i++}i-- // 回退一格防止跳过字符stack = append(stack, token)}}if len(stack) != 1 {return "error"}return stack[0]
}func main() {scanner := bufio.NewScanner(os.Stdin)if scanner.Scan() {expr := scanner.Text()fmt.Println(getResult(expr))}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/13311.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

11 享元(Flyweight)模式

享元模式 1.1 分类 &#xff08;对象&#xff09;结构型 1.2 提出问题 做一个车管所系统&#xff0c;将会产生大量的车辆实体&#xff0c;如果每一个实例都保存自己的所有信息&#xff0c;将会需要大量内存&#xff0c;甚至导致程序崩溃。 1.3 解决方案 运用共享技术有效…

arcgis for js范围内天地图高亮,其余底图灰暗

在GIS地图开发中&#xff0c;有时我们需要突出显示某个特定区域&#xff0c;而将其他区域灰暗处理&#xff0c;以达到视觉上的对比效果。本文将介绍如何使用ArcGIS for JavaScript实现这一功能&#xff0c;具体效果为&#xff1a;在指定范围内&#xff0c;天地图高亮显示&#…

Spring AI + Ollama 实现 DeepSeek-R1 API 服务和调用

随着大语言模型的快速发展&#xff0c;越来越多的开发者开始探索如何将这些强大的推理模型本地化运行。DeepSeek-R1&#xff0c;作为一款性能卓越的开源AI模型&#xff0c;以其低成本和出色的推理能力在技术圈内引起了广泛关注。本文将详细介绍如何使用Ollama部署DeepSeek-R1&a…

Ubuntu 20.04配置网络

1&#xff0c;检查自己网络是否配通。 网络配置成功显示的网络图标 不成功的网络图标 如果看不见网络图标&#xff0c;可以使用ping命令。连接一下百度网。 ping www.baidu.com ping失败的样子 ping成功的样子 2&#xff0c;接下来进入正题&#xff0c;我们开始配置网络。 这…

ElasticSearch入门

目录 1._cat 2.索引一个 document 3.查询document 4.更新document 5.删除document 或 index 6.批量_bulk API 1._cat Get/_cat/nodes 查看所有节点 Get/_cat/indices 查看所有索引&#xff08;indices &#xff1a;index的复数) Get/_cat/master 查看…

java练习(8)

ps:题目来自力扣 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。 假设 nums 中不等于 val 的元素数量为 k&#xff0c;要通过此题&#xff0c;您需要执行以下操作…

Java常用类

文章目录 包装类(Wrapper)包装类的继承体系装箱和拆箱包装类与String类型的相互转换 String类创建 String 对象的两种方式String 类的常见方法案例演示 StringBuffer类类的继承体系String VS StringBufferStringBuffer构造器String 和 StringBuffer 相互转换StringBuffer 类常见…

算法设计与分析三级项目--管道铺设系统

摘 要 该项目使用c算法逻辑&#xff0c;开发环境为VS2022&#xff0c;旨在通过Prim算法优化建筑物间的连接路径&#xff0c;以支持管线铺设规划。可以读取文本文件中的建筑物名称和距离的信息&#xff0c;并计算出建筑物之间的最短连接路径和总路径长度&#xff0c;同时以利用…

【C语言系列】深入理解指针(5)

深入理解指针&#xff08;5&#xff09; 一、sizeof和strlen的对比1.1sizeof1.2strlen1.3sizeof和strlen的对比 二、数组和指针笔试题解析2.1 一维数组2.2 字符数组2.2.1代码1&#xff1a;2.2.2代码2&#xff1a;2.2.3代码3&#xff1a;2.2.4代码4&#xff1a;2.2.5代码5&#…

设计模式——策略模式

设计模式——策略模式 简单介绍一个例子 策略模式是设计模式里面比较简单的设计模式&#xff0c;其特点简单又实用&#xff0c;并且可以让你的代码看起来高大上&#xff0c;维护代码时还方便扩张 多重条件语句不易维护&#xff0c;而使用策略模式可以避免使用多重条件语句&…

【玩转 Postman 接口测试与开发2_018】第14章:利用 Postman 初探 API 安全测试

《API Testing and Development with Postman》最新第二版封面 文章目录 第十四章 API 安全测试1 OWASP API 安全清单1.1 相关背景1.2 OWASP API 安全清单1.3 认证与授权1.4 破防的对象级授权&#xff08;Broken object-level authorization&#xff09;1.5 破防的属性级授权&a…

MySQL的 MVCC详解

MVCC是多版本并发控制&#xff0c;允许多个事务同时读取和写入数据库&#xff0c;而无需互相等待&#xff0c;从而提高数据库的并发性能。 在 MVCC 中&#xff0c;数据库为每个事务创建一个数据快照。每当数据被修改时&#xff0c;MySQL不会立即覆盖原有数据&#xff0c;而是生…

【Uniapp-Vue3】z-paging插件组件实现触底和下拉加载数据

一、下载z-paing插件 注意下载下载量最多的这个 进入Hbuilder以后点击“确定” 插件的官方文档地址&#xff1a; https://z-paging.zxlee.cn 二、z-paging插件的使用 在文档中向下滑动&#xff0c;会有使用方法。 使用z-paging标签将所有的内容包起来 配置标签中的属性 在s…

UG NX二次开发(Python)-API函数介绍与应用实例(三)-UFLayer类操作

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 1 前言2、UFLayer类说明3、获取当前工作图层4、移动对象到特定的图层1 前言 采用Python语言进行UG NX二次开发的帮助材料很少,采用录制的方法是一种比较容易实现的方式,但是使用UFun函数更容易上…

免费PDF 转换成 Word、PPT、Excel 格式的工具

在当今数字化办公的时代&#xff0c;文件格式的转换需求日益频繁。我们的软件应运而生&#xff0c;它是一款专业的 PDF 转换成 Word、PPT、Excel 格式的工具&#xff0c;为您的办公流程带来极大便利。 下载地址&#xff1a;https://pan.quark.cn/s/8c42ac2e4bf5 核心功能&…

deepseek从网络拓扑图生成说明文字实例

deepseek对话页面中输入问题指令&#xff1a; 我是安全测评工程师&#xff0c;正在撰写系统测评报告&#xff0c;现在需要对系统网络架构进行详细说明&#xff0c;请根据附件网络拓扑图输出详细说明文字。用总分的段落结构&#xff0c;先介绍各网络区域&#xff0c;再介绍网络…

排序算法--希尔排序

希尔排序是插入排序的改进版本&#xff0c;适合中等规模数据排序&#xff0c;性能优于简单插入排序。 // 希尔排序函数 void shellSort(int arr[], int n) {// 初始间隔&#xff08;gap&#xff09;为数组长度的一半&#xff0c;逐步缩小for (int gap n / 2; gap > 0; gap …

【NR-NTN】3GPP Release 18中NR-NTN过程描述

本文参考3GPP规范&#xff1a; 【1】《TS 38.300 V18.4.0 NR; NR and NG-RAN Overall Description; Stage2》 1. 概述 图1展示了一个非地面网络&#xff08;NTN&#xff09;的示例&#xff0c;通过NTN载荷和NTN网关为用户设备&#xff08;UE&#xff09;提供非地面NR接入。图…

python3中错误与异常初识

一. 简介 在 编写 Python时&#xff0c;经常会遇到一些报错信息。接下来开始学习 Python3 中错误和异常。 本文首先初步了解一下 Python3中的错误和异常。 二. python3 中错误与异常初识 Python 中有两种错误&#xff1a;语法错误与异常。 1. 语法错误 Python 的语法错误…

一文解释nn、nn.Module与nn.functional的用法与区别

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;零基础入门PyTorch框架_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 …