开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 171|回复: 3
收起左侧

[精币悬赏] 求助各位大佬

[复制链接]
结帖率:60% (3/5)
发表于 4 天前 | 显示全部楼层 |阅读模式   陕西省榆林市
5精币
想写一个计算器,可以实现连续运算的例如(23+34*45-16/6),但是不知道用代码怎么表达加减乘除的优先级.希望各位大佬给我举例提示一下

结帖率:97% (95/98)

签到天数: 4 天

发表于 4 天前 | 显示全部楼层   安徽省宿州市
就用括号呗
((23 + 34) × 45 - 16) ÷ 6
回复

使用道具 举报

结帖率:67% (2/3)

签到天数: 3 天

发表于 4 天前 | 显示全部楼层   湖北省襄阳市
回复

使用道具 举报

签到天数: 3 天

发表于 4 天前 | 显示全部楼层   四川省泸州市

要实现支持运算优先级(如先乘除后加减)的计算器,可以使用逆波兰表达式(后缀表达式)算法递归下降解析法。以下是易语言中的实现方案:


方案一:逆波兰表达式法(推荐)

.版本 2
.支持库 spec

.子程序 计算表达式, 小数型
.参数 表达式, 文本型
.局部变量 数字栈, 小数型, , "0"
.局部变量 运算符栈, 文本型, , "0"
.局部变量 i, 整数型
.局部变量 当前字符, 文本型
.局部变量 当前数字, 文本型
.局部变量 a, 小数型
.局部变量 b, 小数型

' 预处理表达式(去除空格)
表达式 = 子文本替换 (表达式, " ", "", , , 真)

.计次循环首 (取文本长度 (表达式), i)
    当前字符 = 取文本中间 (表达式, i, 1)

    ' 处理数字
    .如果真 (是否数字 (当前字符) 或 当前字符 = ".")
        当前数字 = 当前数字 + 当前字符
        .如果真 (i = 取文本长度 (表达式) 或 不是数字 (取文本中间 (表达式, i + 1, 1)))
            加入成员 (数字栈, 到小数 (当前数字))
            当前数字 = ""
        .如果真结束
        到循环尾 ()
    .如果真结束

    ' 处理运算符优先级
    .判断开始 (当前字符 = "(")
        加入成员 (运算符栈, 当前字符)
    .判断 (当前字符 = ")")
        .判断循环首 (取数组成员数 (运算符栈) > 0 且 运算符栈 [取数组成员数 (运算符栈)] ≠ "(")
            处理运算符 (数字栈, 运算符栈 [取数组成员数 (运算符栈)])
            删除成员 (运算符栈, 取数组成员数 (运算符栈), 1)
        .判断循环尾
        删除成员 (运算符栈, 取数组成员数 (运算符栈), 1)  ' 弹出左括号
    .默认
        .判断循环首 (取数组成员数 (运算符栈) > 0 且 优先级 (当前字符) ≤ 优先级 (运算符栈 [取数组成员数 (运算符栈)]))
            处理运算符 (数字栈, 运算符栈 [取数组成员数 (运算符栈)])
            删除成员 (运算符栈, 取数组成员数 (运算符栈), 1)
        .判断循环尾
        加入成员 (运算符栈, 当前字符)
    .判断结束
.计次循环尾 ()

' 处理剩余运算符
.判断循环首 (取数组成员数 (运算符栈) > 0)
    处理运算符 (数字栈, 运算符栈 [取数组成员数 (运算符栈)])
    删除成员 (运算符栈, 取数组成员数 (运算符栈), 1)
.判断循环尾

返回 (数字栈 [1])

.子程序 处理运算符
.参数 数字栈, 小数型, 数组
.参数 运算符, 文本型
.局部变量 b, 小数型
.局部变量 a, 小数型

b = 数字栈 [取数组成员数 (数字栈)]
删除成员 (数字栈, 取数组成员数 (数字栈), 1)
a = 数字栈 [取数组成员数 (数字栈)]
删除成员 (数字栈, 取数组成员数 (数字栈), 1)

.判断开始 (运算符 = "+")
    加入成员 (数字栈, a + b)
.判断 (运算符 = "-")
    加入成员 (数字栈, a - b)
.判断 (运算符 = "*")
    加入成员 (数字栈, a × b)
.判断 (运算符 = "/")
    加入成员 (数字栈, a ÷ b)
.判断结束

.子程序 优先级, 整数型
.参数 op, 文本型
.判断开始 (op = "+" 或 op = "-")
    返回 (1)
.判断 (op = "*" 或 op = "/")
    返回 (2)
.默认
    返回 (0)
.判断结束

.子程序 是否数字, 逻辑型
.参数 s, 文本型
返回 (寻找文本 ("0123456789.", s, , 假) > 0)

方案二:递归下降解析法(更直观)

.版本 2

.子程序 解析表达式, 小数型
.参数 表达式, 文本型
.局部变量 解析位置, 整数型
解析位置 = 1
返回 (解析加减 (表达式, 解析位置))

' 加减法处理(最低优先级)
.子程序 解析加减, 小数型
.参数 表达式, 文本型
.参数 解析位置, 整数型, 参考
.局部变量 结果, 小数型
.局部变量 运算符, 文本型

结果 = 解析乘除 (表达式, 解析位置)
.判断循环首 (取文本中间 (表达式, 解析位置, 1) = "+" 或 取文本中间 (表达式, 解析位置, 1) = "-")
    运算符 = 取文本中间 (表达式, 解析位置, 1)
    解析位置 = 解析位置 + 1
    .判断开始 (运算符 = "+")
        结果 = 结果 + 解析乘除 (表达式, 解析位置)
    .判断 (运算符 = "-")
        结果 = 结果 - 解析乘除 (表达式, 解析位置)
    .判断结束
.判断循环尾
返回 (结果)

' 乘除法处理(中等优先级)
.子程序 解析乘除, 小数型
.参数 表达式, 文本型
.参数 解析位置, 整数型, 参考
.局部变量 结果, 小数型
.局部变量 运算符, 文本型

结果 = 解析基本单元 (表达式, 解析位置)
.判断循环首 (取文本中间 (表达式, 解析位置, 1) = "*" 或 取文本中间 (表达式, 解析位置, 1) = "/")
    运算符 = 取文本中间 (表达式, 解析位置, 1)
    解析位置 = 解析位置 + 1
    .判断开始 (运算符 = "*")
        结果 = 结果 × 解析基本单元 (表达式, 解析位置)
    .判断 (运算符 = "/")
        结果 = 结果 ÷ 解析基本单元 (表达式, 解析位置)
    .判断结束
.判断循环尾
返回 (结果)

' 处理数字和括号(最高优先级)
.子程序 解析基本单元, 小数型
.参数 表达式, 文本型
.参数 解析位置, 整数型, 参考
.局部变量 当前字符, 文本型
.局部变量 数字文本, 文本型

当前字符 = 取文本中间 (表达式, 解析位置, 1)
.判断开始 (当前字符 = "(")
    解析位置 = 解析位置 + 1
    结果 = 解析加减 (表达式, 解析位置)
    解析位置 = 解析位置 + 1  ' 跳过右括号
    返回 (结果)
.默认
    ' 提取连续数字
    .判断循环首 (是否数字 (当前字符) 或 当前字符 = ".")
        数字文本 = 数字文本 + 当前字符
        解析位置 = 解析位置 + 1
        当前字符 = 取文本中间 (表达式, 解析位置, 1)
    .判断循环尾
    返回 (到小数 (数字文本))
.判断结束

使用示例

.子程序 _按钮计算_被单击
编辑框结果.内容 = 到文本 (计算表达式 ("23+34*45-16/6"))
' 输出:23+34*45-16/6 = 1549.333...

关键点说明

  1. 逆波兰表达式法

    • 通过维护两个栈(数字栈和运算符栈)处理优先级
    • 时间复杂度O(n),适合复杂表达式
  2. 递归下降法

    • 通过多级子程序调用体现优先级
    • 代码更易读,适合教学理解
  3. 优先级顺序

    括号 → 乘除 → 加减
  4. 扩展建议

    • 增加错误处理(如除零检查)
    • 支持更多运算符(如^幂运算)
    • 添加表达式合法性验证

如果需要更完整的实现(包括错误处理、科学计算等),可以进一步扩展上述框架。

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 793400750,邮箱:wp@125.la
网站简介:精易论坛成立于2009年,是一个程序设计学习交流技术论坛,隶属于揭阳市揭东区精易科技有限公司所有。
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表