利用真值表法求取主析取范式以及主合取范式
内容:
编程实现用真值表法求取含n个变元的合式公式所对应的主析取范式和主合取范式。
要求:
能够列出合式公式的真值表并给出相应主析取和主合取范式。
实验代码:
import jdk.swing.interop.SwingInterOpUtils;
import java.util.*;
import java.util.regex.Pattern;
public class Truetable {
private static HashMap<Character,Boolean> map = new HashMap<>();//用键值对存放命题的真假
private static List<Character> Alpha = new ArrayList<>();//命题字符的列表
private static int alphaSize = 0;
private static String infixSentence; //中缀表达式
private static char[] suffixSentence = new char[100];//后缀表达式
private static Boolean res;
private static List<Boolean[]> trueList = new ArrayList<>(); //真值序列
private static List<Boolean[]> falseList = new ArrayList<>();//假值序列
public static void main(String[] args) {
init();
Scanner scanner = new Scanner(System.in);
String inputAlpha;
System.out.println("请输入命题个数");
alphaSize = scanner.nextInt();
System.out.println("请输入合式公式(英文输入):析取:“|” 合取:“&” 非:“!” 单条件运算符:“->” 双条件运算:“<>”");
do {
scanner.nextLine();
inputAlpha = scanner.nextLine();
scanner.close();
} while (!Pattern.matches("^[A-Za-z->, inputAlpha));//判断是是否符合输入要求
StringBuilder sb = new StringBuilder(inputAlpha);
infixSentence = standardExpression(inputAlpha);
infixToSuffix(infixSentence);//调用中缀转换为后缀函数
for (int i = 0; i < Alpha.size(); i++) {
System.out.print(Alpha.get(i) + "\t");
}
System.out.println(inputAlpha);
printTrueTable(0);//调用打印真值表函数
printAns();//打印结果
}
private static void printAns() {
disjunctiveForm();//主析取范式
conjunctiveForm();//主合取范式
}
private static void conjunctiveForm() {
int i = 0, j = 0;
int k;
String ans = "";
for (Boolean[] falsearray : falseList) {
StringBuilder stringBuilder = new StringBuilder(ans);
stringBuilder.append("(");
for (i = 0; i < Alpha.size(); i++) {
if (i == Alpha.size() - 1) {
if (falsearray[i]) {
stringBuilder.append("¬").append(Alpha.get(i));
} else {
stringBuilder.append(Alpha.get(i));
}
} else {
if (falsearray[i]) {
stringBuilder.append("¬").append(Alpha.get(i)).append("∨");
} else {
stringBuilder.append(Alpha.get(i)).append("∨");
}
}
}
stringBuilder.append(")").append("∧");
ans = stringBuilder.toString();
}
try {
ans = ans.substring(0, ans.length() - 1);
System.out.print("主合取范式为: ");
System.out.println(ans);
}catch (StringIndexOutOfBoundsException e){
System.out.println("永真式 T");
}
}
private static void disjunctiveForm() {
int i = 0, j = 0;
int k;
String ans = "";
for (Boolean[] truearray : trueList) {
StringBuilder stringBuilder = new StringBuilder(ans);
stringBuilder.append("(");
for (i = 0; i < Alpha.size(); i++) {
if (i == Alpha.size() - 1) {
if (truearray[i]) {
stringBuilder.append(Alpha.get(i));
} else {
stringBuilder.append("¬").append(Alpha.get(i));
}
} else {
if (truearray[i]) {
stringBuilder.append(Alpha.get(i)).append("∧");
} else {
stringBuilder.append("¬").append(Alpha.get(i)).append("∧");
}
}
}
stringBuilder.append(")").append("∨");
ans = stringBuilder.toString();
}
try {
ans = ans.substring(0, ans.length() - 1);
System.out.print("主析取范式为: ");
System.out.println(ans);
}catch (StringIndexOutOfBoundsException e){
System.out.println("永假式 F");
}
}
//打印真值表
private static void printTrueTable(int cur) {
Boolean[] bs = new Boolean[alphaSize];
if (cur == Alpha.size()) {
checkCal(); //语句的真假值
for (Character character : Alpha) {
if (map.get(character)) {
System.out.print("T" + "\t");
} else {
System.out.print("F" + "\t");
}
}
if (res) {//用来求主析取范式
System.out.println("T");
for (int i = 0; i < Alpha.size(); i++) {
bs[i] = map.get(Alpha.get(i));
}
trueList.add(bs);
} else {//用来求主合取范式
System.out.println("F");
for (int i = 0; i < Alpha.size(); i++) {
bs[i] = map.get(Alpha.get(i));
}
falseList.add(bs);
}
return;
}
/* 递归打印真值表*/
map.put(Alpha.get(cur), true);
printTrueTable(cur + 1);
map.put(Alpha.get(cur), false);
printTrueTable(cur + 1);
}
//利用堆栈来计算表达式的真假值
private static void checkCal() {
Stack<Boolean> s = new Stack<>();
char ch;
int j = 0;
Boolean b1, b2;
ch = suffixSentence[j];
while (!(ch == '#') && (ch != 0)) {
ch = suffixSentence[j++];
if (Character.isAlphabetic(ch)) {
s.push(map.get(ch));
} else {
if (ch == '!') { //取反运算
b1 = s.lastElement();
s.pop();
s.push(!b1);
} else if (ch == '&') { //合取运算
b1 = s.lastElement();
s.pop();
b2 = s.lastElement();
s.pop();
s.push(b1 && b2); //析取运算
} else if (ch == '|') {
b1 = s.lastElement();
s.pop();
b2 = s.lastElement();
s.pop();
s.push(b1 || b2);
} else if (ch == '>') { //单条件运算
b2 = s.lastElement();
s.pop();
b1 = s.lastElement();
s.pop();
s.push(!b1 || b2);
} else if (ch == '<') { //双条件运算
b1 = s.lastElement();
s.pop();
b2 = s.lastElement();
s.pop();
s.push((b1 && b2) || (!b1 && !b2));
}
}
}
res = s.lastElement();//取出栈顶的元素
}
/**
* 中缀表达式转换为后缀表达式
* @param infixSentence 中缀表达式
*/
private static void infixToSuffix(String infixSentence) {
int i = 0, j = 0;
Stack<Character> s = new Stack<>();
s.push('#');
char ch, operator;
char[] alphas = infixSentence.toCharArray();
ch = alphas[j];
while (ch != '#') {
if (Character.isAlphabetic(ch)) {
suffixSentence[i++] = ch;
if (!Alpha.contains(ch)) {
Alpha.add(ch);
}
} else if (ch == ')') {
for (operator = s.lastElement(), s.pop();
operator != '(';
operator = s.lastElement(), s.pop()) {
suffixSentence[i++] = operator;
}
} else {
for (operator = s.lastElement(), s.pop();
icp(ch) <= isp(operator);
operator = s.lastElement(), s.pop()) {
suffixSentence[i++] = operator;
}
s.push(operator);
s.push(ch);
}
ch = alphas[++j];
}
while (!s.isEmpty()) {
operator = s.lastElement();
s.pop();
if (operator != '#') {
suffixSentence[i++] = operator;
}
}
}
//栈内运算优先级
private static int isp(char operator) {
if (operator == '#') return 0;
if (operator == '(') return 1;
if (operator == '!') return 11;
if (operator == '&') return 9;
if (operator == '|') return 7;
if (operator == '>') return 5;
if (operator == '<') return 3;
if (operator == ')') return 12;
return 0;
}
//栈外运算优先级
private static int icp(char ch) {
if (ch == '#') return 0;
if (ch == '(') return 12;
if (ch == '!') return 10;
if (ch == '&') return 8;
if (ch == '|') return 6;
if (ch == '>') return 4;
if (ch == '<') return 2;
if (ch == ')') return 1;
return 0;
}
/**
* 规范输入的表达式
* @param Sentence 输入的合式
* @return 规范后的合式
*/
private static String standardExpression(String Sentence) {
Sentence = Sentence.replaceAll("->", ">")
.replaceAll("<>", "<").replaceAll(" ", "") + "#";//在其末尾追加一个#
return Sentence;
}
/**
* 初始化
*/
private static void init() {
map.clear();
Alpha.clear();
}
}