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

📄 indatt.cpp

📁 某个实验事编写粗糙集智能信息处理的程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "../RSet.h"

#include "indatt.h"
#include "stdio.h"
#include "stdlib.h"//function atoi();
#include "string.h"

#define MAX 10000
//#define max1 10000
/////////////////////
// IndAttRed class //
/////////////////////
 
IndAttRed::IndAttRed()
{
	pFileName=NULL;        //待处理的文件名
	pIntTable=NULL;        //原始表,为int类型,中间对象,转化为info表,最后处理用到
	pInfo=NULL;            //原始表,已转化为int,处理中主要对象,约简对象
	cStyle=NULL;           //数据集基本类型
	pAttName=NULL;         //属性名称(安列分)
	pDataType=NULL;        //数据类型(安列分)
	struWCutRecord=NULL;   //断点链表
	pCoreCD=NULL;		   //C的D核
	pmRedCD=NULL;					//最小属性集合,也是所求结果
	pnegCoreCD=NULL;                //最小属性集合的补集
	pPosCD=NULL;				   //Posc(D)
	pDemSet=NULL;					//pCoreCD的幂集
	max2=MAX;
}

IndAttRed::~IndAttRed()
{
	FreeContent();

}
////////////////////////////////////////////////////////
//the implementation of the  public methods
/////////////////////////////////////////////////////////
bool IndAttRed::GetInfo(char* FileName)//get the privilege pInformation from the file given.
{              //从文件中得到数据,得到int型表
	FILE* fp;
	//return when fail to read the file
	if((fp = fopen(FileName,"r")) == NULL)
	{
       AfxMessageBox("Can't open the file!");
	   return false; 
	}
	cStyle= new char[20];
	fscanf(fp,"Style:%s\n",cStyle);
	fscanf(fp,"Stage:%d\n",&iStage);
	fscanf(fp,"Condition attributes number:%d\n",&iConNum);
	fscanf(fp,"Records number:%d\n",&iRecNum);
	ipriRecNum=iRecNum;
	SetAttName(fp,iConNum+1);
	SetDataType(fp,iConNum+1);
	SetIntegerTable(fp,iConNum+1,iRecNum);//fill the integertable
	SetCutResult(fp);
	fclose(fp);
	return true;
}

bool IndAttRed::InitTable()//初始化决策表,得到int类型的表
{
	int i,j;
	if((pInfo=new int *[iRecNum])==0)
		return false;
	for (i=0;i<iRecNum;i++)
		if((pInfo[i]=new int [iConNum+1])==0)
		{
	    	AfxMessageBox("内存不足!");
		    return false;
		}
	for (i=0;i<iRecNum;i++)
	{
		for (j=0;j<iConNum+1;j++)
		{
			pInfo[i][j]=pIntTable[i][j];  
		}
	}
	return true;
}

bool IndAttRed::DelOverlap()//删除重复的记录
{
	int i,j,k,t;           //循环变量
	int ** pInfoset;        //删除重复记录后的信息表
	int new_iRecNum=0;     //新信息表中的记录数
	int sum=0;             //统计属性值相同的个数
	bool find=false;
   	int * same_rec;
	if((same_rec=new int[iRecNum])==0)
	{
		AfxMessageBox("内存不足!");
		return false;
	}
	int same_num=0;
	//把重复记录编号存在same_rec中,same_num中为重复记录数目
	for(i=0;i<iRecNum-1;i++)
		for(j=i+1;j<iRecNum;j++)
		{
			//比较两条记录是否完全相等
			for(k=0;k<iConNum+1;k++)
				if(pInfo[i][k]==pInfo[j][k])
					sum++;
				else
					break;
			//表示完全相等
			if(sum==(iConNum+1))
			{
				for(t=0;t<same_num;t++)
                    //如果记录中有i,说明第j条记录已存在same_rec中了
					if(same_rec[t]==i)
					{
					    find=true;
					    break;
					}
				if(find==false)
			    	same_rec[same_num++]=j;//编号加入重复记录数组
			}
			find=false;
			sum=0;
		}
	if(same_num>0)//如果有重复记录
	{
    	//为新表分配空间
		if((pInfoset=new int * [iRecNum-same_num])==0)
		{
		  AfxMessageBox("内存不足!");
		  return false;
		}
		for(i=0;i<(iRecNum-same_num);i++)
		{
			if((pInfoset[i]=new int[iConNum+1])==0)
			{
	        	AfxMessageBox("内存不足!");
		        return false;
			}
		}
    	for(i=0;i<iRecNum;i++)
		{
	    	for(j=0;j<same_num;j++)
	    		if(i==same_rec[j])
	     			break;
	    		else
		    		sum++;
	    	if(sum==same_num)//说明第i条记录不在same_rec中
			{
		        for(j=0;j<iConNum+1;j++)
				{//new_iRecNum为新信息表中的记录数 拷贝所有属性
					pInfoset[new_iRecNum][j]=pInfo[i][j];
				}
				new_iRecNum++;
			}
	    	sum=0;
		}
		for(i=0;i<iRecNum;i++)
			delete []pInfo[i];
    	delete []pInfo;
		pInfo=pInfoset;//重新初始化
		iRecNum-=same_num;//得到的不重复的新的记录数
	}
	delete []same_rec;
	return true;
}

bool IndAttRed::SetIntegerTable(FILE* fp,int column, int row)
{
	int i,j;
	char* string=new char[MAX];
	if((pIntTable = new int*[row])==0)
		return false;
	for(i = 0;i<row;i++)
	{
		if((pIntTable[i] = new int[column])==0)
			return false;
	}//end for
	for(i=0;i<row;i++)
	{
		for(j=0;j<column;j++)
		{
			fscanf(fp,"%s",string);
			if(strcmp(string,"-") == 0)
				pIntTable[i][j] = -1;
			else
				pIntTable[i][j] = atoi(string);
		}//end for
	}//end for
	delete []string;
	return true;
}

bool IndAttRed::SetCutResult(FILE* fp)
{
	int n;
	int iColumn;
	int iCuts;
	struct WCutRecord* pHead = NULL;
	struct WCutRecord* pEnd = NULL;
	
	char* temp = new char[MAX];
	if(fscanf(fp,"%s",temp) == -1)
	{
		delete[] temp;
		return false;
	}
	if(strcmp(temp,"[Cuts]") != 0)
	{
		delete[] temp;
		return false;
	}
     //	bCuts = true;
	while(fscanf(fp,"%d",&iColumn) != -1)
	{
		fscanf(fp,"%d",&iCuts);
		pEnd = new WCutRecord;
		if((pEnd->cpCut=new char*[iCuts])==0)
			return false;
		for(int i=0;i<iCuts;i++)
		{
			if((pEnd->cpCut[i] = new char[MAX])==0)
				return false;
		}//end for
		pEnd->iColumn=iColumn;
		pEnd->iCuts=iCuts;
		pEnd->next=NULL;
		for(i=0;i<iCuts;i++)
		{
			fscanf(fp,"%s",temp);//断点区间
			fscanf(fp,"%d",&n);//断点号
			strcpy(pEnd->cpCut[n],temp);//拷贝断点区间
		}//end for
		if(pHead == NULL)
		{
			struWCutRecord = pEnd;
			pHead = pEnd;
		}//end if
		else
		{
			pHead->next = pEnd;
			pHead = pEnd;
		}//end else
	}//end while

	delete[] temp;
	return true;
}

bool IndAttRed::SetAttName(FILE* fp, int count)
{
	int i;
	if((pAttName = new char*[count])==0)
		return false;
	for(i=0;i < count;i++)
	{
		if((pAttName[i]=new char[MAX])==0)
			return false;
	}//end for
	for(i=0;i < count;i++)
		fscanf(fp,"%s",pAttName[i]);
	return true;
}

bool IndAttRed::SetDataType(FILE *fp, int count)
{
	int i;
	if((pDataType = new char*[count])==0)
		return false;
	for(i = 0;i < count;i++)
	{
		if((pDataType[i]=new char[MAX])==0)
			return false;
	}//end for
	for(i = 0;i < count;i++)
		fscanf(fp,"%s",pDataType[i]);
	return true;
}

bool IndAttRed::SaveFile(char *pFileName)
{
    int *a;
	if((a=new int[iConNum])==0)
		return false;
	int i,j,t,k,m=0,n;
	FILE* fp;
    int iConNum1=pmRedCD->PosNum;
//	if(nSelected == -1)
//		return false;
	if((fp = fopen(pFileName,"w")) == NULL)
	{
        AfxMessageBox("Can not open file for writing!");
		return false;
	}//end if
 	fprintf(fp,"Style:%s\n",cStyle);
	fprintf(fp,"Stage:%d\n",3);//3 stands for 属性约简结果
	fprintf(fp,"Condition attributes number:%d\n",iConNum1);
    for(i = 0;i < iConNum;i++)
	{
	        t=0;
			for(k=0;k<pmRedCD->PosNum;k++)
			{
				if(pmRedCD->PosSet[k] == i) 
				{
					t=1;
			    	break;
				}
			}
			if(t!=1)//删除了的属性,记录位置
	          a[m++]=i;
	}
    fprintf(fp,"The Number of Condition attributes deleted:%d\n",m);
    fprintf(fp,"The position of Condition attributes deleted:");
    if(m>0)
      for(i=0;i<m;i++)
	    fprintf(fp," %d",a[i]);
    fprintf(fp,"\n");
	fprintf(fp,"Records number:%d\n",ipriRecNum);
	for(i = 0;i < iConNum;i++)
	{
		    t=0;
			for(k=0;k<pmRedCD->PosNum;k++)
			{
				if(pmRedCD->PosSet[k] == i) 
				{
					t=1;
			    	break;
				}
			}
			if(t==1)//是约简结果,输出
	           fprintf(fp,"%s ",pAttName[i]);
	}
	fprintf(fp,"%s ",pAttName[iConNum]);//决策的名字
    fprintf(fp,"\n");
 	for(i = 0;i < iConNum;i++)
	{
    		t=0;
			for(k=0;k<pmRedCD->PosNum;k++)
			{
				if(pmRedCD->PosSet[k] == i) 
				{
					t=1;
			    	break;
				}
			}
			if(t==1)//是约简结果,输出
	         fprintf(fp,"%s ",pDataType[i]);
	}
    fprintf(fp,"%s ",pDataType[iConNum]);//决策的数据类型
	fprintf(fp,"\n");
	for(i=0;i<ipriRecNum;i++)//行
	{
		for(j=0;j<iConNum;j++)//列
		{
			t=0;
			for(k=0;k<pmRedCD->PosNum;k++)
			{
				if(pmRedCD->PosSet[k] == j) 
				{
				   	t=1;
				     break;
				}
			}
			if(t==1)//是核,打印
				fprintf(fp,"%d ",pIntTable[i][j]);
     		//	else//or press '-'
				//fprintf(fp,"%c ",'-');
		}
		fprintf(fp,"%d ",pIntTable[i][iConNum]);//决策属性单独处理
		fprintf(fp,"\n");
	}
	if(struWCutRecord == NULL)//没有断点
	{
		fclose(fp);
		return true;
	}

	struct WCutRecord* temp = struWCutRecord;
	n=0;
	fprintf(fp,"[Cuts]\n");
	while(temp != NULL)
	{
		bool flag=true;
		for(i=0;i<m;i++)
			if (a[i]==temp->iColumn)
			{
				flag=false;
	             n++;//表示中间空缺的属性数目
				break;
			}
		if(flag)
		{
		   	fprintf(fp,"%d\n",(temp->iColumn)-n);
	    	fprintf(fp,"%d\n",temp->iCuts);
		    for(i = 0;i < temp->iCuts;i++)
			{
			fprintf(fp,"%s ",temp->cpCut[i]);
			fprintf(fp,"%d\n",i);
			}
		}
		temp = temp->next;
	}
	fclose(fp);
	delete []a;
    return true;
}

//首先求U|ind(X),再求U|D,然后求Pos(X)D
bool IndAttRed::PosXD(int XNum,int* XSet,PosD* &PosXD)
{//PosXD->PosNum表示正域中元素的个数
	if(XNum==0)
	{
	    PosXD->PosNum=0;
		return true;
	}
	PosXD->PosNum=0;
	int iClassNumD=0;//决策D的分类数目
	int DNum=1;
	int *DSet=new int[1];
	DSet[0]=iConNum;//决策属性位置。表示用决策来分类
	int **UindD;
	if((UindD=new int*[iRecNum])==0)//记录数,约简对象
		return false;              
	for(int j=0;j<iRecNum;j++)
		if((UindD[j]=new int[iRecNum+1])==0)
			return false;
	//call UindX()//求U|D,结果放在iClassNumD,UindD 中
	UindX(DNum,DSet,iClassNumD,UindD);
	delete []DSet;
	int iClassNumX=0;
	int **pUindX;
	if((pUindX=new int*[iRecNum])==0)
		return false;
	for(j=0;j<iRecNum;j++)
		if((pUindX[j]=new int[iRecNum+1])==0)
			return false;
	//call UindX()	//求U|ind(X),结果放在iClassNumX,pUindX中
	UindX(XNum,XSet,iClassNumX,pUindX);
	//求pos(x)D
	//就是包含在u|d中的uindX的并集
	//简化算法,如果uindx的某一类的元素全在U\D的同一类中,那么就是
	for(int i=0;i<iClassNumX;i++)//对uindx中的每一类

⌨️ 快捷键说明

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