这是离散数学中很简单的一个实验,只需要对输入的公式判断是否合法就可以了,首先给出一个比较复杂的代码。
#include"stdio.h"
#include"string.h"
void rule1(char a[],int i)
{
if((a[i]>='a')&&(a[i]<='z'))
{
a[i]='1';
}
else if(a[i]=='0')
{
a[i]='1';
}
}
int rule2(char a[],int i)
{
int n=strlen(a);
int _result=0;
if((i+1<n)&&(a[i]=='!')&&(a[i+1]=='1'))
{
a[i]='1';
i++;
while(a[i+1]!='\0')
{
a[i]=a[i+1];
i++;
}
a[i]='\0';
_result=1;
}
else if((i+2<n)&&(a[i]=='(')&&(a[i+1]=='1')&&(a[i+2]==')'))
{
a[i]='1';
i++;
while(a[i+2]!='\0')
{
a[i]=a[i+2];
i++;
}
a[i]='\0';
_result=1;
}
return _result;
}
int rule3Con(char a[],int i)
{
int _result=0;
int n=strlen(a);
if((i+2<n)&&(a[i]=='1')&&(a[i+1]=='*')&&(a[i+2]=='1'))
{
a[i]='1';
i++;
while(a[i+2]!='\0')
{
a[i]=a[i+2];
i++;
}
a[i]='\0';
_result=1;
}
return _result;
}
int rule3BiCond(char a[],int i)
{
int _result=0;
int n=strlen(a);
if((i+2<n)&&(a[i]=='1')&&(a[i+1]=='=')&&(a[i+2]=='1'))
{
a[i]='1';
i++;
while(a[i+2]!='\0')
{
a[i]=a[i+2];
i++;
}
a[i]='\0';
_result=1;
}
return _result;
}
int rule3Cond(char a[],int i)
{
int _result=0;
int n=strlen(a);
if((i+2<n)&&(a[i]=='1')&&(a[i+1]=='-')&&(a[i+2]=='1'))
{
a[i]='1';
i++;
while(a[i+2]!='\0')
{
a[i]=a[i+2];
i++;
}
a[i]='\0';
_result=1;
}
return _result;
}
int rule3DisConj(char a[],int i)
{
int _result=0;
int n=strlen(a);
if((i+2<n)&&(a[i]=='1')&&(a[i+1]=='+')&&(a[i+2]=='1'))
{
a[i]='1';
i++;
while(a[i+2]!='\0')
{
a[i]=a[i+2];
i++;
}
a[i]='\0';
_result=1;
}
return _result;
}
void rule3(char a[],int i)
{
int n=strlen(a);
if((i+2<n)&&(a[i]=='1')&&((a[i+1]=='+')||(a[i+1]=='*')||(a[i+1]=='-')||(a[i+1]=='='))&&(a[i+2]=='1'))
{
a[i]='1';
i++;
while(a[i+2]!='0')
{
a[i]=a[i+2];
i++;
}
a[i]='\0';
}
}
int main(int argc,char* argv[])
{
char pstate[120],pstate0[120];
int i=0,nold=0,nnew=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';
i=0;
while(i<strlen(pstate))
{
rule1(pstate,i);
i++;
}
printf("规则1后:%s\n",pstate);
nold=strlen(pstate0)+1;
nnew=strlen(pstate);
while(nnew<nold)
{
nold=strlen(pstate);
i=0;
while(i<strlen(pstate))
{
if(rule2(pstate,i)==0);
{
i++;
}
}
printf("规则2后:%s\n",pstate);
i=0;
while(i<strlen(pstate))
{
if(rule3Con(pstate,i)==0)
{
i++;
}
}
printf("规则3合取后:%s\n",pstate);
i=0;
while(i<strlen(pstate))
{
if(rule3BiCond(pstate,i)==0)
{
i++;
}
}
printf("规则3双条件后:%s\n",pstate);
i=0;
while(i<strlen(pstate))
{
if(rule3Cond(pstate,i)==0)
{
i++;
}
}
printf("规则3单条件后:%s\n",pstate);
i=0;
while(i<strlen(pstate))
{
if(rule3DisConj(pstate,i)==0)
{
i++;
}
}
printf("规则3析取后:%s\n",pstate);
nnew=strlen(pstate);
}
if((pstate[0]=='1')&&(strlen(pstate)==1))
{
printf("%s is valid\n",pstate0);
}
else
{
printf("%s is invalid\n",pstate0);
}
return 0;
}
上面的代码比较复杂,但总体来说是层次是比较分明的,基本一个函数对应于一个功能,其实利用库函数,我们可以很容易的解决这个问题。
我们对以上代码进行简化:
- 合并处理条件,简化代码
- 利用find函数,简化1±*=1处理
- 利用replace函数实现消“1”
30行代码解决,简直不要太简单了!!!!!!
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
string a ,b;
cin>>a;
b=a;
int n=a.length();
for(int i=0;i<n;i++)
{
if(a[i]>='a'&&a[i]<='z')a[i]='1';
if(a[i]=='-'||a[i]=='*'||a[i]=='=')a[i]='+';
}
int m=0;
while(a.find("!1")!=string::npos||a.find("1+1")!=string::npos||a.find("(1)")!=string::npos||a.find("(0)")!=string::npos)
{
if(a.find("!1")!=string::npos)
a=a.replace(a.find("!1"),2,"1");
if(a.find("1+1")!=string::npos)
a = a.replace(a.find("1+1"),3 , "1");
if(a.find("(1)")!=string::npos)
a = a.replace(a.find("(1)"),3 , "1");
if(a.find("(0)")!=string::npos)
a = a.replace(a.find("(0)"),3 , "1");
n=a.length();
}
if(n==1)cout<<b<<" is valid";
else cout<<b<<" is invalid";
}
改进之后的代码,能够很好的处理多重“!”和“()”的问题,最前面的复杂代码好像是不支持的(太久远忘记了)