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

📄 ccj2.cpp

📁 该系统实现粗糙集合中的分辨矩阵与分辨函数的约简方法
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <string>#include <fstream>#include <iostream>using namespace std;const int H=15;//定义二维数组,用于存放决策表Sconst int L=15;void main(){	int row=0,len=0;//用于存放读入文件中数据的行数和列数	int hang,lie,i;	char chr;	string juecebiao[H][L];//定义一个二维的决策表S	string juecebiao_bak[H][L];//定义一个二维的决策表S备份	string str,core,fbfun="";//fbfun用于存放分辨函数,core为核	void fenbian(int hs,string table[][L],int hsh,int lsh,string &fun);//申明分辨函数	void yuejian(int m,string core,string &fun);//申明约简函数	void delrongyu(string &fun);//申明消除冗余函数	void yuejiantable(string strs,string juece[][L],string juecetable[][L],int lieshu,int hangshu);	//申明构建约简后的表S',并推导出规则式	ifstream infile("juece.txt");//打开输入文本文件	ifstream infile2("juece.txt");	infile>>noskipws;//不忽略空白,把每行最后那个'\n'也读进来	if(!infile)//文件打开出错检查	{		cout<<"open file error!"<<endl;		exit(0);//出错退出	}    while(infile>>chr)		//将输入文件读入到决策表S中,判断该表的行数和列数		//文件中每列数据以逗号分隔开	{		switch(chr)		{		case '\n'://判断读入字符是否为换行符			++row;//是换行符则行数+1			len=0;//是换行符则列数清零			break;		case ','://判断读入字符是否为逗号			++len;//则列数+1			break;		default:;		}	}//判断完毕	infile.close();//关闭文本文件	row++;len++;//row,len中保存的值为从外部文件导入的决策表的行数和列数	if(!infile2)//文件打开出错检查	{		cout<<"open file error!"<<endl;		exit(0);//出错退出	}	hang=0;lie=0;//行、列赋值为1。0行、0列存储其他值用	while(hang<row)//循环比较,以行数作为限制	{			while(lie<len-1)		{			getline(infile2,str,',');//以逗号为分隔对象,进行数据读入			juecebiao[hang][lie]=str;//将逗号前的数据保存到相应的字符串数组中			lie++;//保存好数据后列数+1		}		getline(infile2,str,'\n');//将回车符作为对象进行数据输入,以判断一行是否结束		juecebiao[hang][lie]=str;//将回车符前面的数据读入到相应的字符串数组中		lie=0;//列数赋值为1,准备下一行的判断		hang++;//行数+1	}	infile2.close();	for(hang=0;hang<row;hang++)//由于决策表S后面有变动,所以先予以保存在juecebiao_bak中		for(lie=0;lie<len;lie++)			juecebiao_bak[hang][lie]=juecebiao[hang][lie];	cout<<"引入的决策表为:\n";	cout<<"-------------------------------------------------------------------------------\n";	for (lie=0;lie<len;lie++)		cout<<juecebiao[0][lie]<<"\t";	cout<<"\n-------------------------------------------------------------------------------\n";	for (hang=1;hang<row;hang++)	{		for (lie=0;lie<len;lie++)			cout<<juecebiao[hang][lie]<<"\t";		cout<<"\n";	}	cout<<"-------------------------------------------------------------------------------\n\n";	juecebiao[0][0]="U";//为方便运算,将属性列的值改变成a,b,c……等简单字母表示	chr='a';	for(i=1;i<len;i++)	{		juecebiao[0][i]=chr;		chr+=1;	}	chr='1';	for(i=1;i<row;i++)	{		juecebiao[i][0]="U";		juecebiao[i][0]+=chr;		chr+=1;	}	cout<<"生成的分辨矩阵为:\n-------------------------------------------------------------------------------\n ";	for (lie=1;lie<row;lie++)	{		cout<<"\t"<<juecebiao[lie][0];	}	cout<<"\n-------------------------------------------------------------------------------\n";	for (hang=1;hang<row;hang++)	{		cout<<juecebiao[hang][0];		fenbian(hang,juecebiao,row,len,fbfun);//调用分辨矩阵函数,显示构造分辨矩阵的一行元素		cout<<"\n";	}	cout<<"-------------------------------------------------------------------------------\n";	cout<<"\n对应的分辨函数为:\n";	cout<<"△="<<fbfun<<endl;//输出显示分辨函数P	for(lie=0;lie<fbfun.length();lie++)//寻找单独的一个元素,此元素为核。		//也可以先求约简,再求约简的交集,其元素也为核	{		if(fbfun[lie]!=')')//先寻找右括号			continue;		if(fbfun[lie-2]=='(')//判断右括号前二个元素是否为左括号,是则表示两括号间只有一个元素			core+=fbfun[lie-1];//把此元素存放到core中保存	}//求核完毕			for(i=0;i<core.length();i++)//将核元素依次传个约简函数,依次进行约简		yuejian(i,core,fbfun);//调用约简函数,将核元素、分辨函数作为参数传递过去得到约简后的函数	delrongyu(fbfun);//调用消除冗余函数,将上步得到的函数消去冗余值	cout<<"="<<fbfun;	cout<<"\n\n所以该表达式的约简为:";	str="";	for(i=0;i<fbfun.length();i++)//显示根据分辨函数运算得来的几个约简	{		while(fbfun[i]>='A'&&fbfun[i]<='z'&&i<fbfun.length())		{						str+=fbfun[i];			i++;			continue;		}		str="{"+str+"} ";		i++;		cout<<str;		str="";	}	cout<<endl;	cout<<"\n约简的核为:"<<core<<"\n";	for(i=0;i<len;i++)		juecebiao[i][0]=juecebiao[0][i];//将决策表S的属性列存放到表S的0列,以备后用	i=0;	while(i<=fbfun.length())//将计算后得到的最终分辨函数,依次取其中的析取项,传入约简函数		//为和决策属性一起,求出规则	{				if(fbfun[i]>='A'&&fbfun[i]<='z')		{						str+=fbfun[i];			i++;			continue;		}		else		{			yuejiantable(str,juecebiao,juecebiao_bak,len,row);//取析取式中每组元素,调用构造约简表函数			str="";			i+=2;//跳过析取符号			continue;		}	}	cout<<"-------------------------------------------------------------------------------\n";	cout<<"规则式已输出到文本文件result.txt中\n\n";}void fenbian(int hs,string table[][L],int hsh,int lsh,string &fun)//定义分辨矩阵,并输出显示分辨函数{	int m,flag,hangs;//flag是判断是否有左括号的标志位	string str;	for(m=1;m<=hs;m++)//分辨矩阵是对称矩阵,本程序显示上三角部分,下三角部分以制表符跳过		cout<<"\t";	cout<<"\t";//a∈C:f(xi,a)=f(xj,a)时a=Ф。所以对角线上的元素为空,以制表符跳过	hangs=hs+1;//比较(xi,a)与(xj,b),i<j<n	//从该行开始与其下方各行元素比较,上方元素因为对称性不用再作比较。所以hangs初始化为hs+1	while(hangs<hsh)	{		flag=0;//初始化标志位,0为无,1为有		str="";//将接收缓冲区清空,以便下面程序能够分辨出每组元素是否为空。为空则不输出显示括号		for(m=1;m<lsh-1;m++)//此时m为属性列计数,不用比较决策属性		{			if((table[hs][m]==table[hangs][m])||(table[hs][lsh-1]==table[hangs][lsh-1]))				continue;////a∈C:f(xi,a)≠f(xj,a) 当f(xi,D)≠f(xj,D)时,否则为空			str=table[0][m];//将该列属性元素存入str中			cout<<str;			if(str!=""&&flag==0)//当缓冲区里有接收到的属性值,并且已经有左括号了,则执行			{				if(fun[fun.length()-1]==')')//在准备输出显示左括号前先判断前一个字符是否为右括号					fun+="∧";//是有括号,则输出显示合取符号				fun+="(";//将左括号添加到分辨函数中				flag=1;//当输出显示左括号时,将flag标志位置1,表示已有左括号了			}			if(fun[fun.length()-1]!='(')//若前面一个字符不是左括号,则一定是属性值,则输出显示析取符号				fun+="∨";			fun+=str;//将得到的属性值添加到分辨函数中		}		hangs++;//行数+1,进行下一行的比较		if(flag==1)//判断是否有坐括号			fun+=")";//有左括号则将右括号添加到分辨函数中		cout<<"\t";	}}//构造完毕void yuejian(int m,string he,string &fun)//定义约简函数,对分辨函数进行约简{	int lkuohao=0,rkuohao=0,n,p;//lkuohao,rkuohao为左、右括号标志符	string str="",str2="";//str用来保存每组元素,str2用来保存比较后的元素	for(n=0;n<fun.length();)//对分辨函数进行一次从左到右的筛选,去处与核交集≠Ф的每组元素		//约简原则:根据吸收律,P∨(P∧Q)<=>P,P为核	{		if(fun[n]=='(')//以左括号为判断每组元素开始的标记		{			lkuohao=n;//将左括号的下标保存下来,与后面右括号下标一起构成括号内元素取得的标志			n++;//进行下一个元素的比较			continue;		}		if(fun[n]==')')//遇到右括号,则表示一组元素已经取得		{			rkuohao=n;//将右括号的下标保存下来			for(p=0;p<str.length();)//对此组元素依次进行比较,是否与核相同			{				if(str.length()==1)//若取得元素长度为1,则为核。不比较,保存下来

⌨️ 快捷键说明

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