使用weight、opcode和infix_to_prefix三个函数实现中缀表达式到前缀表达式的转换。

算符优先级函数weight

首先定义函数weight,它返回一个算术运算符(可简称为算符)的优先级(优先权)。

;确定算符的优先权
(defun weight (operator) (cond ((equal operator 'dummy) -1) ;运算符号表的开始标记((equal operator '=) 0)  ;等于号((equal operator '+) 1)    ;加号((equal operator '-) 1) ;减号((equal operator '*) 2) ;乘号((equal operator '/) 2);除号((equal operator '\\) 2);求余运算符((equal operator '^) 3) ;指数运算符(t (print (list operator 'not 'an 'operator)) 'nop))
)

在有些LISP的实现中,反斜杠“/”表示对下一个字符做特殊处理,如阻止把空格解释为分隔符,所以在上述函数中用双反斜杠“\\”等价地表示单斜杠“\”。

上述函数中的伪运算符dummy用来标记算符表的开端。

算符到操作码的转换函数opcode

定义算符到操作码的转换函数opcode。

;计算与operator对应的lisp函数名.
(defun opcode (operator) (cond((equal operator 'dummy)(print 'hit-dummy) 'dummy)((equal operator '=) 'setq)((equal operator '+) 'plus)((equal operator '-) 'difference)((equal operator '*) 'times)((equal operator '/) 'quotient)((equal operator '\\ ) 'remainder)((equal operator '^) 'expt)(t (print (list operator 'not 'an 'operator)) 'nop))
)

中缀表达式转换为前缀表达式的函数infix_to_prefix

从一种形式到另一种形式的转换方法有多种,这里采用自左向右的线性扫描法。其中,尚未用来产生输出的操作数和运算符都保留在表内。infix_to_prefix函数使用operands和operators两张表分别保存操作数和运算符(操作符)。

;将算术表达式由中缀形式变为前缀形式
(defun infix_to_prefix (ae)(prog (operands operators) ;操作数表和运算符表(cond((atom ae) (return ae))) ;特殊情况,只有一个操作数(setq operators (list 'dummy)) ;虚拟终结符stuff ;寻找操作数(cond((null ae) 扫描操作数,以运算符结尾(return 'unexpected-end))) ;递归(setq operands ;操作数入栈(cons (cond ((atom (car ae)) (car ae)) (t (infix_to_prefix (car ae))))operands) ;设置operandsae (cdr ae) ;删除操作数,设置ae)scan ;扫描运算符(cond((and(null ae) (equal (car operators) 'dummy)) ;ae及运算符表为空(return (car operands)) ;回送结果,operands即为所需的前缀表达式))(cond;ae为空或运算符表的第一个算符的优先级高于ae的第一个算符的优先级((or (null ae)  (not (> (weight (car ae)) (weight (car operators)))))  ;嵌套次序.(setq operands ;设置operands(cons (list (opcode (car operators)) (cadr operands) (car operands))(cddr operands)) ;弹出两个操作数operators (cdr operators);弹出一个运算符)(go scan) ;继续寻找运算符。);否则(t (setq operators (cons (car ae) operators) ; 运算符入栈ae (cdr ae) ;从ae中删除算符)(go stuff))))
)

三个函数放在一起

为了便于使用和复制,将三个函数放在一起

;确定算符的优先权
(defun weight (operator) (cond ((equal operator 'dummy) -1) ;运算符号表的开始标记((equal operator '=) 0)  ;等于号((equal operator '+) 1)    ;加号((equal operator '-) 1) ;减号((equal operator '*) 2) ;乘号((equal operator '/) 2);除号((equal operator '\\) 2);求余运算符((equal operator '^) 3) ;指数运算符(t (print (list operator 'not 'an 'operator)) 'nop))
);计算与operator对应的lisp函数名.
(defun opcode (operator) (cond((equal operator 'dummy)(print 'hit-dummy) 'dummy)((equal operator '=) 'setq)((equal operator '+) 'plus)((equal operator '-) 'difference)((equal operator '*) 'times)((equal operator '/) 'quotient)((equal operator '\\ ) 'remainder)((equal operator '^) 'expt)(t (print (list operator 'not 'an 'operator)) 'nop))
);将算术表达式由中缀形式变为前缀形式
(defun infix_to_prefix (ae)(prog (operands operators) ;操作数表和运算符表(cond((atom ae) (return ae))) ;特殊情况,只有一个操作数(setq operators (list 'dummy)) ;虚拟终结符stuff ;寻找操作数(cond((null ae) 扫描操作数,以运算符结尾(return 'unexpected-end))) ;递归(setq operands ;操作数入栈(cons (cond ((atom (car ae)) (car ae)) (t (infix_to_prefix (car ae))))operands) ;设置operandsae (cdr ae) ;删除操作数,设置ae)scan ;扫描运算符(cond((and(null ae) (equal (car operators) 'dummy)) ;ae及运算符表为空(return (car operands)) ;回送结果,operands即为所需的前缀表达式))(cond;ae为空或运算符表的第一个算符的优先级高于ae的第一个算符的优先级((or (null ae)  (not (> (weight (car ae)) (weight (car operators)))))  ;嵌套次序.(setq operands ;设置operands(cons (list (opcode (car operators)) (cadr operands) (car operands))(cddr operands)) ;弹出两个操作数operators (cdr operators);弹出一个运算符)(go scan) ;继续寻找运算符。);否则(t (setq operators (cons (car ae) operators) ; 运算符入栈ae (cdr ae) ;从ae中删除算符)(go stuff))))
)

在portacle中添加定义,如下图所示:

程序的运行

依次输入命令

(infix_to_prefix '(A + B * C) )

(infix_to_prefix '(total = principal * ( 1.0 + interest ) ^ years ) )

运行结果如下:

中缀表达式转换为前缀表达式(lisp实现)相关推荐

  1. 中缀表达式转换为前缀及后缀表达式并求值【摘】

    它们都是对表达式的记法,因此也被称为前缀记法.中缀记法和后缀记法.它们之间的区别在于运算符相对与操作数的位置不同:前缀表达式的运算符位于与其相关的操作数之前:中缀和后缀同理. 举例: (3 + 4) ...

  2. java中缀表达式转后缀表达式_数据结构Java实现06----中缀表达式转换为后缀表达式...

    本文主要内容: 表达式的三种形式 中缀表达式与后缀表达式转换算法 一.表达式的三种形式: 中缀表达式:运算符放在两个运算对象中间,如:(2+1)*3.我们从小做数学题时,一直使用的就是中缀表达式. 后 ...

  3. 数据结构 - 拓展突破(C++实现中缀表达式转前缀表达式,中缀表达式转后缀表达式,前缀表达式求值,中缀表达式求值)

    文章目录 1. C++中缀表达式转后缀表达式 2. C++中缀表达式转前缀表达式 3. C++后缀表达式求值 4. C++前缀表达式求值 1. C++中缀表达式转后缀表达式 输入中缀表达式样例: 2+ ...

  4. 逆波兰表达式中缀表达式转换为后缀表达式

    中缀表达式转换为后缀表达式 思路分析 代码实现 package com.atguigu.stack;import javax.swing.plaf.nimbus.State; import java. ...

  5. 中缀表达式到前缀表达式和后缀表达式

    1.算法思路 转化为后缀:从左到右遍历中缀表达式,遇到操作数,输出,遇到操作符,当前操作符的优先级大于栈顶操作符优先级,进栈,否则,弹出栈顶优先级大于等于当前操作符的操作符,当前操作符进栈.     ...

  6. 表达式计算:后缀表达式求解 以及 中缀表达式转换为后缀表达式

    后缀表达式 后缀表达式格式: 不包含括号,运算符放在两个运算对象的后面. 后缀表达式运算规则: (从左向右) 所有计算均按运算符出现的顺序(不再考虑乘除优先于加减这种运算符的优先规则),严格从左向右进 ...

  7. 利用stack结构,将中缀表达式转换为后缀表达式并求值的算法实现

    #!/usr/bin/env python # -*- coding: utf-8 -*-# learn <<Problem Solving with Algorithms and Dat ...

  8. swust oj 1042: 中缀表达式转换为后缀表达式

    题目描述 中缀表达式是一个通用的算术或逻辑公式表示方法,操作符是以中缀形式处于操作数的中间(例:3 + 4),中缀表达式是人们常用的算术表示方法.后缀表达式不包含括号,运算符放在两个运算对象的后面,所 ...

  9. 【数据结构】中缀表达式转前缀表达式求值

    中缀表达式转前缀表达式求值 首先将中缀表达式转换成前缀表达式 前缀表达式中,操作符在前 例如:1+2*(5-3)+4 后缀表达式:++1*2-534 一.转换思路 转换思路为将输入的中缀表达式字符串从 ...

最新文章

  1. 浏览器加载、解析、渲染的过程
  2. 数值计算领域的“圣经”,图灵出了新版本 | 11月书讯
  3. 固件分析工具Binwalk
  4. 小米Android N新功能,快升级牛轧糖 小米Android N支持汇总
  5. Online Learning算法理论与实践
  6. 这些 JS 中强大的操作符,总有几个你没听说过
  7. 天津农学院计算机考研专业,2021年天津农学院计算机与信息工程学院考研专业目录_研究生考试范围 - 学途吧...
  8. [Python] 更改矩阵形状:reshape(m,n)、view(m,n)和view_as(tensor)
  9. 线性表--算法设计题2.25
  10. enjoyable parameter in pgbouncer
  11. 南阳oj-----D的小L(algorithm全排列用法)
  12. 前端js下载mp4、flv格式的文件流
  13. Windows源码编译运行pgAdmin4
  14. SLAM建图精度评估 by EVO
  15. android 远程组件,安卓手机远程协助控制神器 Teamviewer
  16. 2020面试题合集之吊打面试官系列(一),Android中为什么需要Handler
  17. java计算机毕业设计智友少儿编程学习平台源码+mysql数据库+系统+部署+lw文档
  18. HBulider 连接手机,在手机端展示
  19. 军用计算机ip等级是什么,加固计算机的IP防护等级是什么?
  20. Thread.currentThread().interrupt()和Thread.interrupted()和Thread.currentThread().isInterrupted()

热门文章

  1. 前端 summernote富文本编辑器 点击文章预览的功能实现
  2. lotus 错误扇区 恢复
  3. 给大家推荐一款强大的游戏框架——ET
  4. python代码库-哪些 Python 库让你相见恨晚?
  5. 什么是次世代游戏?科普次世代游戏角色制作过程
  6. 数据库模式——三级模式两级映像
  7. HTTP长连接、短连接究竟是什么?
  8. ACM基础之排序算法
  9. 一台计算机的配置,怎么配置一台台式计算机?答案按需求来配
  10. 综合应用能力二(非计算机类),2017年事业单位公开招聘——辽宁省朝阳国税系统...