## 一、设计要求
### 1.问题描述
一个逻辑表达式如果对于其变元的任一种取值都为真,则称为重言式;反之,如果对于其变元的任一种取值都为假,则称为矛盾式;然而,更多的情况下,既非重言式,也非矛盾式。试写一程序,通过真值表判断一个逻辑表达式属于哪一类。
### 2.需求分析
1. 逻辑表达式从终端输入,长度不超过一行。逻辑运算符包括“|”,“&”和“~”,分别表示或、与和非,运算优先程度递增,但可以由括号改变,即括号内的运算优先。逻辑变元为大写字母,表达式中任何地方都可以含有多个空格符。
2. 若是重言式或矛盾式,显示“True forever”或“False forever”,否则显示“Satisfactible”。若用户对表达式中变元取一组值,程序就求出并显示逻辑表达式的值。在判断的结果下方同时列出真值表。
3. 对于一个简单的表达式求值运算规则如下:
a) 从左至右依次计算。
b) 先取反, 然后相与,后相或。
c) 先括号内,后括号外。
## 二、准备知识
我们可以将逻辑表达式的计算类比算术表达式的计算,通常借助堆栈来实现按运算符的优先级完成表达式的求值计算:一个是存放运算符的栈,另一个是存放变量或中间结果的栈。回顾一下中缀表达式转后缀表达式并计算的计算过程:
1、任何中缀表达式都由运算数,运算符,括号这三部分组成,其中括号的优先级最高,其次是乘除,最后是加减。
2、从左到右遍历中缀表达式,若遇到运算数时,则直接将压入数据栈。
3、若为运算符,以下几种情况直接将符号入栈:
栈为空;栈顶为左括号;该符号优先级比栈顶符号的优先级高。
4、若遇到右括号,表达括号内的中缀表达式已经扫描完毕,则执行计算步骤:从运算符栈弹出一个运算符号,从数据栈弹出两个数字进行一次运算并将结果入栈。重复此步骤直至遇到左括号,将左括号出栈。
5、如果该运算符的优先级小于或等于栈顶运算符的优先级时,重复4中的计算步骤,直到运算符栈空或栈顶为左括号。
6、最后扫描到中缀表达式的末尾,继续执行之前的计算步骤直到运算符栈空。
## 三、概要设计
![](https://www.writebug.com/myres/static/uploads/2021/10/26/00ead108555d4b2777ffb5c356f50f81.writebug)
算法整体流程
如图figure1所示,我们算法的整体思路非常清晰;对于给定的逻辑表达式,我们先解析得到所有的变元,然后我们依次给变元赋值0和1;对于由n个变元组成的逻辑表达式,那么最终将得到2^n个不含任何变元的逻辑表达式;最后我们通过将这2^n个表达式一一计算得到真值表;通过真值表判定该逻辑表达式是否是重言式或者矛盾式;对于有追加的赋值,一种方法是直接查刚才计算得出的真值表,另一种途径是提前将追加的变元赋值,然后再解析、算真值表;为了代码的复用,我们使用了第二种方法。
## 四、详细设计
代码的整体结构如下所示,我们采用了面向对象的编程思想;定义LogicExpression类完成所有功能; 定义字典代表所有字符符号的优先级;定义__init__方法完成对象的初始化;定义parse方法完成变元的解析;定义generate方法完成真值表(变元部分)的生成;operate方法、process方法、solve方法均为具体计算表达式的方法;定义main方法整合所有计算过程;定义conclusion方法完成最后表达式的判定;
```python
classLogicExpression:
priority = {
'(': 4,
'~': 3,
'&': 2,
'|': 1
}#
定义符号的优先级
def __init__(self, expression)
def parse(self):
def generate(self):
def operate(self, symbol, arg): #不定长参数
def process(self, data, opt):
def solve(self, exp):
def main(self):
@property
def conclusion(self):
```
### 1.输入表达式
初始化部分非常简单,只是获取用户输入的表达式并删去多余的空格
```python
def __init__(self,expression):
self.expression = expression.replace(' ','') #初始表达式、并删掉多余空格
```
### 2.解析变量
而解析表达式,获得变元这部分我们使用了python的正则表达式模块,我们规定变元的命名标准同代码中变元的命名标准相同;此外用set去除出现过不止一次的变元;最后按照变元的原始顺序排序。
```python
def parse(self):
pattern = re.compile(r '[a-zA-Z_]w')# 变量规则与代码中变量定义规则相同 字母、 数字、 下划线组合,
数字不能开头
vars1 = pattern.findall(self.expression)# 解析成变量列表(待去重)
vars2 = list(set(vars1))# 去重
vars2.sort(key = vars1.index)# 保持原来顺序不变
return vars2
```
### 3.遍历赋值
在编历赋值这块,我们使用了python的自建模块itertools.product函数快速生成组合元祖;然后直接将变元用0和1替换;在返回时,使用yield函数依次返回一种组合,减少内存开销;
```python
def generate(self):
l = [0, 1]
for
case inproduct([l] len(self.vars)):
#case为生成的组合元祖: 两个变量的情况下为(0, 0)(0, 1)(1, 0)(1, 1)
exp = self.expression
for i in range(len(self.vars)):
exp = exp.replace(self.vars[i], str(
case [i]))
yield exp# 使用python的迭代器依次返回代入值后的表达式
```
### 4.计算表达式的值
计算表达式的值(不带变元)是整个代码的核心;我们的思想是维护两个栈分别存放逻辑符号和逻辑值。遍历表达式中的所有字符,按照优先级规则和栈内情况具体决定压栈和出栈,具体标准请参照下图:
1. 对于逻辑值直接进逻辑栈;
2. 遇到 ) 则进行出栈计算直到逻辑符号栈顶为 ( ,并将 ( 出栈
3. 逻辑符号直接进栈的三种情况:符号栈为空、符号栈顶为(、符号栈顶符号的优先级小于该符号,在这三种情况下直接进栈
4. 其余情况下,根据栈顶符号类型,取出相应数量的逻辑值进行运算,然后压入逻辑值栈;如此往复,直至当前符号满足进栈规则3
5. 最后如果符号栈尚有元素,则继续运算
6. 逻辑值栈最后存在的值即为表达式的解
![](https://www.writebug.com/myres/static/uploads/2021/10/26/0d5bb0d7f927cef704f4f6d809e642ba.writebug)
Figure2 出入栈标准
对应代码如下:
```python
def solve(self, exp):
data = []# 逻辑栈
opt = []# 操作符号栈
for i in exp:
if i.isdigit(): #如果是数字则直接进逻辑栈
data.append(int(i) == 1)
elif i == ')': #如果是) 则依次则开始从data栈和opt计算直到遇到(为止
while opt[-1] != '(':
self.process(data, opt)
opt.pop()# 出栈(
elifnot opt or opt[-1] == '('
or self.priority[i] > self.priority[opt[-1]]: #
符号进栈的三种情况: 符号栈为空、 符号栈头为(, ps: (进栈后优先值降为最低、 拿到的比栈中的优先级大
opt.append(i)
else :#优先级低需要先计算达到进栈条件后方能进栈
while opt and opt[-1] != '('
and self.priority[i] < self.priority[opt[-1]]:
self.process(data, opt)
opt.append(i)
while opt:
self.process(data, opt)
return data.pop()
```
其中还定义了两个子函数process和operate; processs 函数的作用是模拟取出符号栈和逻辑�
没有合适的资源?快使用搜索试试~ 我知道了~
基于python实现通过真值表判断一个逻辑表达式.zip
共126个文件
gif:75个
js:28个
css:5个
5星 · 超过95%的资源 需积分: 37 5 下载量 154 浏览量
2023-02-08
18:03:46
上传
评论
收藏 1.02MB ZIP 举报
温馨提示
1.问题描述 一个逻辑表达式如果对于其变元的任一种取值都为真,则称为重言式;反之,如果对于其变元的任一种取值都为假,则称为矛盾式;然而,更多的情况下,既非重言式,也非矛盾式。试写一程序,通过真值表判断一个逻辑表达式属于哪一类。 2.需求分析 1. 逻辑表达式从终端输入,长度不超过一行。逻辑运算符包括“|”,“&”和“~”,分别表示或、与和非,运算优先程度递增,但可以由括号改变,即括号内的运算优先。逻辑变元为大写字母,表达式中任何地方都可以含有多个空格符。 2. 若是重言式或矛盾式,显示“True forever”或“False forever”,否则显示“Satisfactible”。若用户对表达式中变元取一组值,程序就求出并显示逻辑表达式的值。在判断的结果下方同时列出真值表。 3. 对于一个简单的表达式求值运算规则如下: a) 从左至右依次计算。 b) 先取反, 然后相与,后相或。 c) 先括号内,后括号外。
资源推荐
资源详情
资源评论
收起资源包目录
基于python实现通过真值表判断一个逻辑表达式.zip (126个子文件)
layui.css 71KB
layer.css 14KB
layui.mobile.css 10KB
laydate.css 7KB
code.css 1KB
算法报告.docx 300KB
iconfont.eot 41KB
59.gif 10KB
22.gif 10KB
24.gif 8KB
13.gif 7KB
16.gif 7KB
39.gif 6KB
64.gif 6KB
63.gif 6KB
50.gif 6KB
loading-0.gif 6KB
4.gif 6KB
1.gif 5KB
42.gif 5KB
71.gif 5KB
21.gif 5KB
20.gif 5KB
29.gif 5KB
70.gif 4KB
5.gif 4KB
17.gif 4KB
27.gif 4KB
9.gif 4KB
44.gif 4KB
11.gif 4KB
8.gif 4KB
3.gif 4KB
23.gif 4KB
34.gif 4KB
41.gif 4KB
38.gif 4KB
65.gif 3KB
32.gif 3KB
45.gif 3KB
7.gif 3KB
12.gif 3KB
26.gif 3KB
60.gif 3KB
2.gif 3KB
40.gif 3KB
25.gif 3KB
19.gif 3KB
66.gif 3KB
18.gif 3KB
46.gif 3KB
10.gif 3KB
28.gif 3KB
51.gif 3KB
57.gif 3KB
67.gif 3KB
0.gif 3KB
48.gif 3KB
43.gif 3KB
30.gif 2KB
61.gif 2KB
33.gif 2KB
69.gif 2KB
14.gif 2KB
47.gif 2KB
36.gif 2KB
49.gif 2KB
58.gif 2KB
6.gif 2KB
54.gif 2KB
53.gif 2KB
56.gif 2KB
62.gif 2KB
31.gif 2KB
55.gif 2KB
35.gif 2KB
15.gif 2KB
loading-2.gif 2KB
37.gif 1KB
68.gif 1KB
52.gif 777B
loading-1.gif 701B
index.html 3KB
layui.all.js 271KB
jquery.js 95KB
jquery.min.js 84KB
slick.min.js 42KB
bootstrap.min.js 36KB
table.js 31KB
mobile.js 31KB
laydate.js 27KB
layer.js 22KB
nouislider.min.js 21KB
layedit.js 12KB
colorpicker.js 11KB
tree.js 11KB
form.js 9KB
upload.js 7KB
element.js 7KB
slider.js 7KB
共 126 条
- 1
- 2
计算机毕设论文
- 粉丝: 9988
- 资源: 398
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
- 1
- 2
前往页