NJUPT南邮 | 离散数学_实验一

利用真值表法求取主析取范式以及主合取范式

  1. 内容:
    编程实现用真值表法求取含n个变元的合式公式所对应的主析取范式和主合取范式。
    要求:
    能够列出合式公式的真值表并给出相应主析取和主合取范式。

  2. 实验代码:

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();
    }


}

你可能感兴趣的:(南邮实验,java)