C语言 命题公式真值表

1.实验目的

掌握命题公式真值表的求解,并实现自动求解程序。

2.实验内容

输入:任意命题公式

输出:该命题公式的真值表

要求:

  1. 输入任意命题公式,要求用数据存储命题公式的所有赋值及对应真值,并输出该公式真值表
  2. 此题,难度稍大,对命题公式的表示的方式不一样,实现过程略有不同,可查找相关资料

 

3.实验过程(主要思想、核心算法、核心代码)

代码比较长,还需要细心观看,有什么意见还请大佬提出,谢谢!

主函数

#include <stdio.h>
#include <string.h>
int main()
{
	void quFan(char a[]);
	void kuohao(char a[]);
	void heQu(char a[]);
	void stJian(char a[]);
	void xiQu(char a[]);
	int allData(char a[],char b[]);
	void fillIn(char a[],char varchar[],int nvar,char values[],char resultchar[]);

	char pstate[120],pstate0[120],charList[120],charVal[120];
	int i=0,nold=0,nnew=0,nvar=1,nRow=1,j=0,flagsum=1;
	printf("请输入公式(析|,合&,条-,双=,否!,01):\n");
	gets(pstate0);

	nold=strlen(pstate0)+1;
	nnew=strlen(pstate0);
	for(i=0;i<nnew;i++)
	{
		pstate[i]=pstate0[i];
	}
	pstate[i]='\0';

	nvar=allData(pstate,charList);//取变元个数
	nRow=1;//有2^n个情况
	for(i=0;i<nvar;i++){
		charVal[i]='0';nRow=nRow*2;
	}
	charVal[i]='\0';

	for(i=0;i<nRow;i++){//输出每种情况的结果
		for(j=0;j<nvar;j++)
		{
			printf("%4c",charVal[j]);//每种赋值情况输出
		}

		/**
			将值填入公式
			pstate原始数组
			返回pstate填充后数组
		*/
		fillIn(pstate0,charList,nvar,charVal,pstate);
		//计算公式的值
		nold=strlen(pstate0)+1;
		nnew=strlen(pstate);
		while(nnew<nold)
		{
			nold=strlen(pstate);
			quFan(pstate);
			kuohao(pstate);
			stJian(pstate);
			heQu(pstate);
			xiQu(pstate);
			nnew=strlen(pstate);
		}

		printf("%15c%s",' ',pstate);
		printf("\n");
		//值加1
		flagsum=1;
		for(j=nvar-1;j>=0;j--)
		{
			if(charVal[j]=='1'){
				if(flagsum==1){//1+1=10//进位
					charVal[j]='0';flagsum=1;
				}else{break;}//1+0=1  不变
			}else if(charVal[j]=='0'){
				if(flagsum==1){ //0+1=1 //没有进位
					charVal[j]='1'; flagsum=0;
				}else{break;}// 0+0 
			}
		}
	}
	return 0;
}

 

取反,也就是非!

void quFan(char a[]){
	int _result=0,i=0,j=0;
	while(i<strlen(a)){
		j=i;_result=0;
		//非的真值情况
		if((j+1<strlen(a))&&(a[j]=='!')&&(a[j+1]=='1')){
			a[j]='0';_result=1;
		}else if((j+1<strlen(a))&&(a[j]=='!')&&(a[j+1]=='0')){
			a[j]='1';_result=1;
		}

		if(_result==1){//修改成功后则后面的往前覆盖
			j++;
			while(a[j+1]!='\0'){
				a[j]=a[j+1]; j++;
			}
			a[j]='\0';
		}else{i++;}
	}
}

 

括号解析

void kuohao(char a[])
{
	int _result=0,i=0,j=0;
	while(i<strlen(a)){
		j=i; _result=0;
		//括号的处理
		if((j+2<strlen(a))&&(a[j]=='(')&&(a[j+1]=='1')&&(a[j+2]==')')){
			a[j]='1'; _result=1;
		}else if((j+2<strlen(a))&&(a[j]=='(')&&(a[j+1]=='0')&&(a[j+2]==')')){
			a[j]='0'; _result=1;
		}

		if(_result==1){//修改成功后则后面的往前覆盖
			j++;
			while(a[j+2]!='\0'){
				a[j]=a[j+2]; j++;
			}
			a[j]='\0';
		}else {i++;}
	}
}

 

合取

void heQu(char a[]){
	int _result=0,i=0,j=0;
	while(i<strlen(a)){
		j=i;_result=0;
		//合取的真值情况
		if((j+2<strlen(a))&&(a[j]=='0')&&(a[j+1]=='&')&&(a[j+2]=='0'))
		{a[j]='0';_result=1;}
		else if((j+2<strlen(a))&&(a[j]=='0')&&(a[j+1]=='&')&&(a[j+2]=='1'))
		{a[j]='0';_result=1;}
		else if((j+2<strlen(a))&&(a[j]=='1')&&(a[j+1]=='&')&&(a[j+2]=='0'))
		{a[j]='0';_result=1;}
		else if((j+2<strlen(a))&&(a[j]=='1')&&(a[j+1]=='&')&&(a[j+2]=='1'))
		{a[j]='1';_result=1;}

		if(_result==1){//修改成功后则后面的往前覆盖
			j++;
			while(a[j+2]!='\0'){
				a[j]=a[j+2];j++;
			}
			a[j]='\0';
		}else {i++;}
	}
}

 

析取

void xiQu(char a[]){
	int _result=0,i=0,j=0;
	while(i<strlen(a)){
		j=i;_result=0;
		//析取的真值情况
		if((j+2<strlen(a))&&(a[j]=='0')&&(a[j+1]=='|')&&(a[j+2]=='0'))
		{a[j]='0';_result=1;}
		else if((j+2<strlen(a))&&(a[j]=='0')&&(a[j+1]=='|')&&(a[j+2]=='1'))
		{a[j]='1';_result=1;}
		else if((j+2<strlen(a))&&(a[j]=='1')&&(a[j+1]=='|')&&(a[j+2]=='0'))
		{a[j]='1';_result=1;}
		else if((j+2<strlen(a))&&(a[j]=='1')&&(a[j+1]=='|')&&(a[j+2]=='1'))
		{a[j]='1';_result=1;}

		if(_result==1){//修改成功后则后面的往前覆盖
			j++;
			while(a[j+2]!='\0'){
				a[j]=a[j+2];j++;
			}
			a[j]='\0';//结尾添加字符串结束符
		}else {i++;}
	}
}

 

双条件

void stJian(char a[])
{
	int _result=0,i=0,j=0;
	while(i<strlen(a)){
		j=i;_result=0;
		//双条件的真值情况
		if((j+2<strlen(a))&&(a[j]=='0')&&(a[j+1]=='=')&&(a[j+2]=='0'))
		{a[j]='0';_result=1;}
		else if((j+2<strlen(a))&&(a[j]=='0')&&(a[j+1]=='=')&&(a[j+2]=='1'))
		{a[j]='0';_result=1;}
		else if((j+2<strlen(a))&&(a[j]=='1')&&(a[j+1]=='=')&&(a[j+2]=='0'))
		{a[j]='0';_result=1;}
		else if((j+2<strlen(a))&&(a[j]=='1')&&(a[j+1]=='=')&&(a[j+2]=='1'))
		{a[j]='1';_result=1;}

		if(_result==1){//修改成功后则后面的往前覆盖
			j++;
			while(a[j+2]!='\0'){
				a[j]=a[j+2];j++;
			}
			a[j]='\0';
		}else {i++;}
	}
}

 

获取命题公式所有不同的元素

int allData(char a[],char b[]){
	char tmpc=' '; 
	int n=strlen(a),i=0,j=0,k=0;
	for(i=0;i<n;i++){//获取所有变元,以便于输出和赋值
		if(((a[i]>='a')&&(a[i]<='z'))||((a[i]>='A')&&(a[i]<='Z'))){
			for(k=0;k<j;k++){
				if(b[k]==a[i]){
					break;
				}
			}
			if(k>=j){
				b[j]=a[i];
				j++;
			}
		}
	}
	b[j]='\0';//加上结束标志
	//printf("====%s",b);
	//从高到低排序
	for(i=0;i<j-1;i++){
		for(k=0;k<j-i-1;k++){
			if(b[k]>b[k+1]){
				tmpc=b[k];
				b[k]=b[k+1];
				b[k+1]=tmpc;
			}
		}
	}
	return j;//不同的变元个数
}

 

将赋值情况代入命题公式中

void fillIn(char a[],char varchar[],int nvar,char values[],char resultchar[])
{
	/**
		a是原始公式
		varchar是变元列表如abc
		values 是变元的某次取值
		二进制的思维把相应位置的变元替换成'0'或'1'
	*/
	int nLen=strlen(a),i=0,j=0,k=0;
	for(i=0;i<nLen;i++){//不改变原数组
		resultchar[i]=a[i];
	}
	resultchar[i]='\0';
	for(i=0;i<nLen;i++){
		for(j=0;j<nvar;j++){
			if(resultchar[i]==varchar[j]){
				resultchar[i]=values[j];
				break;
			}
		}
	}
}

 

温馨提示:以上是完整代码,小代码块可能多出一个花括号,不碍事那是main的或括号。大佬有意见或者建议还请提出,学习进步。

  • 28
    点赞
  • 184
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值