📄 distwo.cpp
字号:
// DisTwoDoc.cpp: implementation of the CDisTwoDoc class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "RSet.h"
#include "DisTwo.h"
#include "fstream.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CDisTwo::CDisTwo()
{
infotable=NULL;
att_val=NULL;
interval=NULL;
formulas=NULL;
matrix=NULL;
cut=NULL;
new_table=NULL;
pAttName=NULL;
pDataType=NULL;
pStringTable=NULL;
}
CDisTwo::~CDisTwo()
{
int i; //循环变量
if(interval!=NULL)
{
for(i=0;i<iAttNum;i++)
delete []interval[i];
delete []interval;
}
if(infotable!=NULL)
{
for(i=0;i<iRecordNum;i++)
delete []infotable[i];
delete []infotable;
}
if(att_val!=NULL)
{
for(i=0;i<iAttNum;i++)
delete []att_val[i];
delete []att_val;
}
if(cut!=NULL)
{
for(i=0;i<iAttNum;i++)
delete []cut[i];
delete []cut;
}
if(new_table!=NULL)
{
for(i=0;i<iRecordNum;i++)
delete []new_table[i];
delete []new_table;
}
if(pAttName)
{
for(i=0;i<iAttNum+1;i++)
delete []pAttName[i];
delete[] pAttName;
}
if(pDataType)
{
for(i=0;i<iAttNum+1;i++)
delete []pDataType[i];
delete[] pDataType;
}
if(pStringTable)
{
for(i=0;i<iRecordNum;i++)
{
for(int j=0;j<iAttNum+1;j++)
delete[] pStringTable[i][j];
delete[] pStringTable[i];
}
delete[] pStringTable;
}
}
BOOL CDisTwo::OnDisTwo()
{
int matrix_row; //矩阵的行数
int matrix_col; //矩阵的列数
int i = load_table();
if(i==1)
{
get_att_val();
matrix_row=logic();
matrix_col=init_matrix(matrix_row);
findcuts(matrix_row,matrix_col);
make_new_table();
return TRUE;
}
return FALSE;
}
int CDisTwo::get_att_val()
{
int i,j; //循环变量
int n; //记录数
att_val=new float * [iAttNum];
float * val=new float[iRecordNum+1];
for(i=0;i<iAttNum;i++)
{
n=get_rec_num(i,val);
try
{
att_val[i]=new float[n+1];
}
catch(CMemoryException * e)
{
::MessageBeep(MB_ICONHAND);
AfxMessageBox("Out of the memory!",MB_OK|MB_ICONSTOP);
e->Delete();
return -2;
}
for(j=0;j<n+1;j++)
att_val[i][j]=val[j];
}
selectsort(att_val);
interval=new float *[iAttNum];
for(i=0;i<iAttNum;i++)
{
interval[i]=new float[(int)att_val[i][0]];
interval[i][0]=att_val[i][0]-1;
for(j=1;j<att_val[i][0];j++)
interval[i][j]=(att_val[i][j]+att_val[i][j+1])/2;
}
delete val;
return 1;
}
int CDisTwo::get_rec_num(int att, float *val)
{
int i,j; //循环变量
bool find=FALSE;
val[0]=0;
for(i=0;i<iRecordNum;i++)
{
for(j=0;j<val[0];j++)
if(infotable[i][att]==val[j+1])
{
find=TRUE;
break;
}
if(find==FALSE)
{
val[0]++;
val[(int)val[0]]=infotable[i][att];
}
find=FALSE;
}
return (int)val[0];
}
void CDisTwo::selectsort(float **val)
{
int i,j,k; //循环变量
int mini=0;
float middle_val;
for(i=0;i<iAttNum;i++)
for(j=1;j<(int)val[i][0];j++)
{
mini=j;
for(k=j+1;k<(int)val[i][0]+1;k++)
if(val[i][k]<val[i][mini])
mini=k;
if(mini!=j)
{
middle_val=val[i][j];
val[i][j]=val[i][mini];
val[i][mini]=middle_val;
}
}
}
int CDisTwo::logic()
{
int i,j,k,m;//循环变量
int count=0;
int recnum1,recnum2,distance;
float val1,val2;
for(i=0;i<iRecordNum-1;i++)
for(j=i+1;j<iRecordNum;j++)
if(infotable[i][iAttNum]!=infotable[j][iAttNum])
count++;
formulas=new float ** [count];
count=0;
for(i=0;i<iRecordNum-1;i++)
for(j=i+1;j<iRecordNum;j++)
if(infotable[i][iAttNum]!=infotable[j][iAttNum])
{
formulas[count]=new float * [iAttNum];
for(k=0;k<iAttNum;k++)
{
formulas[count][k]=new float[(int)interval[k][0]+1];
recnum1=search(infotable[i][k],k);
recnum2=search(infotable[j][k],k);
distance=abs(recnum2-recnum1);
formulas[count][k][0]=(float)distance;
if(recnum1<recnum2)
for(m=1;m<distance+1;m++)
{
val1=att_val[k][recnum1];
val2=att_val[k][recnum1+1];
formulas[count][k][m]=(val1+val2)/2;
recnum1++;
}
if(recnum1>recnum2)
for(m=1;m<distance+1;m++)
{
val1=att_val[k][recnum2];
val2=att_val[k][recnum2+1];
formulas[count][k][m]=(val1+val2)/2;
recnum2++;
}
}
count++;
}
return count;
}
int CDisTwo::init_matrix(int rows)
{
int i,j,k,m; //循环变量
int cols=0; //定义矩阵的行数列数
bool find=FALSE;
int num=0; //矩阵列数
matrix=new int * [rows];
for(i=0;i<iAttNum;i++)
num+=(int)interval[i][0];
for(i=0;i<rows;i++)
{
matrix[i]=new int[num];
for(j=0;j<iAttNum;j++)
for(k=0;k<(int)interval[j][0];k++)
{
if((int)formulas[i][j][0]==0)
matrix[i][cols]=0;
if((int)formulas[i][j][0]>0)
{
for(m=0;m<(int)formulas[i][j][0];m++)
if(interval[j][k+1]==formulas[i][j][m+1])
{
matrix[i][cols]=1;
find=TRUE;
break;
}
if(find==FALSE)
matrix[i][cols]=0;
find=FALSE;
}
cols++;
}
cols=0;
}
for(i=0;i<iAttNum;i++)
cols+=(int)interval[i][0];
for(i=0;i<rows;i++)
for(j=0;j<iAttNum;j++)
delete []formulas[i][j];
for(i=0;i<rows;i++)
delete []formulas[i];
delete []formulas;
return cols;
}
void CDisTwo::findcuts(int rows, int cols)
{
int i,j,k; //循环变量
int * cuts=new int[cols+1]; //定义断点
cuts[0]=0; //设置断点的初始个数
int num;
int remains; //未处理的矩阵元素个数
int minvalue;//含1最少的行
int select=0;//选择哪个断点
int *countcols=new int[cols]; //各列断点个数总和
int minicol;
int * countrows=new int[rows];
//初始化各行1的总和
for(i=0;i<rows;i++)
countrows[i]=0;
for(i=0;i<rows;i++)
for(j=0;j<cols;j++)
if(matrix[i][j]==1)
countrows[i]++;
do
{
minvalue=0;
remains=0;
for(i=0;i<cols;i++)
countcols[i]=0;
//先选行值1的总数最少的行
//当有两行以上行总数都是最少,看断点列为1的总数
//选取列总数最少的断点
for(i=0;i<rows;i++)
if(minvalue<countrows[i])
minvalue=countrows[i];
for(i=0;i<rows;i++)
if((minvalue>countrows[i])&&(countrows[i]!=0))
minvalue=countrows[i];
//找出行总和最少的1的个数
num=0;
for(i=0;i<rows;i++)
{
if(countrows[i]==minvalue)
{
for(j=0;j<cols;j++)
if((matrix[i][j]==1)&&(countcols[j]==0))
{
num=0;
for(k=0;k<rows;k++)
if(matrix[k][j]==1)
num+=countrows[k];
countcols[j]=num;
}
}
}
minicol=0;
for(i=0;i<cols;i++)
if(countcols[i]>minicol)
minicol=countcols[i];
for(i=0;i<cols;i++)
if((countcols[i]<minicol)&&(countcols[i]!=0))
minicol=countcols[i];
for(i=0;i<cols;i++)
if(minicol==countcols[i])
select=i;
// 删除i所在的列和列值为1的行
for(i=0;i<rows;i++)
if(matrix[i][select]==1)
{
for(j=0;j<cols;j++)
matrix[i][j]=-1;
}
for(i=0;i<rows;i++)
matrix[i][select]=-1;
cuts[0]++;
cuts[cuts[0]]=select;
for(i=0;i<rows;i++)
countrows[i]=0;
for(i=0;i<rows;i++)
for(j=0;j<cols;j++)
if(matrix[i][j]==1)
countrows[i]++;
for(i=0;i<rows;i++)
remains+=countrows[i];
}while(remains>0);
delete countrows;
delete countcols;
for(i=0;i<rows;i++)
delete matrix[i];
delete matrix;
get_cut(cuts);
}
void CDisTwo::get_cut(int *pos)
{
int i,j; //循环变量
int cut_num; //每个属性的断点数
int * new_pos;
int num;
cut=new float *[iAttNum];
for(i=0;i<iAttNum;i++)
{
cut_num=0;
num=0;
cut[i]=new float[(int)interval[i][0]+1];
for(j=0;j<pos[0];j++)
if(pos[j+1]<interval[i][0])
{
cut_num++;
cut[i][cut_num]=interval[i][pos[j+1]+1];
}
cut[i][0]=(float)cut_num;
new_pos=new int[pos[0]-cut_num+1];
new_pos[0]=pos[0]-cut_num;
for(j=0;j<pos[0];j++)
if(pos[j+1]>=interval[i][0])
new_pos[++num]=pos[j+1]-(int)interval[i][0];
delete []pos;
pos=new int[num+1];
for(j=0;j<num+1;j++)
pos[j]=new_pos[j];
delete []new_pos;
}
delete []pos;
}
void CDisTwo::make_new_table()
{
int i,j,k; //循环变量
int m;
selectsort(cut);
new_table=new int *[iRecordNum];
for(i=0;i<iRecordNum;i++)
{
new_table[i]=new int[iAttNum+1];
for(j=0;j<iAttNum;j++)
{
m=0;
for(k=0;k<cut[j][0];k++)
{
if(infotable[i][j]<cut[j][k+1])
{
new_table[i][j]=m;
break;
}
m++;
if(infotable[i][j]>cut[j][(int)cut[j][0]])
new_table[i][j]=m;
}
if(cut[j][0]==0)
new_table[i][j]=0;
}
new_table[i][iAttNum]=(int)infotable[i][iAttNum];
}
}
int CDisTwo::search(float val, int condition)
{
int i; //循环变量
int num;
for(i=0;i<att_val[condition][0];i++)
if(val==att_val[condition][i+1])
num=i+1;
return num;
}
int CDisTwo::load_table()
{
int i,j;
infotable=new float * [iRecordNum];
for(i=0;i<iRecordNum;i++)
{
try
{
infotable[i]=new float[iAttNum+1];
}
catch(CMemoryException * e)
{
::MessageBeep(MB_ICONHAND);
AfxMessageBox("Out of the memory!",MB_OK|MB_ICONSTOP);
e->Delete();
return -2;
}
for(j=0;j<iAttNum+1;j++)
for(j=0;j<iAttNum+1;j++)
infotable[i][j]=(float)atof(pStringTable[i][j]);
}
return 1;
}
void CDisTwo::OnDisTwoSave(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;
for(i=0;i<iRecordNum;i++)
{
for(j=0;j<iAttNum+1;j++)
{
fpw<<new_table[i][j];
fpw<<" ";
}
fpw<<endl;
}
fpw<<"[Cuts]"<<endl;
for(i=0;i<iAttNum;i++)
{
fpw<<i<<endl<<cut[i][0]+1<<endl;
fpw<<"["<<"*"<<",";
for(j=0;j<(int)cut[i][0];j++)
{
fpw<<cut[i][j+1]<<")"<<" "<<j<<endl;
fpw<<"["<<cut[i][j+1]<<",";
}
fpw<<"*"<<")"<<" "<<j;
fpw<<endl;
}
fpw.close();
}
BOOL CDisTwo::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(!SetAttName(fp,iAttNum+1))
return FALSE;
if(!SetDataType(fp,iAttNum+1))
return FALSE;
if(!SetStringTable(fp,iAttNum+1,iRecordNum))
return FALSE;
}
return TRUE;
}
BOOL CDisTwo::SetAttName(FILE* fp, int count)
{
int i;
if(pAttName == NULL)
{
try
{
pAttName = new char*[count];
}
catch(CMemoryException* e)
{
::MessageBeep(MB_ICONHAND);
AfxMessageBox("Out of the memory!",MB_OK|MB_ICONSTOP);
e->Delete();
return FALSE;
}
for(i=0;i < count;i++)
{
try
{
pAttName[i]=new char[MAX];
}
catch(CMemoryException* e)
{
::MessageBeep(MB_ICONHAND);
AfxMessageBox("Out of the memory!",MB_OK|MB_ICONSTOP);
e->Delete();
return FALSE;
}
}//end for
}//end if
for(i=0;i < count;i++)
fscanf(fp,"%s",pAttName[i]);
fscanf(fp,"\n");
return TRUE;
}
BOOL CDisTwo::SetDataType(FILE *fp, int count)
{
int i;
if(pDataType == NULL)
{
try
{
pDataType = new char*[count];
}
catch(CMemoryException* e)
{
::MessageBeep(MB_ICONHAND);
AfxMessageBox("Out of the memory!",MB_OK|MB_ICONSTOP);
e->Delete();
return FALSE;
}
for(i = 0;i < count;i++)
{
try
{
pDataType[i]=new char[MAX];
}
catch(CMemoryException* e)
{
::MessageBeep(MB_ICONHAND);
AfxMessageBox("Out of the memory!",MB_OK|MB_ICONSTOP);
e->Delete();
return FALSE;
}
}//end for
}//end if
for(i = 0;i < count;i++)
fscanf(fp,"%s",pDataType[i]);
return TRUE;
}
BOOL CDisTwo::SetStringTable(FILE* fp, int column, int row)
{
int i,j;
if(pStringTable == NULL)
{
try
{
pStringTable = new char**[row];
}
catch(CMemoryException* e)
{
::MessageBeep(MB_ICONHAND);
AfxMessageBox("Out of memory!",MB_OK|MB_ICONSTOP);
e->Delete();
return FALSE;
}
for(i = 0;i < row;i++)
{
try
{
pStringTable[i] = new char*[column];
}
catch(CMemoryException* e)
{
::MessageBeep(MB_ICONHAND);
AfxMessageBox("Out of memory!",MB_OK|MB_ICONSTOP);
e->Delete();
return FALSE;
}
for(j = 0;j < column;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;
}
strcpy(pStringTable[i][j]," ");
}//end for
}//end for
}//end if
for(i = 0;i < row;i++)
for(j = 0;j < column;j++)
fscanf(fp,"%s",pStringTable[i][j]);
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -