Java求取主析取范式、主合取范式、成真赋值、成假赋值、打印真值表

离散数学实验

/*1.对给出的任意一个命题公式(不超过四个命题变元),
 * 使学生会利用编程软件表示出来,并且能够计算它在各组真值指派下所应有的真值,
 * 画出其真值表。
 * (1)﹁(﹁p∨q)∧q的真值表;
 * (2)(p∨q)→﹁r的真值表;
 */

/*2.输入命题公式(p→﹁q)→r
  *输出主析取范式、主合取范式
  *输出成真赋值、成假赋值
*/

实现思路:先求出命题公式变元由000~111的真值储存在数组中,循环遍历输出真值表;当命题公式真值为1时对应的变元值为成真赋值,此时若对应变元值为0输出对应变元的非,否则直接输出变元与变元之间用合取联结词连接,公式与公式之间用析取联结词连接(此时为主析取范式);当命题公式真值为0时对应变元值为成假赋值,此时若对应变元值为0输出对应变元的非,否则直接输出,变元与变元之间用析取联结词连接,公式与公式间用合取联结词连接(此时为主合取范式)。

        命题公式的计算用后缀表达式(逆波兰表达式)求解,后缀表达式用栈来存储。

        在思考解决主析取范式、主合取范式时走了很多的弯路,后来经过很久才发现真值表与范式之间的联系,其实想通了写起来非常的顺畅。写完也非常的有成就感。

打印真值表代码运行结果:

 

 

主析取范式、主合取范式、成真赋值、成假赋值代码运行结果:

package experiment;

public class LogicalOperation {

	int disjunction(int x,int y){//析取∨
		if(x==1||y==1) {
			return 1;
		}
		else return 0;
	}
	int conjunction(int x,int y) {//合取∧
		if(x==y&&x==1) {
			return 1;
		}
		else return 0;
	}
	int nagation(int x) {//否定
		if(x==0) {
			return 1;
		}
		else return 0;
	}
	int implication(int x,int y) {//蕴涵
		if(x==1&&y==0) {
			return 0;
		}
		else return 1;
	}
	int equivalence(int x,int y) {//等价
		if(x==y) {
			return 1;
		}
		else return 0;
	}
}

 NormalForm.java

包含求取真值表、主析取范式、主合取范式、成真赋值、成假赋值等的方法

package experiment;

public class NormalForm {
	String form;
	int count=0;
	int count0=0;
	int count1=0;
	
	Proposition fo;
	Translation tr;
	NormalForm(String form){
		this.form=form;
		fo = new Proposition(form);
		tr = new Translation(form);
		tr.judge();
	}
	
	void calculate() {
		int [] x=new int[4];
		for(int i=0;i<2;i++) {
			for(int j=0;j<2;j++) {
				for(int k=0;k<2;k++) {
					for(int l=0;l<2;l++) {
						fo.va1[count]=i;
						fo.va2[count]=j;
						fo.va3[count]=k;
						fo.va4[count]=l;
						x[0]=i;
						x[1]=j;
						x[2]=k;
						x[3]=l;
						fo.truth[count]=tr.operate(x);
						if(fo.truth[count]==0) {
							count0++;
						}
						else
							count1++;
						count++;	
					}					
				}
			}
		}
	}
	void table() {
		if(tr.judge()==2) {
			System.out.println(tr.va[0]+" "+tr.va[1]+" "+tr.pfr);
			for(int i=0;i<4;i++) {
				System.out.println(fo.va1[i*4]+" "+fo.va2[i*4]+"   "+fo.truth[i*4]);
			}
		}
		if(tr.judge()==3) {
			System.out.println(tr.va[0]+" "+tr.va[1]+" "+tr.va[2]+" "+tr.pfr);
			for(int i=0;i<8;i++) {
				System.out.println(fo.va1[i*2]+" "+fo.va2[i*2]+" "+fo.va3[i*2]+"   "+fo.truth[i*2]);
			}
		}
		if(tr.judge()==4) {
			System.out.println(tr.va[0]+" "+tr.va[1]+" "+tr.va[2]+" "+tr.va[3]+" "+tr.pfr);
			for(int i=0;i<16;i++) {
				System.out.println(fo.va1[i]+" "+fo.va2[i]+" "+fo.va3[i]+" "+fo.va4[i]+"   "+fo.truth[i]);
			}
		}
		
	}
	void pdnf() {
		//this.calculate();
		count1=count1/2;
		count1--;
		System.out.println("主析取范式为:");
		for(int i=0;i<8;i++) {
			if(fo.truth[i*2]==1) {
				System.out.print("(");
				if(fo.va1[i*2]==0) {
					System.out.print("﹁"+tr.va[0]);
				}
				else {
					System.out.print(tr.va[0]);
				}
				System.out.print("∧");
				if(fo.va2[i*2]==0) {
					System.out.print("﹁"+tr.va[1]);
				}
				else {
					System.out.print(tr.va[1]);
				}
				System.out.print("∧");
				if(fo.va3[i*2]==0) {
					System.out.print("﹁"+tr.va[2]);
				}
				else {
					System.out.print(tr.va[2]);
				}
				System.out.print(")");
				
				if(count1>0) {
					System.out.print("∨");
					count1--;
				}
			}
		}
		System.out.println();
	}
	void pcnf() {
		count0=count0/2;
		count0--;
		System.out.println("主合取范式为:");
		for(int i=0;i<8;i++) {
			if(fo.truth[i*2]==0) {
				System.out.print("(");
				if(fo.va1[i*2]==0) {
					System.out.print("﹁"+tr.va[0]);
				}
				else {
					System.out.print(tr.va[0]);
				}
				System.out.print("∨");
				if(fo.va2[i*2]==0) {
					System.out.print("﹁"+tr.va[1]);
				}
				else {
					System.out.print(tr.va[1]);
				}
				System.out.print("∨");
				if(fo.va3[i*2]==0) {
					System.out.print("﹁"+tr.va[2]);
				}
				else {
					System.out.print(tr.va[2]);
				}
				System.out.print(")");
				
				if(count0>0) {
					System.out.print("∧");
					count0--;
				}
			}
		}
		System.out.println();
	}
	void comeTrue() {
		System.out.println("成真赋值为:");
		for(int i=0;i<8;i++) {
			if(fo.truth[i*2]==1) {
				System.out.print(fo.va1[i*2]+" "+fo.va2[i*2]+" "+fo.va3[i*2]);
				System.out.print("   ");
			}
		}
		System.out.println();
	}
	void aFalse() {
		System.out.println("成假赋值为:");
		for(int i=0;i<8;i++) {
			if(fo.truth[i*2]==0) {
				System.out.print(fo.va1[i*2]+" "+fo.va2[i*2]+" "+fo.va3[i*2]);
				System.out.print("   ");
			}
		}
		System.out.println();
	}
}

Translation.java

包含命题公式后缀表达式的转换和求解,变元个数的判断

package experiment;

public class Translation {
	String pfr;
	char[] op;//命题公式
	char[] op1;//后缀表达式
	char[] op2;//符号,中间数组
	char[] va=new char[4];//变量储存
	int[] variable=new int[4];                                                                                                                               
	int count1=-1;//op1计数器
	int count2=-1;//op2计数器
	int count3=0;//va计数器
	int x1,x2,x3,x;//x储存表达式的值
	LogicalOperation lg = new LogicalOperation();
	Translation(String pfr){
		this.pfr=pfr;
		op=pfr.toCharArray();
		op1=new char[op.length];
		op2=new char[op.length];
		for(int i=0;i<op.length;i++) {//转化为后缀表达式,遍历op数组;
			if(op[i]>='a'&&op[i]<='z') {
				count1++;
				op1[count1]=op[i];
			}
			else if(op[i]=='(') {
				count2++;
				op2[count2]=op[i];
			}
			else if(op[i]=='﹁') {
				if(count2==-1||op2[count2]=='∨'||op2[count2]=='∧'||op2[count2]=='→'||op2[count2]=='↔'||op2[count2]=='(') {
					count2++;
					op2[count2]=op[i];
				}
				else if(op2[count2]=='﹁') {
					count1++;
					op1[count1]='﹁';
				}
			}
			else if(op[i]=='∨'||op[i]=='∧'||op[i]=='→'||op[i]=='↔') {
				if(count2==-1||op2[count2]=='(') {
					count2++;
					op2[count2]=op[i];
				}
				else if(op2[count2]=='∨'||op2[count2]=='∧'||op2[count2]=='→'||op2[count2]=='﹁'||op2[count2]=='↔') {
					count1++;
					op1[count1]=op2[count2];
					op2[count2]=op[i];
				}
			}
			else if(op[i]==')') {
				while(op2[count2]!='(') {
					count1++;
					op1[count1]=op2[count2];
					count2--;
				}
				count2--;
			}
		}//循环结束
		while(count2>=0) {
			count1++;
			op1[count1]=op2[count2];
			count2--;
		}//后缀表达式完成
	}
	int judge() {//判断变量个数
		va[0]=op1[0];
		for(int i=1;i<=count1;i++) {
			if(op1[i]>='a'&&op1[i]<='z') {
				if(op1[i]!=va[0]&&op1[i]!=va[1]&&op1[i]!=va[2]) {
					if(va[1]==0) {
						va[1]=op1[i];
						count3=2;
					}
					else if(va[2]==0) {
						va[2]=op1[i];
						count3=3;
					}
					else {
						va[3]=op1[i];
						count3=4;
					}
				}
			}
		}
		return count3;
	}
	int operate(int []xi) {
		int num=-1;
		for(int i=0;i<=count1;i++) {
			if(op1[i]>='a'&&op1[i]<='z') {
				if(op1[i]==va[0]) {
					num++;
					variable[num]=xi[0];
				}
				else if(op1[i]==va[1]) {
					num++;
					variable[num]=xi[1];
				}
				else if(op1[i]==va[2]) {
					num++;
					variable[num]=xi[2];
				}
				else if(op1[i]==va[3]) {
					num++;
					variable[num]=xi[3];
				}
			}
			else if(op1[i]=='﹁') {
				variable[num]=lg.nagation(variable[num]);
			}
			else if(op1[i]=='∨') {
				variable[num-1]=lg.disjunction(variable[num-1], variable[num]);
				num--;
			}
			else if(op1[i]=='∧') {
				variable[num-1]=lg.conjunction(variable[num-1], variable[num]);
				num--;
			}
			else if(op1[i]=='→') {
				variable[num-1]=lg.implication(variable[num-1], variable[num]);
				num--;
			}
			else if(op1[i]=='↔') {
				variable[num-1]=lg.equivalence(variable[num-1], variable[num]);
				num--;
			}
		}
		return variable[num];
	}

}

Proposition.java

命题公式类,包含命题公式所具有的成员变量

package experiment;

public class Proposition {
	String formula;
	int[] va1 = new int[16];
	int[] va2 = new int[16];
	int[] va3 = new int[16];
	int[] va4 = new int[16];
	int[] truth = new int[16];
	Proposition(String formula) {
		this.formula=formula;
	}
}

experiment2.java

求真值表执行类

package experiment;
import java.util.*;
/*2.对给出的任意一个命题公式(不超过四个命题变元),
 * 使学生会利用编程软件表示出来,并且能够计算它在各组真值指派下所应有的真值,
 * 画出其真值表。
 * (1)﹁(﹁p∨q)∧q的真值表;
 * (2)(p∨q)→﹁r的真值表;
 */
public class experiment2 {
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		Scanner scanf=new Scanner(System.in);
		int[] w=new int[4];
		System.out.println("输入命题公式(不超过四个命题变元):");
		System.out.println("非为‘﹁’,析取为‘∨’,合取为‘∧’蕴涵为‘→’,等价为‘↔’");
		String prf = scanf.nextLine();
		NormalForm form = new NormalForm(prf);
		form.calculate();
		form.table();
	}
}

 experiment3.java

求主析取范式主合取范式、成真赋值、成假赋值执行类

package experiment;
import java.util.*;
public class experiment3 {

	public static void main(String[] args) {
		/*输入命题公式(p→﹁q)→r
		 *输出主析取范式、主合取范式
		 *输出成真赋值、成假赋值
		 * 非为‘﹁’,析取为‘∨’,合取为‘∧’蕴涵为‘→’,等价为‘↔’*/
		String form;
		Scanner scanf = new Scanner(System.in);
		System.out.println("请输入命题公式:(非为‘﹁’,析取为‘∨’,合取为‘∧’蕴涵为‘→’,等价为‘↔’)");
		form = scanf.nextLine();
		NormalForm normal = new NormalForm(form);
		normal.calculate();
		normal.pdnf();
		normal.pcnf();
		normal.comeTrue();
		normal.aFalse();
	}

}

  • 11
    点赞
  • 63
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值