HNU-离散数学-程序设计实验-输出合式公式的真值表以及主析取范式

离散数学程序设计实验(占期末比重1.5%)

输出合式公式的真值表以及主析取范式

希望能帮到HNUers,加油!

注释部分是原代码部分,如果帮到你了麻烦点个赞

/*
 * 实验二
 * 输出合式公式的真值表以及主析取范式
 * by wolf
 */
 
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
int getalpha(char a[],char b[])
{
    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'))
        {
            /* 修改点1:用strchr函数替代循环搜索,优化了运行速度 */
            if(strchr(b,a[i])==NULL)
            {
                b[j]=a[i];
                j++;
            }
        }
    /* 修改点2:用sort函数替代冒泡排序,优化了运行速度 */
    sort(b,b+j);
    b[j]='\0';
    return j;
}
 
void fillvalue(char a[],char varchar[],int nvar,char valchar[],char resultchar[])
{
    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]=valchar[j];
                break;
            }
}
 
/* 修改点3:重复代码编写成函数,减少代码量 */
void eraser(int r,int &i,int &j,char a[],int w)
{
    if(r==1)
    {
        j++;
        while(a[j+w]!='\0')
        {
            a[j]=a[j+w];
            j++;
        }
        a[j]='\0';
    }
    else
        i++;
}
 
void negatecal(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;
        }
        eraser(_result,i,j,a,1);
    }
}
 
void bracket(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;
        }
        eraser(_result,i,j,a,2);
    }
}
 
void con(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;
        }
        eraser(_result,i,j,a,2);
    }
}
 
void bicond(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]=='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;
        }
        eraser(_result,i,j,a,2);
    }
}
 
void cond(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;
        }
        eraser(_result,i,j,a,2);
    }
}
 
void disconj(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;
        }
        eraser(_result,i,j,a,2);
    }
}
 
/* 修改点4:标准化输入,避免输入格式错误 */
void getformula(char a[])
{
    char cc;
    int cnt=0;
    while((cc=getchar())!='\n')
        if((cc>='a'&&cc<='z')||(cc>='A'&&cc<='Z')||cc=='='||cc=='-'||
           cc=='+'||cc=='*'||cc=='!'||cc=='0'||cc=='1'||cc=='('||cc==')')
            a[cnt++]=cc;
}
 
int main()
{
    /* 修改点5:持续化输入,方便使用 */
    while(1)
    {
        char pstate[120]={' '},pstate0[120]={' '},charlist[120]={' '},charval[120]={' '};
        char minitem[1024][52]={' '},maxitem[1024][52]={' '},truetable[1024]={' '};
        int i=0,nold=0,nnew=0,nvar=1,nrow=1,j=0,flagsum=1,iminitem=0,imaxitem=0;
        printf("请输入公式(析+,合*,条-,双=,否定!,01):\n");
        //gets(pstate0);
        getformula(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';
            /* 修改点6:用位运算加速乘法,优化了运行速度 */
            nrow<<=1;
        }
        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");
 
        int sum=1;
        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);
                bracket(pstate);
                con(pstate);
                bicond(pstate);
                cond(pstate);
                disconj(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++;
                }
                else if(pstate[0]=='0')
                {
                    for(j=0;j<nvar;++j)
                        maxitem[imaxitem][j]=charval[j];
                    maxitem[imaxitem][j]='\0';
                    imaxitem++;
                }
                truetable[i]=pstate[0];
            }
 
            printf("%20c%s",' ',pstate);
            printf("\n");
            /* 修改点7:优化为变元赋值的逻辑,优化了运行速度 */
            int tmp=sum;
            for(int j=nvar-1;j>=0;--j)
            {
                charval[j]=(tmp%2+'0');
                tmp/=2;
            }
            sum++;
        }
        printf("\n");
 
        printf("主析取范式:\n");
        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(")");
            }
        printf("\n\n");
 
        /* 修改点8:添加主合取范式的输出,丰富了功能 */
        printf("主合取范式:\n");
        for(i=0;i<imaxitem;++i)
            if(i==0)
                printf("M%s",maxitem[i]);
            else
                printf("*M%s",maxitem[i]);
        printf("\n");
        for(i=0;i<imaxitem;++i)
            if(i==0)
            {
                printf("(");
                for(j=0;j<nvar;++j)
                {
                    if(j==0)
                        if(maxitem[i][j]=='0')
                            printf("%c",charlist[j]);
                        else
                            printf("!%c",charlist[j]);
                    else
                        if(maxitem[i][j]=='0')
                            printf("+%c",charlist[j]);
                        else
                            printf("+!%c",charlist[j]);
                }
                printf(")");
            }
            else
            {
                printf("*(");
                for(j=0;j<nvar;++j)
                {
                    if(j==0)
                        if(maxitem[i][j]=='0')
                            printf("%c",charlist[j]);
                        else
                            printf("!%c",charlist[j]);
                    else
                        if(maxitem[i][j]=='0')
                            printf("+%c",charlist[j]);
                        else
                            printf("+!%c",charlist[j]);
                }
                printf(")");
            }
        printf("\n\n");
    }
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_39480177/article/details/129428800
今日推荐