📄 semimini.cpp
字号:
delete []DeciSet;
}
catch(CMemoryException* e)
{
::MessageBeep(MB_ICONHAND);
AfxMessageBox("Out of memory!",MB_OK|MB_ICONSTOP);
e->Delete();
return FALSE;
}
}//end if(num1>0 &&num>0)
num=num1=0;
mid=0;
}//end for(i=0;i<N;i++)
return DiscernValue;
}
void CSemiMini::SelectSort(double * &Mid)
{// 对出现的属性值进行从小到大排序
int i,j;
double mid;
for(i=1;i<(int)Mid[0];i++)
for(j=i+1;j<=(int)Mid[0];j++)
if(Mid[i]>Mid[j])
{
mid=Mid[i];
Mid[i]=Mid[j];
Mid[j]=mid;
}
}
int** CSemiMini::SplitSet(int** &Set, int &N, double cut, int m)
{//X为等价类,N为等价类的个数,cut为所选的断点,m为所选的断点是在哪个条件属性中
//根据断点cut把原来的等价类集合划分成新的等价类集合并返回,新集合的个数保存在N中
//failed:return NULL;
// if(N==634)
// AfxMessageBox("a");
int i,j;
int flag=0;
int flag1=0;
int num=0;
int **Mid=NULL;
int num1;
for(i=0;i<N;i++)
{
for(j=1;j<=Set[i][0];j++)
{
if(pNonStringTable[Set[i][j]][m]>cut)
flag=1;
else if(pNonStringTable[Set[i][j]][m]<cut)
flag1=1;
}
if((flag==1)&&(flag1==1))//说明当前等价类中存在断点两边的值
++num; //统计num:断点把等价类划分为两部分的个数,增加的子集个数
flag=flag1=0;
}
if((Mid=new int *[N+num])==0)
{
AfxMessageBox("分配内存失败!");
return NULL;
}
num=0;
//重新设置等价类
for(i=0;i<N;i++)//对这N个等价类
{
if(i==152 && N==634)
AfxMessageBox("a");
num1=0;
flag=flag1=0;
for(j=1;j<=Set[i][0];j++)
{
if(pNonStringTable[Set[i][j]][m]>cut)
++flag;
else if(pNonStringTable[Set[i][j]][m]<cut)
++flag1;
}
if(num==152)
int kkkkk=0;
if((flag!=0)&&(flag1!=0)) //表明断点能把等价类划分为两部分
{
Mid[num]=NULL;
if((Mid[num]=new int[flag1+1])==0)
{
AfxMessageBox("分配内存失败!");
return NULL;
}
for(j=1;j<=Set[i][0];j++)
{
if(pNonStringTable[Set[i][j]][m]<cut)
Mid[num][++num1]=Set[i][j];//将小于断点值的划为一类
}
Mid[num++][0]=flag1;//个数
num1=0;
Mid[num]=NULL;
if((Mid[num]=new int[flag+1])==0)
{
AfxMessageBox("分配内存失败!");
return NULL;
}
for(j=1;j<=Set[i][0];j++)
{//将大于断点值的划为一类
if(pNonStringTable[Set[i][j]][m]>cut)
Mid[num][++num1]=Set[i][j];
}
Mid[num++][0]=flag;
}//end if((flag!=0)&&(flag1!=0))
else if((flag==0)&&(flag1!=0))//此等价类中只包含小于断点值的实例
{//全部拷贝到一个等价类中
Mid[num]=NULL;
if((Mid[num]=new int[flag1+1])==0)
{
AfxMessageBox("分配内存失败!");
return NULL;
}
for(j=1;j<=Set[i][0];j++)
Mid[num][++num1]=Set[i][j];
Mid[num++][0]=flag1;
}
else if((flag!=0)&&(flag1==0))//此等价类中只包含大于断点值的实例
{
Mid[num]=NULL;
if((Mid[num]=new int[flag+1])==0)
{
AfxMessageBox("分配内存失败!");
return NULL;
}
num1 =0;
for(j=1;j<=Set[i][0];j++)
Mid[num][++num1]=Set[i][j];
Mid[num++][0]=flag;
}
delete []Set[i];
Set[i]=NULL;
}//end for(i=0;i<N;i++)
delete []Set;
Set=NULL;
N=num; //重置等价类个数
return Mid; //返回划分后的等价类
}
double** CSemiMini::GetLastCut()
{//根据选出的断点集,求得最终的断点集,原先的断点集不是连续的(是有序的),即它留下了每个候选断点的
//位置,只有最终选上的断点位置上才不为0,按顺序选出这些断点,形成新的断点集是连续的。
//返回整理后的断点集
int i,j;
int num=0;
double **Mid=NULL;
if(iNonStrAttNum==0)
return NULL;
if((Mid=new double*[iNonStrAttNum])==0)
{
AfxMessageBox("分配内存失败!");
return NULL;
}
for(i=0;i<iNonStrAttNum;i++)
{//每个属性
Mid[i]=NULL;
if((Mid[i]=new double[(int)MidCut[i][0]+1])==0)
{
AfxMessageBox("分配内存失败!");
return NULL;
}
for(j=1;j<=(int)MidCut[i][0];j++)
{
if(Cut[i][j]!=0)
Mid[i][++num]=Cut[i][j];
}
Mid[i][0]=(double)num;//被选取作为断点的个数
num=0;
}//ebd for(i)
for(i=0;i<iNonStrAttNum;i++)
delete []Cut[i];
delete []Cut;
return Mid;
}
double* CSemiMini::GetDeciSet()
{//返回决策集,Mid1[0]为决策种类数,Mid1[]为决策值.返回决策属性的所有出现的值
int i,j;
int num=0;
int flag=0;
double *Mid=NULL;
double *Mid1=NULL;
if((Mid=new double[iRecordNum+1])==0)
{
AfxMessageBox("分配内存失败!");
return NULL;
}
Mid[++num]=pNonStringTable[0][iNonStrAttNum];//第0行的决策值
for(i=1;i<iRecordNum;i++)
{//i记录
for(j=1;j<=num;j++)
{//看是否与现有决策值重复
if(pNonStringTable[i][iNonStrAttNum]==Mid[j])
{
flag=1;
break;
}
}
if(flag==0)//不重复,加入
Mid[++num]=pNonStringTable[i][iNonStrAttNum];
flag=0;
}
Mid[0]=(double)num;
Mid1=new double[num+1];
for(i=0;i<num+1;i++)
Mid1[i]=Mid[i];
delete[] Mid;
return Mid1;
}
void CSemiMini::OnSemiMinidisSave(LPCTSTR lpszPathName)
{//写文件
int i,j;
fstream fpw;
fpw.open(lpszPathName,ios::out);
if(!fpw)
{
::MessageBeep(MB_ICONHAND);
AfxMessageBox("some error happen, file can't be opend!",
MB_OK|MB_ICONSTOP);
exit(0);
}
fpw<<"Style:"<<"train"<<endl;
fpw<<"Stage:2"<<endl;
fpw<<"Condition attributes number:"<<iAttNum<<endl;
fpw<<"Records number:"<<iRecordNum<<endl;
for(i = 0;i < iAttNum+1;i++)
fpw<<pAttName[i]<<" ";
fpw<<endl;
for(i = 0;i < iAttNum+1;i++)
fpw<<pDataType[i]<<" ";
fpw<<endl;
int strIndex=0,nonStrIndex=0;
for(i=0;i<iRecordNum;i++)
{
for(j=0;j< iAttNum;j++)
{
if(!strcmp(pDataType[j],"String"))
fpw<<pStringTableResult[i][strIndex++]<<" ";
else
fpw<<NewTable[i][nonStrIndex++]<<" ";
}
fpw<<NewTable[i][nonStrIndex];//决策属性
strIndex=0,nonStrIndex=0;
fpw<<endl;
}
fpw<<"[Cuts]"<<endl;//写断点
strIndex=0,nonStrIndex=0;
for(i=0;i<iAttNum;i++){
fpw<<i<<endl;
if(!strcmp(pDataType[i],"String")){
fpw<<strCuts[strIndex]<<endl; //断点个数
for(j=0;j<strCuts[strIndex];j++){
fpw<<pStrResult[j][strIndex]<<" "<<j<<endl;
//断点与离散值对应关系
}
strIndex++;
}
else{
fpw<<Cut[nonStrIndex][0]+1<<endl; //断点个数
fpw<<"["<<"*"<<",";
for(j=0;j<(int)Cut[nonStrIndex][0];j++){
fpw<<Cut[nonStrIndex][j+1]<<")"<<" "<<j<<endl;
fpw<<"["<<Cut[nonStrIndex][j+1]<<",";
}
fpw<<"*"<<"]"<<" "<<j;
fpw<<endl;
nonStrIndex++;
}
}
fpw.close();
}
BOOL CSemiMini::ReadDataFromFile(char *filename)
{//读文件
FILE *fp;
if((fp = fopen(filename,"r")) == NULL)
{
::MessageBeep(MB_ICONHAND);
AfxMessageBox("Couldn't open the file",MB_OK|MB_ICONSTOP);
return FALSE;
}//end if
fscanf(fp,"Style:%s\n",cStyle);
fscanf(fp,"Stage:%d\n",&iStage);
fscanf(fp,"Condition attributes number:%d\n",&iAttNum);
if(_stricmp(cStyle,"train") == 0 && iStage<=1)
{
fscanf(fp,"Records number:%d\n",&iRecordNum);
if(!readAttrInfo(fp))
return FALSE;
if(!readTable(fp))
return FALSE;
}
return TRUE;
}
//将属性名称读入pAttName中,将数据类型读入pDataType中
BOOL CSemiMini::readAttrInfo(FILE* fp){
int i;
if(pAttName == NULL){
try{
pAttName = new char*[iAttNum+1];
pDataType= new char*[iAttNum+1];
}
catch(CMemoryException* e){
::MessageBeep(MB_ICONHAND);
AfxMessageBox("Out of memory!",MB_OK|MB_ICONSTOP);
e->Delete();
return FALSE;
}
for(i=0;i <= iAttNum;i++){
try{
pAttName[i]=new char[MAX];
pDataType[i]=new char[MAX];
}
catch(CMemoryException* e){
::MessageBeep(MB_ICONHAND);
AfxMessageBox("Out of memory!",MB_OK|MB_ICONSTOP);
e->Delete();
return FALSE;
}
}//end for
}//end if
for(i=0;i <= iAttNum;i++)
fscanf(fp,"%s",pAttName[i]);
fscanf(fp,"\n");
//读属性名
iStrAttNum = 0;
iNonStrAttNum = 0;
for(i = 0;i < iAttNum;i++){
fscanf(fp,"%s",pDataType[i]);
if(!strcmp(pDataType[i],"String"))
iStrAttNum++;
else
iNonStrAttNum++;
}//读属性值类型
fscanf(fp,"%s",pDataType[iAttNum]);
//决策属性类型
fscanf(fp,"\n");
return TRUE;
}
//将表中属性值读入 pNonStringTable和pStringTable中
BOOL CSemiMini::readTable(FILE* fp){
int i,j;
if((pStringTable == NULL)&&(pNonStringTable == NULL)){
try
{
if(iStrAttNum!=0)
pStringTable = new char**[iRecordNum];
pNonStringTable = new double*[iRecordNum];
//至少决策属性是保存在pNonStringTable中的,所以pNonStringTable一
//定不为空
}
catch(CMemoryException* e){
::MessageBeep(MB_ICONHAND);
AfxMessageBox("Out of memory!",MB_OK|MB_ICONSTOP);
e->Delete();
return FALSE;
}
for(i = 0;i < iRecordNum;i++){
try{
if(iStrAttNum!=0)
pStringTable[i] = new char*[iStrAttNum];
pNonStringTable[i] = new double[iNonStrAttNum+1];//包括决策属性
}
catch(CMemoryException* e){
::MessageBeep(MB_ICONHAND);
AfxMessageBox("Out of memory!",MB_OK|MB_ICONSTOP);
e->Delete();
return FALSE;
}
for(j = 0;j < iStrAttNum;j++){
try{
pStringTable[i][j] = new char[MAX];
}
catch(CMemoryException* e){
::MessageBeep(MB_ICONHAND);
AfxMessageBox("Out of memory!",MB_OK|MB_ICONSTOP);
e->Delete();
return FALSE;
}
}//end for
for(j=0;j<=iNonStrAttNum;j++)
pNonStringTable[i][j]=0.0;
}//end for
}//end if
int iStrIndex=0,iNonStrIndex=0;
char* str=NULL;
if((str=new char[MAX])==0)
return FALSE;
/////////////////////////////////////////////////
//判断对那些属性进行处理,增加一个判断行,包括1,0
//对应为0的属性不进行离散化处理
//增加属性的判断标识符
// JudgeAttr=new bool [i];
////////////////////////////////////////////////
for(i = 0;i < iRecordNum;i++){
for(j = 0;j < iAttNum;j++){
if(!strcmp(pDataType[j],"String"))
fscanf(fp,"%s",pStringTable[i][iStrIndex++]);
//字符串类型的属性值读入pStringTable
else if(!strcmp(pDataType[j],"Float")){
fscanf(fp,"%s",str);
pNonStringTable[i][iNonStrIndex++]=(double)atof(str);
}//非字符串类型的属性值读入pNonStringTable
else if(!strcmp(pDataType[j],"Integer")){
fscanf(fp,"%s",str);
pNonStringTable[i][iNonStrIndex++]=atoi(str);
}//非字符串类型的属性值读入pNonStringTable
}
fscanf(fp,"%s",str);//读入决策属性的值
fscanf(fp,"\n");
pNonStringTable[i][iNonStrIndex]=(int)atof(str);
iStrIndex=0,iNonStrIndex=0;
}
delete[] str;
return TRUE;
}
void CSemiMini::doString(){
//先建立一个pStrResult,通过对pStringTable的一次扫描,把每一个属性的所有可能值
//找出来,建立字符串值与离散值的映射关系
//再把pStringTable中的数据与pStrResult中的数据进行比较,修改pStringTable中的
//值,以便打印结果 //strCuts[]存放断点个数
int i=0,j=0,k=0;
try{
pStrResult = new char**[iRecordNum];
pStringTableResult = new int*[iRecordNum];
//存放离散化以后的结果
strCuts = new int[iStrAttNum];
//存放字符串属性的断点个数
}
catch(CMemoryException* e){
::MessageBeep(MB_ICONHAND);
AfxMessageBox("Out of memory!",MB_OK|MB_ICONSTOP);
e->Delete();
}
for (i=0;i<iRecordNum;i++){
try{
pStrResult[i]= new char*[iStrAttNum];
pStringTableResult[i]= new int[iStrAttNum];
}
catch(CMemoryException* e){
::MessageBeep(MB_ICONHAND);
AfxMessageBox("Out of memory!",MB_OK|MB_ICONSTOP);
e->Delete();
}
for(j=0;j<iStrAttNum;j++){
pStrResult[i][j] = new char[MAX];
strcpy(pStrResult[i][j],"");
}
}
for(i=0;i<iStrAttNum;i++){
for(j=0;j<iRecordNum;j++)
pStringTableResult[j][i]=0;
strCuts[i]=0;
}
for(i=0;i<iStrAttNum;i++){
for(j=0;j<iRecordNum;j++){//对每一列
for(k=0;k<=j; k++){
if(!strcmp(pStringTable[j][i],pStrResult[k][i]))
break;
else if(!strcmp(pStrResult[k][i],"")){
//如果pStrResult[k][i]不等于pStringTable[j][i]
//而且pStrResult[k][i]为空则应该把pStringTable[j][i]赋值给pStrResult[k][i]
strcpy(pStrResult[k][i],pStringTable[j][i]);
strCuts[i]++;//记录断点个数
break;
}
}
pStringTableResult[j][i]=k;
//把pStringTableResult[j][i]的值改为离散化以后的值
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -