搜索
查看
编辑修改
首页
UNITY
NODEJS
PYTHON
AI
GIT
PHP
GO
CEF3
JAVA
HTML
CSS
搜索
酷酷是懒虫
这个屌丝很懒,什么也没留下!
关注作者
热门标签
jquery
HTML
CSS
PHP
ASP
PYTHON
GO
AI
C
C++
C#
PHOTOSHOP
UNITY
iOS
android
vue
xml
爬虫
SEO
LINUX
WINDOWS
JAVA
MFC
CEF3
CAD
NODEJS
GIT
Pyppeteer
article
热门文章
1
CAD模型下载
2
Rabbitmq 超时异常解决:PRECONDITION_FAILED - Timeout value used: 1800000 ms._rabbitmq timeout
3
命令行查看、设置和取消git或终端代理_查看当前git环境的代理情况
4
新型开发语言的试用感受-仓颉语言发布之际_仓颉 golang
5
微信小程序通过外链跳转网址打开小程序_小程序打开外链网址
6
FPGA基础知识6(FPGA时钟系统及多时钟系统处理)_行波时钟和使能时钟
7
teamviewer介绍及操作
8
语音识别之Kaldi:学习GMM-HMM_kaldi hmm
9
【RAG检索增强生成】RAG技术革新数据库:Vanna框架的高效SQL生成策略_rag+vanna
10
搞懂HDFS体系架构这一篇就够了_描述hdfs系统的体系结构
当前位置:
article
> 正文
浅谈中缀表达式的求值(带符号,等于,不等于,大于,小于,与,或,非,等等)_中缀表达式的比较符号大小需要自己写函数么
作者:酷酷是懒虫 | 2024-08-05 21:33:48
赞
踩
中缀表达式的比较符号大小需要自己写函数么
我们知道中缀表达式的求值,通常都是先转换为后缀表达式,在通过堆栈求出后缀表达式的值,对于这点,如果有不太清楚的请参见:
http://202.113.89.254/DataStructure/DS/web/zhanhuoduilie/zhanhuoduilie3.3.1.htm
(原理)
http://tech.ccw.com.cn/article/252014.htm
(实现)
对于ChinaDHF的这篇“
中缀表达式到逆波兰表达式的转换及求值
”写的很清楚,但他没有对符号处理,更没有对布尔运算进行判断。在这里,我们来看看怎么来完善他的这篇文章。
下面是ChinaDHF的代码的结构。
1.
对中缀表达式进行语法分析,或称合法性检查。
2.
将中缀表达式转换为逆波兰表达式。
3.
计算逆波兰表达得到我们想要的值。
我们照久,首先检查合法性。
为了方便后面的运算,我们先要做一个替换,把所有只能用字符串表示的运算符号,都替换成一个字符(char)的形式。
private
static
string
ReplaceExpString(
string
ExpString) {
//
如果改表达式直接采用的是
C
的风格
,
这段都可以注释掉
ExpString = ExpString.Replace(
"NOT"
,
"!"
);
ExpString = ExpString.Replace(
"OR"
,
"|"
);
ExpString = ExpString.Replace(
"AND"
,
"&"
);
//
把双字的运算符转化方便我们处理
ExpString = ExpString.Replace(
">="
, ((
char
)242).ToString());
//‘ò’
表示大于等于
ExpString = ExpString.Replace(
"<="
, ((
char
)243).ToString());
//‘ó’
表示小于等于
ExpString = ExpString.Replace(
"<>"
, ((
char
)247).ToString());
//‘÷’
表示不等于
ExpString =
Regex
.Replace ( ExpString,
@"/s+"
,
""
);
//
消除所有的空格
return
ExpString;
}
public
static
string
RexStringWord =
@"[#&|!+=<>.- *()/÷òó]"
;
public
static
string
RexStringNumber =
@"-?(/d+/.?/d*)"
;
public
static
string
RexStringLining =
@"[(]#[+/-*><=&|÷òó]+#[)]"
;
public
static
string
RexStringExp =
@”([#][+/-*><=&|÷òó])+[#] "
;
在合法性检查里面,我们把所有的数字(带负号,不带负号,带小数,不带小数)用正则表达式
RexStringNumber
都替换成#号
替换后表达式里面就只存在类似” #+#-# “,” #*(#-#) “,”(#<#)” 等等的了。在用正则表达式RexStringLining替换掉所有带括号的,最后用RexStringExp替换掉不带括号的,于是最后剩下的只会是#号
public
static
bool
IsRight (
string
expString ) {
string
ExpString = ReplaceExpString ( expString );
ExpString =
Regex
.Replace ( ExpString, RexStringNumber,
"#"
);
//
替换所有数字
if
(
Regex
.Matches ( ExpString, RexStringWord ).Count > 0 ) {
while
(
Regex
.IsMatch ( p, RexStringLining ) ) {
foreach
(
Match
match
in
Regex
.Matches (ExpString, RexStringLining ) ) {
string
strsingle = match.Value.Substring ( 1, match.Value.Length - 2 );
if
( !
Regex
.IsMatch ( strsingle, RexStringExp ) )
return
false
;
}
ExpString =
Regex
.Replace (ExpString, RexStringLining,
"#"
);
}
if
( p ==
"#"
)
return
true
;
if
( !
Regex
.IsMatch ( p, RexStringExp ) )
return
false
;
else return true
;
}
我们已经完成了合法性的检查,很简单,只是扩展我几个运算符。然后我们来看看转换后缀表达式的问题。转换后缀表达式有几个问题先要提一下,对于ChinaDHF的实现,他只处理了带2元运算符,也就是说,对于符号,非,他没有办法做到。首先我们要设计一个能够处理一元运算符的代码段。第二点,对于”-“他既是负号,又是减号,我们需要一个判断,什么时候是负号,什么时候是减号。
我们知道,一般来说,如果’-‘号出现在表达式最开始,而后面紧跟的是数字(-#),那么他一定是负号,另外如果’-‘号出现在左括号’(‘后面,而后面紧跟数字((-#)那么他也一定是负号,而对于其他位置的’-‘号,我们都把他做减号处理了。为了区别减号和负号,我把负号(1元运算符)都替换成另外一个符号,在这里我用’/’。
有了以上的思路,我们先来设计一个函数,把负号替换成’/’。
private
string
ReplaceMinusString(
string
expString) {
string
rstr = expString;
//
查找首字符为
-,
后面为数字的匹配
if
(
Regex
.IsMatch(rstr,
@"/A-(/d+/.?/d*)"
)){
rstr = rstr.Remove(0,1);
rstr =
"//"
+ rstr;
}
//
查找以(
-
开始后面为数字的匹配
while
(
Regex
.IsMatch(rstr,
@"/(-(/d+/.?/d*)"
)) {
foreach
(
Match
m
in
Regex
.Matches(rstr, RexMinusString)) {
int
index = m.Index + 1;
rstr = rstr.Remove(index, 1);
rstr = rstr.Insert(index,
"//"
);
}
}
return
rstr;
}
上面的函数完成了负号转换’/’的工作。
public
static
string
GetRnpExpValue (
string
exp ) {
string
strexp = ReplaceExpString(exp);
//
运算符化减
strexp = ReplaceMinusString(strexp);
//
负号替换
string
strRnpExp =
string
.Empty;
string
num =
string
.Empty;
Stack
<
char
> stack =
new
Stack
<
char
> ( );
string
strexp;
for
(
int
i = 0; i < strexp.Length; i++ ) {
if
(
char
.IsDigit ( strexp[i] ) || strexp[i] ==
'.'
)
num += strexp[i];
else
if
(
"//,!+-*/><=&|÷òó"
.IndexOf ( strexp[i] ) >= 0 ) {
if
( num.Length > 0 ) {
strRnpExp +=
"["
+ num +
"]"
;
num =
string
.Empty;
}
while
( stack.Count > 0 ) {
char
opInStack = (
char
)stack.Pop ( );
if
( opInStack ==
'('
|| Power ( opInStack ) < Power ( strexp[i] ) ) {
stack.Push ( opInStack );
break
;
}
else
strRnpExp += opInStack;
}
stack.Push ( strexp[i] );
}
else
if
( strexp[i] ==
'('
)
stack.Push ( strexp[i] );
if
( strexp[i] ==
')'
) {
if
( num.Length > 0 ) {
strRnpExp +=
"["
+ num +
"]"
;
num =
string
.Empty;
}
while
( stack.Count > 0 ) {
char
opInStack = (
char
)stack.Pop ( );
if
( opInStack ==
'('
)
break
;
else
strRnpExp += opInStack;
}
}
}
if
( num.Length > 0 ) {
strRnpExp +=
"["
+ num +
"]"
;
num =
string
.Empty;
}
while
( stack.Count > 0 )
strRnpExp += stack.Pop ( );
strRnpExp =
Regex
.Replace ( strRnpExp,
","
,
""
);
return
strRnpExp;
}
运算符的优先级比较:这里统一采用char类型做参数,所有前面出现运算符的单字符转化
private
static
int
Power (
char
o ) {
switch
( o ) {
case
'+'
:
case
'-'
:
return
1;
case
'*'
:
case
'/'
:
return
2;
case
'//'
:
case
'!'
:
return
3;
default
:
return
0;
}
}
以上把中缀表达式转换成后缀表达式的函数和ChinaDHF的一样,只是,前面多了2个函数的处理。如果有对算法不清楚,请点开篇的原理连接。
通过上面的处理,我们已经可以把一个合法的中缀表达式转换成了后缀表达式,那么我们怎么,那么我们怎么才能处理一元运算符呢?在后缀表达式求值的算法里面,在遇到+-*/时都会有2次退栈,提取出2个操作数,我在这里加了一个判断遇到一元运算符,就只提取一个操作数。
public
static
string
GetValueByRpn (
string
rpnExp ) {
Stack
<
string
> stack =
new
Stack
<
string
> ( );
char
[] expChar = rpnExp.ToCharArray ( );
string
digit =
string
.Empty;
string
result =
"0"
;
for
(
int
i = 0; i < expChar.Length; i++ ) {
char
c = expChar[i];
if
( c ==
'['
) {
digit =
string
.Empty;
}
else
if
( c ==
']'
) {
stack.Push ( digit );
}
else
if
(
char
.IsDigit ( c ) || c ==
'.'
) {
digit += c.ToString ( );
}
else
if
( c ==
'+'
|| c ==
'-'
|| c ==
'*'
|| c ==
'/'
|| c ==
'>'
|| c ==
'<'
|| c == (
char
)242 || c == (
char
)243 || c == (
char
)247 || c ==
'&'
|| c ==
'|'
|| c ==
'='
) {
string
v2 = stack.Pop ( );
string
v1 = stack.Pop ( );
result = Opert ( v1, v2, c );
stack.Push ( result );
}
//
一元运算符的单独判断
else
if
( c ==
'!'
|| c==
'//'
) {
string
v = stack.Pop ( );
result = Opert ( v,
""
, c );
stack.Push ( result );
}
}
return
result;
}
这里便是求值了,无论是求布尔值,还是四则运算,都是这个函数处理,中间没有加异常处理,如果遇到 布尔值 与 浮点数的运算会出错,对这段代码有兴趣的可以再改改。
private
static
string
Opert (
string
v1,
string
v2,
char
o ) {
switch
( o ) {
case
'+'
:
return
(
Convert
.ToDouble ( v1 ) +
Convert
.ToDouble ( v2 ) ).ToString ( );
case
'-'
:
return
(
Convert
.ToDouble ( v1 ) -
Convert
.ToDouble ( v2 ) ).ToString ( );
case
'*'
:
return
(
Convert
.ToDouble ( v1 ) *
Convert
.ToDouble ( v2 ) ).ToString ( );
case
'/'
:
return
(
Convert
.ToDouble ( v1 ) /
Convert
.ToDouble ( v2 ) ).ToString ( );
case
'>'
:
return
(
Convert
.ToDouble ( v1 ) >
Convert
.ToDouble ( v2 ) ).ToString ( );
case
'<'
:
return
(
Convert
.ToDouble ( v1 ) <
Convert
.ToDouble ( v2 ) ).ToString ( );
case
'='
:
return
( v1 == v2 ).ToString ( );
case
(
char
)242:
//>=
return
(
Convert
.ToDouble ( v1 ) >=
Convert
.ToDouble ( v2 ) ).ToString ( );
case
(
char
)243:
//<=
return
(
Convert
.ToDouble ( v1 ) <=
Convert
.ToDouble ( v2 ) ).ToString ( );
case
(
char
)247:
//<>
return
(
Convert
.ToDouble ( v1 ) !=
Convert
.ToDouble ( v2 ) ).ToString ( );
case
'&'
:
return
(
Convert
.ToBoolean ( v1 ) &&
Convert
.ToBoolean ( v2 ) ).ToString ( );
case
'|'
:
return
(
Convert
.ToBoolean ( v1 ) ||
Convert
.ToBoolean ( v2 ) ).ToString ( );
case
'!'
:
return
( !
Convert
.ToBoolean ( v1 ) ).ToString ( );
case
'//'
:
return
( -
Convert
.ToDouble ( v1 ) ).ToString ( );
default
:
return
null
;
}
}
上面这些,我做了一定的修改,简化了一下,本来布尔运算只会出现在IF语句里面,在这里我把IF的处理去掉了,IF处理很简单的,把条件语句单独提出来,判断,如果是true就执行THEN块,否则执行ELSE块
我觉得我正则表达式写的不好,算法上也有不好的地方,希望高手指教。
声明:
本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:
https://www.wpsshop.cn/w/酷酷是懒虫/article/detail/934372?site
推荐阅读
article
spring
cloud
搭建(
eureka
)_
spring
cloud
eureka
后端
项目
...
spring
cloud
是
spring
体系的简化版。
spring
cloud
是基于
spring
boot实现的管理
项目
的工...
赞
踩
article
常见
机器
学习
问题解答
(
一
)_
机器
学习
答疑表...
常见
机器
学习
问题解答
(
一
)本文是个人对
机器
学习
问题的总结,问题的来源是七月在线、牛客网等。划有横线的部分是本人掌握不够熟...
赞
踩
article
【
Oracle
】
Linux
x86
-64 安装
Oracle
23AI指南_
ora
cle startu...
在信息技术日新月异的今天,企业级数据库系统扮演着数据管理与业务支撑的核心角色。
Oracle
数据库,作为全球范围内广泛应用...
赞
踩
article
阿里
CTO程立:
阿里
巴巴
的
开源
历程、
理念
和
实践
_
开源
理念
...
云
和
开源
,已然共同成为数字世界的根,需要政府
和
企业、需要我们大家一起来共建
和
共享。_
开源
理念
开源
理念
...
赞
踩
article
软考学习 |
面向对象分析
方法
OOA
_
面向对象分析
与
设计
工具 软考...
从用户的角度看,他们并不想了解系统的内部结构和
设计
,他们所关心的是系统所能提供的服务,这是用例
方法
的基本思想。用例是一种...
赞
踩
article
科普文:万字细说微
服务
及其框架
Netflix
,
Spring
Cloud
,
Spring
Cloud
A...
微
服务
(Microservices)是一种软件架构风格,它将单一的应用程序拆分为多个小的
服务
,每个
服务
都是独立运行和部署...
赞
踩
article
Android
13
带来了
哪些
新功能?需要
哪些
适配工作?|
开发者
说·
DTalk
...
本文原作者: BennuC,原文发布于: BennuCTech前言目前 Google 已经发布了
Android
13
...
赞
踩
article
ELK
与
EFK
的介绍
和
对比_
elk
和
efk
...
ELK
与
EFK
的介绍
和
对比_
elk
和
efk
elk
和
efk
...
赞
踩
article
Linux
之
MobaXterm
:
MobaXterm
工具
的
简介
、
安装
、
使用方法(连接
Linux
服务器
以...
Linux
之
MobaXterm
:
MobaXterm
工具
的
简介
、
安装
、
使用方法(连接
Linux
服务器
以及常规命令操作教程...
赞
踩
article
Java
注释
(
Java
Doc
Comment
)与
注解
(
Annotation
)_
java
注释
和
注解
...
注解
(
Annotation
):又称为 标注,即
Java
标注,是 JDK5.0 引入的一种
注释
机制。
注释
(Note):...
赞
踩
article
身份证
OCR
接口
的
原理
和
使用场景_
身份证
拍照
识别
接口
...
通过运用这种先进
的
OCR
技术,不仅极大地提升了身份验证流程
的
精确度
和
效率,而且在各类业务场景下,都能够实现快速、准确
的
信...
赞
踩
article
贪心
算法
总结
_
贪心
算法
的概念
总结
...
本文
总结
了
贪心
算法
的小知识点,包括定义比较函数、重载运算符和pair的使用。通过四个例题详细解释了
贪心
算法
的应用,如背包...
赞
踩
article
course
ra——Image and Video
Processing
_
video
process...
最近一直在刷
course
ra上的Image and Video
Processing
(https://www.cours...
赞
踩
article
Integration
Services
服务
连接失败,拒绝
访问
以及
无法
检索
数据
报错问题...
第一个方法比较简单:把域账号添加admin组即可; 第二种方法: 添加域账号到分布式 COM 组 命令提示符下运行 d...
赞
踩
article
基于深度
学习
的高精度
西红柿
检测
识别
系统(
Python
+PyTorch+
Pyside6
+
YOLOv5
模...
近年来,机器
学习
和深度
学习
取得了较大的发展,深度
学习
方法在检测精度和速度方面与传统方法相比表现出更良好的性能。YOLOv...
赞
踩
article
Fiddler
无法
抓
包
怎么解决?这些配置
项
你需要
检查
。尤其是最后一
项
。_
fiddler
抓
不到
包
...
有时候,我们的启动是正常的,但是就是
抓
不到
包
,原因有很多。但多数情况都是因为配置不正确,接下来我们就看下有哪些导致fid...
赞
踩
article
李彦宏
在2024世界
人工智能
大会
上
的
发言
解读_ai
人工智能
大会
上
的
发言
稿...
李彦宏
在2024年世界
人工智能
大会
上
的
发言
,不仅深刻揭示了当前
人工智能
(AI)领域
的
关键转向,还明确指出了AI技术
的
核心...
赞
踩
article
运行中
动态
加载远程
vue
文件,
解析
template
、
script
、
style
并注册全局组件:...
(1).通过http请求获取组件数据,然后使用http-
vue
-loader插件
解析
script
(
解析
为各生命周期钩子函...
赞
踩
article
android13
(T)
SystemUI
运营商
显示
bug
修复
_
安卓
13systemui
结构...
android13
(T)
SystemUI
运营商
显示
bug
修复
_
安卓
13systemui
结构安卓13systemu...
赞
踩
article
windows
系统搭建
EasyDarwin
流媒体
服务器
_
easydarwin
官网...
windows
系统
EasyDarwin
流媒体
服务器
笔者未商用文章目录
windows
系统
EasyDarwin
流媒体
服务器
E...
赞
踩
相关标签
spring cloud
eureka
java
机器学习
oracle
linux
数据库
dubbo
apache
OOA
微服务
android
大数据
移动开发
区块链
elk
开发语言
Linux
MobaXterm
ssh
后端
ocr
日记