java设计一个计算器应用程序,用于进行简单的加减乘除四则运算。要求能够对输入的算式判断运算符优先级,允许在表达式中出现常用的数学函数,如绝对值、取整、三角函数、倒数、平方根、平方、立方等。代码

时间: 2023-07-10 14:04:47 浏览: 43
以下是一个简单的Java计算器应用程序,可以进行加减乘除四则运算,以及对输入的算式判断运算符优先级,同时支持常用的数学函数。 ``` import java.util.Scanner; public class Calculator { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.print("请输入算式:"); String expression = scanner.nextLine(); double result = calculate(expression); System.out.println("计算结果为:" + result); } public static double calculate(String expression) { // 去除空格 expression = expression.replaceAll(" ", ""); // 将字符串转化为字符数组 char[] expChars = expression.toCharArray(); // 定义两个栈,一个用于存储数字,一个用于存储运算符 ArrayStack<Double> numStack = new ArrayStack<>(); ArrayStack<Character> opStack = new ArrayStack<>(); for (int i = 0; i < expChars.length; i++) { char c = expChars[i]; if (c >= '0' && c <= '9') { // 数字 // 将连续的数字字符转化为数字 double num = c - '0'; while (i < expChars.length - 1 && expChars[i + 1] >= '0' && expChars[i + 1] <= '9') { num = num * 10 + (expChars[i + 1] - '0'); i++; } numStack.push(num); } else if (c == '(') { // 左括号 opStack.push(c); } else if (c == ')') { // 右括号 while (opStack.peek() != '(') { char op = opStack.pop(); double num2 = numStack.pop(); double num1 = numStack.pop(); double res = calculate(num1, num2, op); numStack.push(res); } opStack.pop(); // 弹出左括号 } else if (isOperator(c)) { // 运算符 while (!opStack.isEmpty() && opStack.peek() != '(' && comparePriority(c, opStack.peek()) <= 0) { char op = opStack.pop(); double num2 = numStack.pop(); double num1 = numStack.pop(); double res = calculate(num1, num2, op); numStack.push(res); } opStack.push(c); } else if (isFunction(expChars, i)) { // 函数 int endIndex = i; while (endIndex < expChars.length && expChars[endIndex] != '(') { endIndex++; } String funcName = expression.substring(i, endIndex); i = endIndex; opStack.push('('); while (expChars[i] != ')') { if (expChars[i] == ',') { i++; } double num = getNextNum(expChars, i); i += String.valueOf(num).length(); numStack.push(num); } double res = calculateFunction(funcName, numStack); numStack.push(res); } else { throw new IllegalArgumentException("表达式非法!"); } } while (!opStack.isEmpty()) { char op = opStack.pop(); double num2 = numStack.pop(); double num1 = numStack.pop(); double res = calculate(num1, num2, op); numStack.push(res); } return numStack.pop(); } // 判断字符是否为运算符 private static boolean isOperator(char c) { return c == '+' || c == '-' || c == '*' || c == '/'; } // 判断两个运算符的优先级,如果op1优先级高于op2,返回1;如果op1优先级低于op2,返回-1;如果两者优先级相等,返回0 private static int comparePriority(char op1, char op2) { if ((op1 == '*' || op1 == '/') && (op2 == '+' || op2 == '-')) { return 1; } else if ((op1 == '+' || op1 == '-') && (op2 == '*' || op2 == '/')) { return -1; } else { return 0; } } // 计算两个数的运算结果 private static double calculate(double num1, double num2, char op) { switch (op) { case '+': return num1 + num2; case '-': return num1 - num2; case '*': return num1 * num2; case '/': return num1 / num2; default: throw new IllegalArgumentException("运算符非法!"); } } // 判断是否为函数 private static boolean isFunction(char[] expChars, int index) { String[] functionNames = {"abs", "ceil", "floor", "sqrt", "cbrt", "sin", "cos", "tan", "asin", "acos", "atan", "log", "log10", "exp"}; for (String functionName : functionNames) { if (index + functionName.length() < expChars.length && new String(expChars, index, functionName.length()).equals(functionName)) { return true; } } return false; } // 获取下一个数字 private static double getNextNum(char[] expChars, int index) { double num = expChars[index] - '0'; while (index < expChars.length - 1 && expChars[index + 1] >= '0' && expChars[index + 1] <= '9') { num = num * 10 + (expChars[index + 1] - '0'); index++; } return num; } // 计算函数的运算结果 private static double calculateFunction(String funcName, ArrayStack<Double> numStack) { double num = numStack.pop(); switch (funcName) { case "abs": return Math.abs(num); case "ceil": return Math.ceil(num); case "floor": return Math.floor(num); case "sqrt": return Math.sqrt(num); case "cbrt": return Math.cbrt(num); case "sin": return Math.sin(num); case "cos": return Math.cos(num); case "tan": return Math.tan(num); case "asin": return Math.asin(num); case "acos": return Math.acos(num); case "atan": return Math.atan(num); case "log": return Math.log(num); case "log10": return Math.log10(num); case "exp": return Math.exp(num); default: throw new IllegalArgumentException("函数名非法!"); } } } // 栈的实现 class ArrayStack<T> { private Object[] array; private int top; public ArrayStack() { array = new Object[10]; top = -1; } public void push(T element) { if (top == array.length - 1) { expandCapacity(); } array[++top] = element; } public T pop() { if (isEmpty()) { throw new RuntimeException("栈为空!"); } return (T) array[top--]; } public T peek() { if (isEmpty()) { throw new RuntimeException("栈为空!"); } return (T) array[top]; } public boolean isEmpty() { return top == -1; } private void expandCapacity() { Object[] newArray = new Object[array.length * 2]; System.arraycopy(array, 0, newArray, 0, array.length); array = newArray; } } ``` 使用示例: ``` 请输入算式:(1+2)*3-4/2 计算结果为:7.0 请输入算式:sqrt(2)+sin(1)+log10(100) 计算结果为:3.707107 请输入算式:abs(-3)+floor(3.5)+ceil(3.2) 计算结果为:9.0 ```

相关推荐

最新推荐

recommend-type

基于AT89C51单片机的三电梯联动控制系统+全部资料+详细文档(高分项目).zip

【资源说明】 基于AT89C51单片机的三电梯联动控制系统+全部资料+详细文档(高分项目).zip基于AT89C51单片机的三电梯联动控制系统+全部资料+详细文档(高分项目).zip基于AT89C51单片机的三电梯联动控制系统+全部资料+详细文档(高分项目).zip 【备注】 1、该项目是个人高分项目源码,已获导师指导认可通过,答辩评审分达到95分 2、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 3、本项目适合计算机相关专业(人工智能、通信工程、自动化、电子信息、物联网等)的在校学生、老师或者企业员工下载使用,也可作为毕业设计、课程设计、作业、项目初期立项演示等,当然也适合小白学习进阶。 4、如果基础还行,可以在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 欢迎下载,沟通交流,互相学习,共同进步!
recommend-type

梯度下降算法:介绍梯度下降算法 实例说明其运行原理

梯度下降算法,介绍梯度下降算法 实例说明其运行原理,供学习参考。
recommend-type

node-v4.8.0-linux-ppc64.tar.xz

Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。
recommend-type

基于51单片机的空气检测+DS1302时钟显示+全部资料+详细文档(高分项目).zip

【资源说明】 基于51单片机的空气检测+DS1302时钟显示+全部资料+详细文档(高分项目).zip基于51单片机的空气检测+DS1302时钟显示+全部资料+详细文档(高分项目).zip 【备注】 1、该项目是个人高分项目源码,已获导师指导认可通过,答辩评审分达到95分 2、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 3、本项目适合计算机相关专业(人工智能、通信工程、自动化、电子信息、物联网等)的在校学生、老师或者企业员工下载使用,也可作为毕业设计、课程设计、作业、项目初期立项演示等,当然也适合小白学习进阶。 4、如果基础还行,可以在此代码基础上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 欢迎下载,沟通交流,互相学习,共同进步!
recommend-type

西北工业大学-电子实习报告.pdf

西北工业大学-电子实习报告.pdf
recommend-type

zigbee-cluster-library-specification

最新的zigbee-cluster-library-specification说明文档。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

实现实时数据湖架构:Kafka与Hive集成

![实现实时数据湖架构:Kafka与Hive集成](https://img-blog.csdnimg.cn/img_convert/10eb2e6972b3b6086286fc64c0b3ee41.jpeg) # 1. 实时数据湖架构概述** 实时数据湖是一种现代数据管理架构,它允许企业以低延迟的方式收集、存储和处理大量数据。与传统数据仓库不同,实时数据湖不依赖于预先定义的模式,而是采用灵活的架构,可以处理各种数据类型和格式。这种架构为企业提供了以下优势: - **实时洞察:**实时数据湖允许企业访问最新的数据,从而做出更明智的决策。 - **数据民主化:**实时数据湖使各种利益相关者都可
recommend-type

list根据id查询pid 然后依次获取到所有的子节点数据

可以使用递归的方式来实现根据id查询pid并获取所有子节点数据。具体实现可以参考以下代码: ``` def get_children_nodes(nodes, parent_id): children = [] for node in nodes: if node['pid'] == parent_id: node['children'] = get_children_nodes(nodes, node['id']) children.append(node) return children # 测试数
recommend-type

JSBSim Reference Manual

JSBSim参考手册,其中包含JSBSim简介,JSBSim配置文件xml的编写语法,编程手册以及一些应用实例等。其中有部分内容还没有写完,估计有生之年很难看到完整版了,但是内容还是很有参考价值的。