離散數學——自動生成真值表、主合取範式

主要完成真值表的自動生成:

1. 自動生成真值表
2. 生成主合取範式

給出兩個版本,先給一個簡單的,怕大家看完都不想往下看了,簡單版本的,只需要100多行代碼!!!!(好像也不少),但是比第二個版本增加了生成主合取範式的功能,主要是利用了庫函數,所以比較簡單:

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;


int main()
{
    string a,b;
    cin>>a;
    int n=a.length();
    b=a;
    int num=0;
    for(int i=0;i<n;i++)
    {int q=1;
            for(int j=0;j<i;j++)
            {
                    if(a[i]==a[j])
                    {q=0;
                    break;}        
            }    
            if(a[i]>='a'&&a[i]<='z'&&q==1)num++;    
    }
    char zimu[num];
    int o=pow(2,num);
    int fs[o][num+1]; 
    int zhenzhi[num]={0};
	int k=0;
    for(int i=0;i<n;i++)
    {int q=1;
            for(int j=0;j<i;j++)
            {
                    if(a[i]==a[j])
                    {q=0;
                    break;}        
            }    
            if(a[i]>='a'&&a[i]<='z'&&q==1)
            {zimu[k]=a[i];
			 k++;}   
    }
    sort(zimu,zimu+num);
    for(int i=0;i<n+(2*num)+3;i++)
	cout<<"-" ;
	cout<<endl;
    for(int i=0;i<num;i++)
    cout<<zimu[i]<<" ";
    cout<<"| ";
    cout<<b<<endl;
    for(int i=0;i<n+(2*num)+3;i++)
	cout<<"-" ;
	cout<<endl;
    int cishu=0;
    	while(cishu<pow(2,num))
    {    int m=n;
         string c=a; 
         
         for(int i=0;i<num;i++)
         {
		    cout<<zhenzhi[i]<<" ";
		    fs[cishu][i]=zhenzhi[i];
		}
         cout<<"| ";
         for(int i=0;i<n;i++)
         {
         	for(int j=0;j<num;j++)
         	{
         		if(c[i]==zimu[j])c[i]=zhenzhi[j]+'0';
			 }
		 }
		 while(m!=1)
		 {  
		 	if(c.find("!1")!=string::npos)
	        c=c.replace(c.find("!1"),2,"0");
	        if(c.find("!0")!=string::npos)
	        c=c.replace(c.find("!0"),2,"1");
	        
	        if(c.find("1+1")!=string::npos)
	        c=c.replace(c.find("1+1"),3 , "1");
	        if(c.find("1+0")!=string::npos)
	        c=c.replace(c.find("1+0"),3 , "1");
	        if(c.find("0+1")!=string::npos)
	        c=c.replace(c.find("0+1"),3 , "1");
	        if(c.find("0+0")!=string::npos)
	        c=c.replace(c.find("0+0"),3 , "0");
	        
	        if(c.find("1*1")!=string::npos)
	        c=c.replace(c.find("1*1"),3 , "1");
	        if(c.find("1*0")!=string::npos)
	        c=c.replace(c.find("1*0"),3 , "0");
	        if(c.find("0*1")!=string::npos)
	        c=c.replace(c.find("0*1"),3 , "0");
	        if(c.find("0*0")!=string::npos)
	        c=c.replace(c.find("0*0"),3 , "0");
	        
	        if(c.find("1-1")!=string::npos)
	        c=c.replace(c.find("1-1"),3 , "1");
	        if(c.find("1-0")!=string::npos)
	        c=c.replace(c.find("1-0"),3 , "0");
	        if(c.find("0-1")!=string::npos)
	        c=c.replace(c.find("0-1"),3 , "1");
	        if(c.find("0-0")!=string::npos)
	        c=c.replace(c.find("0-0"),3 , "1");
	        
	        if(c.find("1=1")!=string::npos)
	        c=c.replace(c.find("1=1"),3 , "1");
			if(c.find("1=0")!=string::npos)
	        c=c.replace(c.find("1=0"),3 , "0");
	        if(c.find("0=1")!=string::npos)
	        c=c.replace(c.find("0=1"),3 , "0");
	        if(c.find("0=0")!=string::npos)
	        c=c.replace(c.find("0=0"),3 , "1");
	        
	        if(c.find("(1)")!=string::npos)
	        c=c.replace(c.find("(1)"),3 , "1");
	   	    if(c.find("(0)")!=string::npos)
	        c=c.replace(c.find("(0)"),3 , "0");
	        m=c.length();
	        }
	        for(int i=0;i<(n/2);i++)
	        cout<<" ";
	       cout<<c<<endl;
	       if(c=="1")
	       fs[cishu][num]=1;
	       else fs[cishu][num]=0;
           zhenzhi[num-1]=zhenzhi[num-1]+1;
           for(int i=num-1;i>=0;i--)
          {if(zhenzhi[i]==2)
            {
			  zhenzhi[i]=0;
              zhenzhi[i-1]=zhenzhi[i-1]+1;
			 }
           }
          cishu++;
                           
    }
    for(int i=0;i<n+(2*num)+3;i++)
	cout<<"-" ;
	cout<<endl;
	
	int m=0;int M=0;
		for (int i=0;i<o;i++)
    {
	
		if(fs[i][num]==1)m++;
		else M++;

	}
	cout<<"主析取範式:";
	if (m==0)cout<<"不存在"<<endl; 
	else {
	for (int i=0;i<o;i++)
    {    
		if(fs[i][num]==1)
		{   cout<<"(";
			for(int j=0;j<num;j++)
			{
				if(fs[i][j]==1)cout<<zimu[j];
				else cout<<"!"<<zimu[j];
				if(j!=num-1)cout<<"*";
			}
			m--;
			if(m!=0)cout<<")+";
			else cout<<")";
		}

     }
	
  }cout<<endl;
  
  	cout<<"主合取範式:";
	if (M==0)cout<<"不存在"<<endl; 
	else {
	for (int i=0;i<o;i++)
    {    
		if(fs[i][num]==0)
		{   cout<<"(";
			for(int j=0;j<num;j++)
			{
				if(fs[i][j]==0)cout<<zimu[j];
				else cout<<"!"<<zimu[j];
				if(j!=num-1)cout<<"+";
			}
			M--;
			if(M!=0)cout<<")*";
			else cout<<")";
		}

     }
	
  }
    
}

第二個版本(代碼結構比較清楚):

//truetable.c
#include<iostream>
#include<string.h>
#include<stdio.h>
int getalpha(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++;
            }
        }
    }
    //從低到高排序 
    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;
            }
        }
    }
    b[j]='\0';//加上結束標誌 
    return j;//小寫字母個數 
}

void fillValue(char a[],char varchar[],int nvar,
               char valchar[],char resultchar[]) {
    //a是原始公式 , varchar是變元列表如pqrs 
    //valchar是變元的某次取值 
    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]) {
                //是第j變元 ,其值換成第j個值 
                resultchar[i]=valchar[j];
                break;
            }
        }
    }
}

void negatecal(char a[]) {
    int _result=0,i=0,j=0;
    while(i<strlen(a)) {
        // !1 換成1 
        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 { //沒有!0 或!1 則看下一個指針 
            i++;
        }
    }
}

void kuanhao(char a[])
{
    int _result=0,i=0,j=0;
    while(i<strlen(a)){//!1 ->1 
        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  {//沒有!0 或!1 則看下一個指針 
            i++;
        }
    }
}
void conYsh(char a[])
{
    int _result=0,i=0,j=0;
    while(i<strlen(a))  {//!1 ->1 
        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 {  //沒有!0 或!1 則看下一個指針 
            i++;
        }
    }
}
void biCondYsh(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]='1';_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]=='0')&&(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 condYsh(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]='1';
            _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]='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 disConjYsh(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++;
        }
    }
}
int main(int argc,char* argv[])
{
    char pstate[120],pstate0[120],charList[120],charVal[120];
    char minItem[1024][52],truetable[1024];//最多10個變量 
    int i=0,nold=0,nnew=0,nvar=1,nRow=1,j=0,flagsum=1,iMinItem=0;
    printf("請輸入公式(析+,合*,條—,雙=,否定!,01):\n");
    gets(pstate0);fflush(stdin);
    nold=strlen(pstate0)+1;nnew=strlen(pstate0);
    for(i=0;i<nnew;i++)
    {
        pstate[i]=pstate0[i];
    }
    pstate[i]='\0';
    nvar=getalpha(pstate,charList);
    //真值表各個變元的值 
    nRow=1;
    for(i=0;i<nvar;i++)
    {
        charVal[i]='0';nRow=nRow*2;
    }
    charVal[i]='\0';
    //真值表的首行 
    printf("\n");
    for(i=0;i<nvar;i++){
        printf("%4c",charList[i]);}
    printf("%15c%s\n",' ',pstate);
    for(i=0;i<nvar;i++)
    {printf("%4c",'-');}
    printf("|");
    for(i=0;i<60;i++){
        printf("%c",'-');}
    printf("\n");
    
    for(i=0;i<nRow;i++){
        //真值表的各行 
        for(j=0;j<nvar;j++){
            printf("%4c",charVal[j]);
        }
        //將值填入到公式中 
        pstate[0]='\0';
        fillValue(pstate0,charList,nvar,charVal,pstate);
        //計算公式的值 
        nold=strlen(pstate0)+1;
        nnew=strlen(pstate);
        while (nnew<nold){
            nold=strlen(pstate);
            negatecal(pstate);//否定 
            kuanhao(pstate);//(A)
            conYsh(pstate);
            biCondYsh(pstate);
            condYsh(pstate);
            disConjYsh(pstate);
            nnew=strlen(pstate);
        }
        if(strlen(pstate)==1){
            if(pstate[0]=='1'){
                for(j=0;j<nvar;j++){
                    minItem[iMinItem][j]=charVal[j];
                }
                minItem[iMinItem][j]='\0';
                iMinItem++;
            }
            truetable[i]=pstate[0];
        }
        printf("%20c%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   //1+0=1 不變 
                {break;			 }
            }
            else if(charVal[j]=='0'){
                if(flagsum==1)//0+1=1//沒有進位 
                {charVal[j]='1';flagsum=0;} 
                else  //0+0結束 
                {break;	 }
            }
        } 
    }
    for(i=0;i<iMinItem;i++){
        if(i==0){
            printf("m%s",minItem[i]);
        }
        else {printf("+m%s",minItem[i]);}
    }
    printf("\n");
    for(i=0;i<iMinItem;i++){
        if(i==0){
            printf("(");
            for(j=0;j<nvar;j++){
                if(j==0){
                    if(minItem[i][j]=='1'){printf("%c",charList[j]);}
                    else {printf("!%c",charList[j]);}
                }
                else{
                    if(minItem[i][j]=='1'){
                        printf("*%c",charList[j]);}
                    else {printf("*!%c",charList[j]);}
                }
            }
            printf(")");
        }
        else {
            printf("+(");
            for(j=0;j<nvar;j++){
                if(j==0){
                    if(minItem[i][j]=='1'){printf("%c",charList[j]);}
                    else {printf("!%c",charList[j]);}
                }else{
                    if(minItem[i][j]=='1'){printf("*%c",charList[j]);}
                    else{printf("*!%c",charList[j]);}
                }
            }
            printf(")");
        }
    }
    
    
    
}

第一個程序主要是用了庫函數find()和replace()所以比較簡單,第二個就寫的很模塊化,可能更容易理解,大家自己看看叭~
Ps:find()和replace()函數用來處理字符串很舒服!!!!!!(C++)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章