這是離散數學中很簡單的一個實驗,只需要對輸入的公式判斷是否合法就可以了,首先給出一個比較複雜的代碼。
#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";
}
改進之後的代碼,能夠很好的處理多重“!”和“()”的問題,最前面的複雜代碼好像是不支持的(太久遠忘記了)