离散数学——判断公式是否合法

这是离散数学中很简单的一个实验,只需要对输入的公式判断是否合法就可以了,首先给出一个比较复杂的代码。

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

改进之后的代码,能够很好的处理多重“!”和“()”的问题,最前面的复杂代码好像是不支持的(太久远忘记了)

你可能感兴趣的:(离散数学,实验)