# Calculator **Repository Path**: zhang-zekai-m/calculator ## Basic Information - **Project Name**: Calculator - **Description**: 计算器项目 标准计算器 科学计算器 历史记录 后缀表达式 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 6 - **Forks**: 3 - **Created**: 2023-11-15 - **Last Updated**: 2025-07-16 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 计算器项目说明 ## 1 项目简介: 本项目实现的是一个安卓计算器,具备了基础的运算功能,科学计算和历史记录功能。 ## 2 项目亮点: - 输入错误提示功能 - 历史记录功能 - 寄存器功能 - 反函数计算 - 弧度制和角度制单位切换 - 考虑到并优化了小数运算不精确的问题 ## 3 前端设计 - 竖屏 ![输入图片说明](asset/images/竖屏.png) - 横屏 ![输入图片说明](asset/images/横屏.png) ## 4 基本功能 ### (1)基础计算器 - 加减法运算 ![输入图片说明](asset/images/加减法运算.png) - 四则运算 ![输入图片说明](asset/images/四则运算.png) - 带括号和一元运算 ![输入图片说明](asset/images/带括号和一元运算.png) ### (2)科学计算器 - 包含基础运算器的功能 - 幂运算 ![输入图片说明](asset/images/幂运算.png) - 阶乘 ![输入图片说明](asset/images/阶乘运算.png) - 对数 ![输入图片说明](asset/images/对数运算.png) - 三角函数 ![输入图片说明](asset/images/三角函数.png) - 反函数计算 ![输入图片说明](asset/images/反三角函数.png) - 弧度制和角度值单位切换 ![输入图片说明](asset/images/弧度制计算.png) - 寄存器功能 ![输入图片说明](asset/images/寄存器.png) ### (3)历史记录 - 保存计算历史 ![输入图片说明](asset/images/历史记录.png) - 二次计算 ## 5 实现方法 ### (1)计算(中缀转后缀) **举例:** 中缀:3+4*3 后缀:3 4 3 * + **实现逻辑如下:** #### 输入逻辑 - 如果输入框为空或者最后一个字符是'(',则不可以输入运算符+,*,/, - 不能连续输入两个dot - 如果连续输入两个运算符,第二个运算符替换第一个运算符 - 如果最后一个字符是加号而此时输入减号,将其替换成减号 - 如果输入框最后一个是括号,输入框不变,结果框显示错误 - 如果最后是运算符,那么结果框显示错误 #### 计算逻辑 1. 表达式初步处理 ``` //如果表达式只有运算符,返回错误 //处理表达式中的阶乘 //处理表达式中的根号 //处理百分号% //处理表达式中的特殊常量比如e和π //如果最后一个字符是运算符,删除最后一个字符 //处理括号里面没有内容的情况 //处理带负号的表达式 //处理表达式中左括号前面没有运算符和右括号后面没有运算符但是有数字的情况 //如果最后一个字符是运算符,删除最后一个字符 expression=handleOnlyOperator(expression); expression=handleFactorial(expression); expression=handleSqrt(expression); expression=handlePercent(expression); expression=handleConstant(expression); expression=handleLastOperator(expression); expression=handleEmptyBracket(expression); expression=handleNegativeExpression(expression); expression=handleBracket(expression); expression=handleLastOperator(expression); //如果有错误,返回错误 if(expression.equals("error")||errorFlag){ //清空错误标识 errorFlag=false; return "错误"; } ``` 2. 中缀转后缀 ``` //将中缀表达式转换为后缀表达式 /* * 1.遍历中缀表达式的每个字符 * 2.如果是数字,需要先分析出完整的数字,直接送入后缀表达式 * 完整的数字:需要判断位数,是否包含负号 * 3.如果是左括号,入栈(左括号入栈之后优先级降至最低) * 4.如果是右括号,出栈,并将出栈的运算符送入后缀表达式,直到遇到左括号(左括号出栈,但不送入后缀表达式) * 总结:只要满足栈顶为左括号即可进行最后一次出栈 * 5.如果是运算符:(需要判断是否是完整的运算符,比如sin,cos,tan,ln,log) * 5.1.如果栈为空,直接入栈 * 5.2.如果栈不为空,比较栈顶运算符和当前运算符的优先级: * 5.2.1.如果栈顶运算符优先级高于或等于当前运算符,出栈,并将出栈的运算符送入后缀表达式,直到栈顶运算符优先级低于当前运算符,或者栈为空,最后将当前运算符入栈 * 5.2.2.如果栈顶运算符优先级低于当前运算符,直接入栈 * 总结:只要满足栈空或者优先级高于栈顶运算符即可停止出栈,并将当前运算符入栈 * 重复以上步骤,直到遍历完中缀表达式接着判断栈是否为空,如果不为空,将栈中剩余的运算符出栈,送入后缀表达式 */ ``` 3. 后缀表达式计算 ``` //计算后缀表达式 /* * 1.遍历后缀表达式的每个字符 * 2.如果是数字,需要先分析出完整的数字,直接入栈 * 3.如果是运算符,先分析出完整的字符,判断是一元还是二元运算符 * 4.重复以上步骤,直到遍历完后缀表达式,最后栈中只有一个数字,即为结果 */ ``` ### (2)历史记录 - 通过repository保存历史记录,,viewmodel保存状态,recyclerview实现滚动布局显示。 - 给每个item设置监听器跳转到计算界面。