在命题逻辑中,每个变元可以取值为真或假,通过逻辑运算符连接得到逻辑表达式,逻辑表达式的值由逻辑变元的值计算得出。
以下是常用的逻辑运算符。
~:表示否定,~P为真当且仅当P为假。
>:蕴含,P>Q为真当且仅当Q为真或者P为假。
^:合取,P^Q为真当且仅当P和Q同为真。
v:析取,PvQ为真当且仅当P和Q中至少一个为真。
重言式是指无论变元如何取值其结果都为真的表达式,矛盾式是指无论变元如何取值其结果都为假的表达式。
在表式逻辑表达式的时候,可以使用辅助符号来方便描述,一个辅助符号可能是另外两个变元或辅助符号运算的结果。
为了使用辅助符号来表示否定运算,我们设置一个虚拟的辅助符号X0,使用X0和另一个变元运算P运算后即得到~P的结果。
给定一系列辅助符号的定义,问最后一个辅助符号是重言式、矛盾式还是其他表达式。
输入数据第一行是两个整数n、m(1<=n<=4,1<=m<=10)。表示在输入中出现的变元不超过n个、辅助符号为m个,变元依次为P0, P1, ..., Pn-1,辅助符号依次为A0, A1, ..., Am-1。
从第二行开始,依次描述A0,A1,…Am-1,并严格依照以下格式:
Ai L ? R
其中Ai依次为A0, A1, ..., Am-1。?可以为“~”、“>”、“^”、“v”。L和R可以是变元或者之前出现过的辅助符号。
若?为“~”,则L必定为X0。
输出格式
若Am-1为重言式,输出1。
若Am-1为矛盾式,输出-1。
若两者都不是,输出0。
样例输入
1 2
A0 X0 ~ P0
A1 A0 v P0
样例输出
1
题目分析:
离散数学中关于命题逻辑的应用
算法分析:
将左项 left[ ] 和右项 right[ ] 分开,根据题意写逻辑判断。
为了具体化地分析,先用样例数据做说明。输入数据第一行是两个整数1、2。表示在输入中出现的变元不超过1个,此处为P0;辅助符号为2个,此处为A0,A1。
首先我们引入二维数组value[ ][ ] 记录真假,result[ ] [ ]记录结果。赋初值value[0][0]为假(0),value[1][0]为真(1)。
在输入第一行后,根据题意X0为虚拟的辅助符号,那么只记录右项P0,并将value[0][0]的值(0)赋给right[0],value[1][0]的值(1)赋给right[1],这里逻辑运算符为否定运算符,由题意,若右项right[0]为真,则result[0][0]为假,同理若right[1]为真,则result[1][0]为假。此处right[0]=0,result[0][0]=1;right[1]=1,result[1][0]=0。
接着输入第二行,记录左项A0,因为A0就是根据第一行的输入做出的逻辑判断,所以将result[0][0]的值(1)赋给left[0],result[1][0]的值(0)赋给left[1]。再按照输入第一行时记录右项的方式记录此处P0(实际上是一样的记录方式,不改变right[],即right[0]仍为0,right[1]仍为1,因为这里的变元仍然是P0),这里逻辑运算符为析取运算符,由题意,左项和右项中至少有一个为真,则为真,即A1,也就是result[0][1]=1,result[1][1]=1。
上述我们已经记录了A1的可能结果,也就是最后一个辅助符号的可能结果,根据题意需要判断A1是重言式还是矛盾式,既然我们已经得到result[0][1]=1,result[1][1]=1,也就是说无论变元怎么取值,结果总为真,那么A1显然是重言式,输出1。
下面我们往一般化去考虑,如果有多个变元呢,这也就是将value引为二维数组,而不是一维数组的原因。根据上述已知,当只有一个变元P0时,我们赋初值value[0][0]为假(0),value[1][0]为真(1),因为一个变元的真假情况只可能有这两种,也就是2的1次方,当有n变元时,情况数自然扩大为2的n次方。
同时这里涉及到一个排列组合问题,每一个变元的值可以取真(1)或假(0),n个变元组合可能有哪些情况。比如说有3个变元,就有000,100,010,110,001,101,011,111八种情况,详细来说也就是我们将value赋值为了:
value[0][0]=0,value[0][1]=0,value[0][2]=0
value[1][0]=1,value[1][1]=0,value[1][2]=0
value[2][0]=0,value[2][1]=1,value[2][2]=0
value[3][0]=1,value[3][1]=1,value[3][2]=0
value[4][0]=0,value[4][1]=0,value[4][2]=1
value[5][0]=1,value[5][1]=0,value[5][2]=1
value[6][0]=0,value[6][1]=1,value[6][2]=1
value[7][0]=1,value[7][1]=1,value[7][2]=1
接下来根据一开始我们对样例数据的分析过程,可以归纳得知,我们对这每一个组合按照先后顺序求出了A0,A1...An的可能结果,同样以n=3为例,也就是得到了A7的可能结果,如果每一种可能结果都为真(1),也就是重言式了,输出1;同理,如果每一种可能结果都为假(0),也就是矛盾式,输出-1;否则输出0。
这就是这道题的整个思路。最后在代码中对细节进行完善和优化即可。
算法设计:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
int probability = 1; //可能的情况数
for (int i = 0; i < n; i++) {
probability *= 2;
}
int result[][] = new int[probability][m+1]; //记录结果
int value[][] = new int[probability][n+1]; //记录真假
for (int i = 0; i < probability; i++) {
int k = i;
for (int j = 0; j < n; j++) {
value[i][j] = k % 2;
k /= 2;
}
}
int []right = new int[probability]; //记录右项
int []left = new int[probability]; //记录左项
String temp = sc.nextLine(); //读取多余的换行符
for (int i = 0; i < m; i++) {
String data = sc.nextLine();
for (int j = 0; j < probability; j++) {
if (data.charAt(3) == 'P')
left[j] = value[j][(int) data.charAt(4) - '0'];
else if (data.charAt(3) == 'A')
left[j] = result[j][(int) data.charAt(4) - '0'];
if (data.charAt(8) == 'P')
right[j] = value[j][(int) data.charAt(9) - '0'];
else if (data.charAt(8) == 'A')
right[j] = result[j][(int) data.charAt(9) - '0'];
switch (data.charAt(6)) { //逻辑运算符判断
case '~':
if (right[j] == 1)
result[j][i] = 0;
else
result[j][i] = 1;
break;
case '>':
if (right[j] == 1 || left[j] == 0)
result[j][i] = 1;
else
result[j][i] = 0;
break;
case '^':
if (right[j] == 1 && left[j] == 1)
result[j][i] = 1;
else
result[j][i] = 0;
break;
case 'v':
if (right[j] == 1 || left[j] == 1)
result[j][i] = 1;
else
result[j][i] = 0;
break;
default:
break;
}
}
}
int sum = 0;
for (int i = 0; i < probability; i++) {
sum += result[i][m - 1];
}
if (sum == 0) {
System.out.println(-1);
} else if (sum == probability) {
System.out.println(1);
} else {
System.out.println(0);
}
}
}
该博客讨论了如何在离散数学中应用命题逻辑,通过分析和算法设计,解释了如何判断给定的辅助符号表达式是重言式、矛盾式还是其他。通过样例数据,展示了如何处理逻辑判断,尤其是当涉及多个变量时的情况,最终得出结论并优化代码实现。
— 离散数学应用(详解)&spm=1001.2101.3001.5002&articleId=79350267&d=1&t=3&u=45e7ff0b7d0941c286f705d480711d3d)
568

被折叠的 条评论
为什么被折叠?



