離散數學——判斷公式是否合法

這是離散數學中很簡單的一個實驗,只需要對輸入的公式判斷是否合法就可以了,首先給出一個比較複雜的代碼。

#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;
}

上面的代碼比較複雜,但總體來說是層次是比較分明的,基本一個函數對應於一個功能,其實利用庫函數,我們可以很容易的解決這個問題。
我們對以上代碼進行簡化:

  1. 合併處理條件,簡化代碼
  2. 利用find函數,簡化1±*=1處理
  3. 利用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";
}

改進之後的代碼,能夠很好的處理多重“!”和“()”的問題,最前面的複雜代碼好像是不支持的(太久遠忘記了)

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