⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 动物识别专家系统.cpp

📁 该程序可以识别动物,就是你输入动物的特征可以辨别什么动物
💻 CPP
字号:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//事实链表的结构描述
struct CAUSE_TYPE
{
	char *cause;
	struct CAUSE_TYPE *next;
};

struct RULE_TYPE
{
	char *result;
	int lastflag;
	struct CAUSE_TYPE *cause_chain;
	struct RULE_TYPE *next;
};


struct CAUSE_TYPE *DataBase;//已知事实链表头指针
struct CAUSE_TYPE *Conclusion;//结论链表头指针
struct RULE_TYPE *KnowledgeBase;//知识库规则链表头指针 
struct RULE_TYPE *Used;//已使用规则链表头指针 

void freeKB(struct RULE_TYPE *);
void freeDB(struct CAUSE_TYPE *);
int FindCause(char *);
void markKB();
void creatKB();
void inputDB();
void think();
void explain();
void copyKB(struct RULE_TYPE *rp,struct RULE_TYPE *KB);


//主函数
void main()
{
	printf("请用正确的命令操作:\n");
	printf("\t\t创建知识库:    create\n");
	printf("\t\t输入已知事实:  input\n");
	printf("\t\t进行推理:      think\n");
	printf("\t\t解释:          explain\n");
	printf("\t\t退出:          exit\n");
	
	char ch[10];
	gets(ch);
	while(1)
	{
		
		if(strcmp("exit",ch)==0)
			{
				//if(KnowledgeBase)	freeKB(KnowledgeBase);
				//if(Used)			freeKB(Used);
				//if(DataBase)		freeDB(DataBase);
				//if(Conclusion)		freeDB(Conclusion);
				printf("已正常退出!!!\n");
				return;
			}
		if(strcmp("create",ch)==0)
			{
				if(KnowledgeBase)
					{printf("知识库已创建!\n");}
				else
					{
						creatKB();	printf("知识库已创建!\n");
						RULE_TYPE *rp;
						for(rp=KnowledgeBase;rp;rp=rp->next)
							{printf("%s\n",rp->result);}
					}
				RULE_TYPE *rp1=NULL,*rp2=NULL;
				copyKB(rp1,KnowledgeBase);
				for(rp2=KnowledgeBase;rp2;rp2=rp2->next)
						{printf("%s",rp2->result);printf("\n");}

			}

		else if(strcmp("input",ch)==0)
			inputDB();
		else if(strcmp("think",ch)==0)
			{	
				think();
				RULE_TYPE *rp;
				for(rp=KnowledgeBase;rp;rp=rp->next)
					{printf("%s\n",rp->result);}
			}
		else if(strcmp("explain",ch)==0)
			explain();
		else
		{
			printf("请选择正确的命令:\n");
			printf("\t\t创建知识库:    create\n");
			printf("\t\t输入已知事实:  input\n");
			printf("\t\t进行推理:      think\n");
			printf("\t\t解释:          explain\n");
			printf("\t\t退出:          exit\n");
		}
		gets(ch);
	}
}

//释放事实链表子程序
void freeDB(struct CAUSE_TYPE *cPoint)
{
	struct CAUSE_TYPE *cp;
	while(cPoint)
	{
		cp=cPoint->next;
		free(cPoint->cause);
		cPoint->cause=NULL;
		cPoint->next=NULL;
		free(cPoint);
		cPoint=cp;
	}
}

//释放规则链表子程序
void freeKB(struct RULE_TYPE *rPoint)
{
	struct RULE_TYPE *rp;
	while(rPoint)
	{
		rp=rPoint->next;
		freeDB(rPoint->cause_chain);
		rPoint->cause_chain=NULL;
		free(rPoint->result);
		rPoint->result=NULL;
		rPoint->next=NULL;
		free(rPoint);
		rPoint=rp;
	}
}

//标记结论性规则子程序
void markKB()
{
	struct RULE_TYPE *rp1,*rp2;
	struct CAUSE_TYPE *cp;
	rp1=KnowledgeBase;
	while(rp1)
	{
		cp=rp1->cause_chain;
		rp1->lastflag=1;
		while(cp)
		{
			rp2=KnowledgeBase;
			while(rp2)
			{
				//若该规则的结论是某规则的条件,则将该规则置为非结论规则
				if(strcmp(rp2->result,cp->cause)==0)
					rp2->lastflag=0;
				rp2=rp2->next;
			}
			cp=cp->next;
		}
		rp1=rp1->next;
	}
}



//创建知识库
void creatKB()
{
	//if(KnowledgeBase)
	//	{printf("知识库已创建!\n");return;}
	FILE *fp;
	struct CAUSE_TYPE *cp=NULL;
	struct RULE_TYPE *rp=NULL;
	int i,j;
	char sp[80];
	char ch;
	freeKB(KnowledgeBase);
	freeKB(Used);
	KnowledgeBase=Used=NULL;
	if((fp=fopen("c:\\rule.dat","r"))==NULL)
	{
		printf("\n知识库不存在!\n");
		printf("请输入新的规则,以创建知识库!\n");
		//for输入新知识库规则
		for(i=1;;i++)
		{
			printf("\n*****************第(%d)条规则***********************",i);
			printf("\n**结论:(是/会/有)");
			//输入规则结论
			gets(sp);
			if(*sp=='\0') break;
			rp=(struct RULE_TYPE *)malloc(sizeof(rp));
			rp->result=(char *)malloc(sizeof(sp));
			strcpy(rp->result,sp);
			rp->cause_chain=NULL;
			rp->next=KnowledgeBase;
			KnowledgeBase=rp;
			
			//输入规则的条件
			for(j=1;;j++)
			{
				printf("\n**条件(%d):(是/会/有)",j);
				gets(sp);
				if(*sp=='\0') break;
				cp=(struct CAUSE_TYPE *)malloc(sizeof(cp));
				cp->cause=(char *)malloc(sizeof(sp));
				strcpy(cp->cause,sp);
				cp->next=rp->cause_chain;
				rp->cause_chain=cp;
			}
		}
		if(!KnowledgeBase)
		{
			printf("\n警告!知识库中没有任何规则!!\n");
			return;
		}
		printf("\n需要保存已建立的知识库吗?(Y/N)?");
		while(!strchr("YyNn",ch=getchar()));//?
		if(ch=='Y'||ch=='y')
			if((fp=fopen("C:\\rule.dat","w"))==NULL)
			{
				printf("\n写文件有错误!\n");
				exit(1);
			}
			else
			{
				//保存已建立的知识库
				rp=KnowledgeBase;
				while(rp)
				{
					fputs(rp->result,fp);
					fputc('\n',fp);//"\n"为结论或事实的结束符

					cp=rp->cause_chain;
					while(cp)
					{
						fputs(cp->cause,fp);
						fputc('\n',fp);
						cp=cp->next;
					}
					fputs("\\\n",fp);//"\"是一条规则的结束符
					rp=rp->next;
				}
				fclose(fp);
			}
	}
else
{
	//若知识库文件已存在,则读入所有的规则,建立知识库
	while(!feof(fp))
	{
		fgets(sp,80,fp);
		if(*sp=='\\') break;
		rp=(struct RULE_TYPE *)malloc(sizeof(rp));
		rp->result=(char *)malloc(i=strlen(sp));
		sp[i-1]='\0';
		strcpy(rp->result,sp);
		rp->cause_chain=NULL;
		rp->next=KnowledgeBase;
		KnowledgeBase=rp;

		fgets(sp,80,fp);
		while(*sp!='\\')
		{
			cp=(struct CAUSE_TYPE *)malloc(sizeof(cp));
			cp->cause=(char *)malloc(i=strlen(sp));
			sp[i-1]='\0';
			strcpy(cp->cause,sp);
			cp->next=rp->cause_chain;
			rp->cause_chain=cp;
			fgets(sp,80,fp);
		}
	}
	fclose(fp);
}
//给知识库中的所有结论规则打上标记
markKB();
}



//输入已知条件的子程序
void inputDB()
{
	//if(!KnowledgeBase)
	//	{printf("规则库不存在!!!\n");		return;}
	int i;
	char sp[80];
	struct CAUSE_TYPE *cp;
	//释放条件链表和结论链表
	freeDB(DataBase);
	freeDB(Conclusion);
	DataBase=Conclusion=NULL;
	printf("\n*****请输入已知事实:\n");

	for(i=1;;i++)
	{
		printf("\n**条件(%d):(是/会/有)",i);
		gets(sp);
		if(*sp=='\0') break;
		cp=(struct CAUSE_TYPE *)malloc(sizeof(cp));
		cp->cause=(char *)malloc(sizeof(sp));
		strcpy(cp->cause,sp);
		cp->next=DataBase;
		DataBase=cp;
	}

	//printf("已知事实为:");
	if(DataBase=='\0')
		printf("已知事实为空空空空空!");
	else
	{
		printf("已知事实已读入,可以用think命令推理了!");
		//for(cp=DataBase;cp!='\0';cp=cp->next)
		//	printf("%s	",cp->cause);
	}
	printf("\n");
}


//在条件链表及结论链表中查证字符串sp是否存在,若存在返回1,否则返回0
int FindCause(char *sp)
{
	struct CAUSE_TYPE *cp2;
	cp2=DataBase;
	while(cp2)
		if(strcmp(sp,cp2->cause)==0) return(1);
		else cp2=cp2->next;
	cp2=Conclusion;
	while(cp2)
		if(strcmp(sp,cp2->cause)==0) return(1);
		else cp2=cp2->next;
	return(0);
}


//推理机子程序
void think()
{
	if(!DataBase)
		{printf("没有已知事实!!!\n");		return;}

	struct RULE_TYPE *rp1,*rp2;
	struct CAUSE_TYPE *cp1;
	int RuleCount,i;
	char sp[80];
	//把规则链表和已使用规则链表连接起来
	if(Used)
	{
		//rp1=Used;
		//while(rp1->next) rp1=rp1->next;
		//rp1->next=KnowledgeBase;
		//KnowledgeBase=Used;
		//Used=NULL;

		rp1=KnowledgeBase;
		while(rp1) rp1=rp1->next;
		rp1=Used;
		Used=NULL;
	}

	if(Conclusion)
	{
		freeDB(Conclusion);
		Conclusion=NULL;
	}
	do
	{
		RuleCount=0;
		rp1=KnowledgeBase;
		while(rp1)
		{
			cp1=rp1->cause_chain;
			//取出一条规则的条件部分,检查是不全部为已知
			while(cp1)
				if(FindCause(cp1->cause)==0)//若有条件未知,则跳出该规则
					break;
				else cp1=cp1->next;//若该条件已知,则查找下一条件是否已知
			if(cp1)//若cp1不为空,则该规则的条件不是全部已知,考查下一条规则
			{
				rp2=rp1;
				rp1=rp1->next;
			}
			else if(FindCause(rp1->result)==0)//该规则的条件均满足,且得出的是新事实
			{
				//将新事实保存到conlusion中
				cp1=(struct CAUSE_TYPE *)malloc(sizeof(cp1));
				cp1->cause=(char *)malloc(sizeof(rp1->result));
				strcpy(cp1->cause,rp1->result);
				cp1->next=Conclusion;
				Conclusion=cp1;
				
				//(得出了新结论)将该规则从知识库中取出,插入已使用规则链表
				rp2=rp1->next;
				rp1->next=Used;
				Used=rp1;
				rp1=rp2;
				RuleCount++;
				if(Used->lastflag==1)
				{
					RuleCount=0;
					break;
				}
			}
			else
			{
				rp2=rp1;
				rp1=rp1->next;
			}
		}
	}while(RuleCount>0);     //do while

	if(!Conclusion||Used->lastflag==0)
	{
		printf("\n已知事实不充分!请输入补充事实:\n");
		cp1=DataBase;
		//显示已输入的事实
		for(i=1;cp1;i++)
		{
			printf("\n**条件(%d):(是/会/有)%s",i,cp1->cause);
			cp1=cp1->next;
		}
		//输入补充事实
		for(;;i++)
		{
			printf("\n**条件(%d):(是/会/有)",i);
			gets(sp);
			if(*sp=='\0') break;
			cp1=(struct CAUSE_TYPE *)malloc(sizeof(cp1));
			cp1->cause=(char *)malloc(sizeof(sp));
			strcpy(cp1->cause,sp);
			cp1->next=DataBase;
			DataBase=cp1;
		}
	}
	else printf("\n这个动物:(是/会/有)%s\n",Conclusion->cause);
}



//对推理结果进行解释
void explain()
{
	struct RULE_TYPE *rp;
	struct CAUSE_TYPE *cp;
	int i;

	rp=Used;
	i=0;
	if(rp=='\0') {printf("没有可以解释的!!!\n");	return;}
	while(rp)
	{
		printf("\n*这个动物(是/会/有)%s,因为:\n",rp->result);
		cp=rp->cause_chain;
		while(cp)
		{
			printf("**(%d)--它(是/会/有)%s\n",++i,cp->cause);
			cp=cp->next;
		}
		rp=rp->next;
	}
}



void copyKB(struct RULE_TYPE *rp,struct RULE_TYPE *KB)
{
	struct CAUSE_TYPE *cp,*cp1;
	struct RULE_TYPE *rp1,*rp2,*rp3;
	rp1=KB;
	while(rp1)
	{
		rp2=(struct RULE_TYPE *)malloc(sizeof(rp2));
		rp2->result=(char *)malloc(sizeof(rp1->result));
		strcpy(rp2->result,rp1->result);
		cp=rp1->cause_chain;
		while(cp)
		{
			cp1=(struct CAUSE_TYPE *)malloc(sizeof(cp1));
			cp1->cause=(char *)malloc(sizeof(cp->cause ));
			strcpy(cp1->cause,cp->cause );
			cp=cp->next;
		}
		rp2->lastflag=rp1->lastflag ;
		if(!rp)
			rp=rp2;
		else
			{
				rp3=rp;
				while(rp3->next)
					rp3=rp3->next;
				rp3->next=rp2;
			}
		rp1=rp1->next ;
	}
}
  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -