您的位置:首页 > 编程语言 > C语言/C++

C语言实现离散数学中的命题逻辑

2014-03-28 18:06 274 查看
今天,终于完成了用C语言实现了离散数学里关于命题逻辑的运算,一开始想用栈来实现,但是发现自己对栈还不太熟悉,于是在网上参考了一下其他人的做法,最后终于整出来了。先做个记录,下次再用栈实现。
要求:
从键盘输入两个命题变元P和Q的真值,求它们的合取、析取、非取和单、双蕴涵的真值,

求任意一个命题公式的真值表(包括公式合法性检查),并根据真值表求主范式(分析取主范式、合取主范式)

一、算法分析



①合取/\:p,q都为1的时候为1,其他为0

C语言算法:

/**求P、Q的合取的函数**/
  void Conj(int p,int q){
  	int a = p && q;
  	printf("\n \t\tP和Q的合取为:P/\\Q = %d\n",a);
  }


②析取\/:p,q都为0的时候为0,其他为1

C语言算法:

/**求P、Q的析取的函数**/
  	void Disj(int p,int q){
  	int a = p || q;
  	printf("\n \t\tP和Q的析取为:P\\/Q = %d\n",a);
  	}


③非取!:p为1时,!p为0;p为0时,!P为1

C语言算法:

/**求P的非取的函数**/
  	void P_unor(int p){
  	int a = !p;
  	printf("\n\t\tP的非取为:!P = %d\n",a);
  	}
/**求Q的非取的函数**/
void Q_unor(int q){
int a = !q;
printf("\n\t\tQ的非取为:!Q = %d\n",a);
}


④蕴含->:p为1,q为0时为0,其他为1

C语言算法:

 /**求P、Q的单蕴涵的函数**/
  void S_impl(int p,int q){
  	int a = (!p) || q;
  	printf("\n\t\tP和Q的单蕴涵为:P -> Q = %d\n",a);
  }


⑤双蕴涵<->:p,q同真同假

C语言算法:

/**求P、Q的双蕴涵的函数**/
  void D_impl(int p,int q){
  	int a = ((!p) || q) && ((!q) || p);
  	printf("\n\t\tP和Q的双蕴涵为:P <-> Q = %d\n",a);
  }


⑥求任意一个命题公式的真值表

根据真值表求主范式

C语言算法:

首先是输入一个式子,判断其合理性后从式子中查找出变量的个数,开辟一个二进制函数,用来生成真值表,然后用函数运算,输出结果,并根据结果归类给范式,最后输出范式。

函数部分,主要是3个函数,一个为真值表递加函数,通过二进制的加法原理递进产生,一个为分级运算函数,这个函数是通过判断括号,选出最内级括号的内容执行运算函数,这样一级一级向外运算,最后得出最终结果,剩下一个为主运算函数,按照运算符号的优先级按顺序进行运算,如先将所有非运算运算完,再执行与运算。

⑦主运算函数

/**主运算函数**/
  int MAP(char sz
,char ccu
,int icu
,int h0)
  {
    int i, h = 0, j = 0, j1 = 0, j2 = 0, j3 = 0, j4 = 0, j5 = 0, i1, i2, p1 = -1, p2 = -1, s;
    char dt
;
    s = strlen(sz);
    if(s == 1)
  	if(sz[0] == -2)		//判断是否是最后一项
  		return 0;
  	else
  		return 1;		//1 就是sz[0]的值、
    else{
      for(i = 0; i < s-j; i++) //先处理非
  		if(sz[i] == '!'){
  			for(i1 = 0; i1 < h0; i1++)
  				if(sz[i+1] == ccu[i1])//将变量赋值并给P1
  					p1 = icu[i1];
  			if(sz[i+1] == -2)//如果是前运算结果的0,则P1等于0
  				p1 = 0;
  			if(p1 == -1)//如果是数字,直接给P1
  				p1 = sz[i+1];
  			dt[j+2] = !p1;//非运算
  			sz[i] = j+2;
  			j++;
  			p1 = 0;
  			for(i1 = i+1; i1 < s-j; i1++)
  				sz[i1] = sz[i1+1];//将后续式子前移一项
  		}
  		p1 = -1;
  		j1 = j;
      for(i = 0; i < s-j1-2*j2; i++) // 处理与
  		if(sz[i] == '&'){
  			for(i1 = 0; i1 < h0; i1++){
  				if(sz[i-1] == ccu[i1])//将变量赋值并给P1
  					p1 = icu[i1];
  				if(sz[i+1] == ccu[i1])//将变量赋值并给P2
  					p2 = icu[i1];
  			}
        for(i2 = 2; i2 < j+2; i2++) {
          if(sz[i-1] == i2) //如果为前计算结果,将结果赋值并给P1
            p1 = dt[i2];
          if(sz[i+1] == i2) //如果为前计算结果,将结果赋值并给P2
            p2 = dt[i2];
  	  }
        if(sz[i-1] == -2)//如果是前运算结果的0,则P1等于0
          p1 = 0;
        if(sz[i+1] == -2)//如果是前运算结果的0,则P2等于0
          p2 = 0;
        if(p1 == -1) //如果是数字,直接给P1
          p1 = (int)(sz[i-1]);
        if(p2 ==-1)//如果是数字,直接给P2
          p2 = (int)(sz[i+1]);
        dt[j+2] = p1 && p2;//与运算
        sz[i-1] = j+2;
        j++;
        j2++;
        p1 = -1;
        p2 = -1;
        for(i1 = i; i1 < s-j1-2*j2; i1++)//将后续式子前移两项
          sz[i1] = sz[i1+2];
        i = i-1;
  	}
      for(i = 0; i < s-j1-2*j2-2*j3; i++) // 处理或。
        if(sz[i] == '|'){
          for(i1 = 0; i1 < h0; i1++){
            if(sz[i-1] == ccu[i1])//将变量赋值并给P1
              p1 = icu[i1];
            if(sz[i+1] == ccu[i1])//将变量赋值并给P2
              p2 = icu[i1];
  		}
          for(i2=2;i2<j+2;i2++) {
            if(sz[i-1] == i2)  //如果为前计算结果,将结果赋值并给P1
              p1 = dt[i2];
            if(sz[i+1] == i2)//如果为前计算结果,将结果赋值并给P2
              p2 = dt[i2];
  		}
          if(sz[i-1] == -2)//如果是前运算结果的0,则P1等于0
            p1 = 0;
          if(sz[i+1] == -2)//如果是前运算结果的0,则P2等于0
            p2 = 0;
          if(p1 == -1)//如果是数字,直接给P1
            p1 = sz[i-1];
          if(p2 == -1)//如果是数字,直接给P2
            p2 = sz[i+1];
          dt[j+2] = p1 || p2;//或运算
          sz[i-1] = j+2;
          j++;
          j3++;
          p1 = -1;
          p2 = -1;
          for(i1 = i; i1 < s-j1-2*j2-2*j3; i1++)//将后续式子前移两项
            sz[i1]=sz[i1+2];
          i--;
  	  }
        for(i = 0; i < s-j1-2*j2-2*j3-2*j4; i++) // 处理蕴含。
        if(sz[i] == '^'){
          for(i1 = 0; i1 < h0; i1++){
            if(sz[i-1] == ccu[i1])//将变量赋值并给P1
              p1 = icu[i1];
            if(sz[i+1] == ccu[i1])//将变量赋值并给P2
              p2 = icu[i1];
  		}
          for(i2 = 2; i2 < j+2; i2++) {
            if(sz[i-1] == i2) //如果为前计算结果,将结果赋值并给P1
              p1 = dt[i2];
            if(sz[i+1] == i2) //如果为前计算结果,将结果赋值并给P2
              p2 = dt[i2];
  		}
  		if(sz[i-1] == -2)//如果是前运算结果的0,则P1等于0
  	   	  p1 = 0;
  		if(sz[i+1] == -2)//如果是前运算结果的0,则P2等于0
  		  p2 = 0;
  		if(p1 == -1)//如果是数字,直接给P1
  	  	  p1 = sz[i-1];
  		if(p2 == -1)//如果是数字,直接给P2
  		  p2 = sz[i+1];
  		dt[j+2] = (!p1) || p2;//蕴含运算
  		sz[i-1] = j+2;
  		j++;
  		j4++;
  		p1 = -1;
  		p2 = -1;
  		for(i1 = i; i1 < s-j1-2*j2-2*j3-2*j4; i1++)//将后续式子前移两项
  		  sz[i1] = sz[i1+2];
  		i--;
  	  }
  	  for(i = 0; i < s-j1-2*j2-2*j3-2*j4-2*j5; i++) // 处理等值。
  	  if(sz[i] == '~'){
  	    for(i1 = 0; i1 < h0; i1++){
            if(sz[i-1] == ccu[i1])//将变量赋值并给P1
              p1 = icu[i1];
            if(sz[i+1] == ccu[i1])//将变量赋值并给P2
              p2 = icu[i1];
  		}
          for(i2 = 2; i2 < j+2; i2++) {
            if(sz[i-1] == i2) //如果为前计算结果,将结果赋值并给P1
              p1 = dt[i2];
            if(sz[i+1] == i2) //如果为前计算结果,将结果赋值并给P2
              p2 = dt[i2];
  		}
          if(sz[i-1] == -2)//如果是前运算结果的0,则P1等于0
            p1 = 0;
          if(sz[i+1] == -2)//如果是前运算结果的0,则P2等于0
            p2 = 0;
          if(p1 == -1)//如果是数字,直接给P1
            p1 = sz[i-1];
          if(p2 == -1)//如果是数字,直接给P2
            p2 = sz[i+1];
          dt[j+2] = (!p1 || p2) && (!p2 || p1);//等值运算
          sz[i-1] = j+2;
          j++;
          j5++;
          p1 = -1;
          p2 = -1;
          for(i1 = i; i1 < s-j1-2*j2-2*j3-2*j4-2*j5; i1++)//将后续式子前移两项
            sz[i1] = sz[i1+2];
          i--;
  	  }
        return dt[j+1];//返回结果
      }
  }


⑧分级运算函数

 /**分级运算函数**/
  int CR(char sz
,char ccu
,int icu
,int h0)
  {
  	  int i,j,h,s,kh = 0,wz
,a;
  	  char xs1
,ckh
;			//xs1用来保存括号内的字符 ckh用来保存括号。
  	  s = strlen(sz);
  	  for(i = 0; i < s; i++)
  		  if(sz[i] == '(' || sz[i] == ')'){	//判断括号
  				wz[kh] = i;					//存储括号位置
  				ckh[kh] = sz[i];			//存储括号类型
  				kh++;
  		  }
  	  if(kh == 0)
  		return MAP(sz,ccu,icu,h0);	//如果无括号,直接运行
  	  else{
  		for(i = 0; i < kh; i++)
  			if(ckh[i] == ')')			//找到第一个" )"
  				break;
  		for(j = wz[i-1]+1,h=0; j < wz[i]; j++,h++) //存储最内级括号中的内容
  			xs1[h] = sz[j];
  		xs1[h] = '\0';
  		a = MAP(xs1,ccu,icu,h0);		//运行最内级括号的式子,得到结果
  		if(a == 1)					//判断并存储结果
  		  sz[wz[i-1]] = 1;
  		else
  		  sz[wz[i-1]] = -2;
  		for(j = wz[i-1]+1; j < s+wz[i-1] - wz[i]; j++)//将括号后内容前移
  		  sz[j] = sz[j + wz[i] - wz[i-1]];
  		sz[j] = '\0';
  		return CR(sz,ccu,icu,h0);//循环执行
  	  }
  }


⑨二进制赋值函数

/**二进制赋值函数**/
  void BVA(int b
,int f){
  	  int i;
  	  i = f;
  	  if(b[f] == 0)	 //加1
  		b[f] = 1;
  	  else			//进位
  	  {
  		b[f] = 0;
  		BVA(b,--i);
  	  }
  }



二、程序运行如下





输入数据,进行操作选择:

选a:求P、Q的合取、析取、非取、单蕴涵、双蕴涵



输入数据:



选择进行的操作:

选a:



选b:



选g:

返回上一级



选b:求任意一个命题公式的真值表及其主范式





公式合法性检查:



输入合法数据后:



选择b:

返回上一级



选c:

退出系统

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c语言