主要完成真值表的自动生成:
1. 自动生成真值表
2. 生成主合取范式
给出两个版本,先给一个简单的,怕大家看完都不想往下看了,简单版本的,只需要100多行代码!!!!(好像也不少),但是比第二个版本增加了生成主合取范式的功能,主要是利用了库函数,所以比较简单:
#include
#include
#include
#include
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
#include
#include
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++)