您的位置:首页 > 编程语言 > Java开发

1049 命题逻辑(java)— 离散数学应用(详解)

2018-02-22 23:37 351 查看
问题描述
  在命题逻辑中,每个变元可以取值为真或假,通过逻辑运算符连接得到逻辑表达式,逻辑表达式的值由逻辑变元的值计算得出。
  以下是常用的逻辑运算符。
  ~:表示否定,~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);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: