?? getdata.c
字號(hào):
/*************************************************************************
* Get case descriptions from data file
*************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "types.h"
#include "ErrorP.h"
char *FileName = "DF"; /* 默認(rèn)的數(shù)據(jù)文件名 */
short ClassNum; /* 分類數(shù)目 */
char **ClassName; /* 類名 */
short AttNum; /* 最大屬性數(shù)目 */
char **AttName; /* 屬性名 */
short *AttValNum; /* 每個(gè)屬性取值的最大個(gè)數(shù) */
char ***AttValName; /* 屬性值類型或名稱 - AttValName[Att][0]中存儲(chǔ)離散屬性值的最大值 */
char *SpecialStatus; // 特征類型:IGNORE,DISCRETE,CONTINUOUS
short MaxDiscrValNum = 2; // 離散特征(數(shù)值類型)和集合特征的最大取值個(gè)數(shù)
int ItemNum; /* 讀取的數(shù)據(jù)條數(shù)目 */
Description *Item; /* 讀取的數(shù)據(jù)條內(nèi)容 */
char Delimiter; /* 定界符 */
///////////////////////////////////////////////////////////////////////////////////////////////////
// 功能函數(shù)
///////////////////////////////////////////////////////////////////////////////////////////////////
char *CopyString( char *x)
{
char *s;
s = (char *) calloc(strlen(x)+1, sizeof(char));
if( s != NULL ) {
//printf( "Allocated Success\n" );
//free( s );
}
else {
printf( "Can't allocate memory\n" );
}
strcpy(s, x);
return s;
}
/////////////////////////////////////////////////////////////////////
// 在 List[First] 到 List[Last] 之間定位 Val 值的位置
/////////////////////////////////////////////////////////////////////
int Which(char *Val, char *List[], short First, short Last)
{
short n=First;
while ( n <= Last && strcmp(Val, List[n]) ) n++;
return ( n <= Last ? n : First-1 );
}
/////////////////////////////////////////////////////////////////////
// Read a name from file f into string s, setting Delimiter.
/////////////////////////////////////////////////////////////////////
#define SkipComment while ( ( c = getc(f) ) != '\n' )
#define Space(s) (s == ' ' || s == '\n' || s == '\t')
Boolean ReadName(FILE *f, char *s)
{
register char *Sp=s;
register int c;
/* 跳過空格和注釋 */
while ( ( c = getc(f) ) == '|' || (c == ' ' || c == '\n' || c == '\t') ) {
if ( c == '|' ) {
/* 跳過注釋信息 */
SkipComment;
}
}
/* 如果沒有屬性名返回FALSE, 定界符賦值=EOF(文件結(jié)束) */
if ( c == EOF ) { Delimiter = EOF; return FALSE; }
/**************************************************************************
* 讀字符直到另一個(gè)分界符
* ':' 屬性名與屬性值之間的分界符
* ',' 屬性值與數(shù)據(jù)條值之間的分界符
* '\n' 行結(jié)束
* '|' 注釋分界符
* 'EOF' 文件結(jié)束分界符
**************************************************************************/
while ( c != ':' && c != ',' && c != '\n' && c != '|' && c != EOF ) {
if ( c == '.' ) {
if ( ( c = getc(f) ) == '|' || (c == ' ' || c == '\n' || c == '\t') ) break;
*Sp++ = '.';
}
if ( c == '\\' ) { c = getc(f); }
*Sp++ = c;
/* 跳過空格 */
if ( c == ' ' ) { while ( ( c = getc(f) ) == ' ' ) ; }
else { c = getc(f); }
}
if ( c == '|' ) SkipComment;
Delimiter = c;
while ( (*(Sp-1) == ' ' || *(Sp-1) == '\n' || *(Sp-1) == '\t') ) Sp--;
*Sp++ = '\0';
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
// 讀取類、特征的有關(guān)信息
///////////////////////////////////////////////////////////////////////////////
void GetNames()
{
FILE *File_Hander;
char Ch_FileName[100];
char Buffer[1000];
short v;
int ClassCeiling=100, AttCeiling=100, ValCeiling;
// 打開數(shù)據(jù)屬性名文件 ///////////////////////////////////////////////////////
strcpy(Ch_FileName, FileName);
strcat(Ch_FileName, ".names");
if ( !(File_Hander=fopen(Ch_FileName, "r")) ) { Error(0, Ch_FileName, ""); }
// 從數(shù)據(jù)屬性名文件獲取類名 /////////////////////////////////////////////////////////
ClassName = (char **) calloc(ClassCeiling, sizeof(char *));
if( ClassName != NULL ) {
// printf( "Allocated Success\n" );
// free( ClassName );
}
else {
printf( "Can't allocate memory on ClassName!\n" );
exit(1);
}
ClassNum = -1;
do {
ReadName(File_Hander, Buffer);
if ( ++ClassNum >= ClassCeiling) {
ClassCeiling += 100;
ClassName = (char **) realloc(ClassName, ClassCeiling*sizeof(char *));
if( ClassName != NULL ) {
// printf( "Allocated Success\n" );
// free( ClassName );
}
else {
printf( "Can't allocate memory on ClassName!\n" );
exit(1);
}
}
ClassName[ClassNum] = CopyString(Buffer); // free(ClassName[ClassNum]);
} while ( Delimiter == ',' );
// 從數(shù)據(jù)屬性名文件獲取屬性名和屬性值 ///////////////////////////////////////////////
AttName = (char **) calloc(AttCeiling, sizeof(char *));
if( AttName != NULL ) {
// printf( "Allocated Success\n" );
// free( AttName );
}
else {
printf( "Can't allocate memory on AttName!\n" );
exit(1);
}
AttValNum = (short *) calloc(AttCeiling, sizeof(short));
AttValName = (char ***) calloc(AttCeiling, sizeof(char **));
SpecialStatus = (char *) malloc(AttCeiling);
AttNum = -1;
while ( ReadName(File_Hander, Buffer) ) {
// 每個(gè)特征一個(gè)循環(huán) //////////////////////////////////////////////////
if ( Delimiter != ':' ) { Error(1, Buffer, ""); } // 格式定義":"
if ( ++AttNum >= AttCeiling ) {
/* 如果分配記錄屬性名的空間不夠,則再分配空間 */
AttCeiling += 100;
AttName = (char **) realloc(AttName, AttCeiling*sizeof(char *));
AttValNum = (short *) realloc(AttValNum, AttCeiling*sizeof(short));
AttValName = (char ***) realloc(AttValName, AttCeiling*sizeof(char **));
SpecialStatus = (char *) realloc(SpecialStatus, AttCeiling);
}
// 獲取特征名 ////////////////////////////////
AttName[AttNum] = CopyString(Buffer);
// 獲取特征值及判斷屬性的特點(diǎn) ////////////////
SpecialStatus[AttNum] = NIL;
AttValNum[AttNum] = 0;
ValCeiling = 100;
AttValName[AttNum] = (char **) calloc(ValCeiling, sizeof(char *));
do {
// 每個(gè)特征取值一個(gè)循環(huán) ////////////////////////////////////////////////////
if ( ! ( ReadName(File_Hander, Buffer) ) ) Error(2, AttName[AttNum], "");
if ( ++AttValNum[AttNum] >= ValCeiling ) {
ValCeiling += 100;
AttValName[AttNum] = (char **) realloc(AttValName[AttNum], ValCeiling*sizeof(char *));
}
// 獲取特征值名稱,數(shù)組下標(biāo) AttValNum[AttNum] 從1開始 /////
AttValName[AttNum][AttValNum[AttNum]] = CopyString(Buffer);
} while ( Delimiter == ',' );
// 根據(jù)屬性取值個(gè)數(shù)進(jìn)行屬性類別的處理 ///////////////////////////////////////////
if ( AttValNum[AttNum] == 1 ) {
// 如果屬性只有一個(gè)取值: continous,discrete和ignore 三種類型 ///////
if ( ! strcmp(Buffer, "continuous") ) {
// "continuous" 類型
// 進(jìn)行離散處理
SpecialStatus[AttNum] = CONTINUOUS;
}
else if ( ! memcmp(Buffer, "discrete", 8) ) {
// "discrete" 類型的屬性處理
SpecialStatus[AttNum] = DISCRETE;
v = atoi(&Buffer[8]);
if ( v < 2 ) {
printf("** %s: illegal number of discrete values\n", AttName[AttNum]);
exit(1);
}
AttValName[AttNum] = (char **) realloc(AttValName[AttNum], (v+2)*sizeof(char *));
// DISCRETE 類型的特征值數(shù)組,設(shè)置相應(yīng)離散屬性的最大取值 /////////////////////////
AttValName[AttNum][0] = (char *) v;
if ( v > MaxDiscrValNum ) MaxDiscrValNum = v;
}
else {
if ( ! strcmp(Buffer, "ignore") ) {
/* "ignore" 類型的屬性處理 */
SpecialStatus[AttNum] = IGNORE;
}
else {
/* 不能識(shí)別的屬性類型 */
Error(3, AttName[AttNum], "");
}
}
// IGNORE,DISCRETE,CONTINUOUS 特征取值個(gè)數(shù)設(shè)置為 0 ///////////////////
AttValNum[AttNum] = 0;
}
else {
// 集合特征 ///////////////////////////////////////////////////////////
SpecialStatus[AttNum] = SET;
if ( AttValNum[AttNum] > MaxDiscrValNum ) MaxDiscrValNum = AttValNum[AttNum];
}
} /* end while */
fclose(File_Hander);
}
/////////////////////////////////////////////////////////////////////////////////////////
// 讀訓(xùn)練數(shù)據(jù)
/////////////////////////////////////////////////////////////////////////////////////////
#define ITEM2K 2048
Description GetDescription(FILE *File_Hander)
{
short Att;
char name[500], *endname;
int Dv;
float Cv;
Description Dvec;
if ( ReadName(File_Hander, name) ) {
// 分配存儲(chǔ)屬性值的空間 //////////////////////////////////////////////
Dvec = (Description) calloc(AttNum+2, sizeof(AttValue));
if( Dvec == NULL ) {
printf("Can't allocate memory on sub Item.\n" );
exit(1);
}
// 讀取各個(gè)特征的取值 ////////////////////////////////////////////////
for (Att = 0; Att <= AttNum; ++Att ) {
if ( SpecialStatus[Att] == IGNORE ) {
DVal(Dvec, Att) = 0;
}
else if ( AttValNum[Att] || SpecialStatus[Att] == DISCRETE ) {
// SET 特征 || DISCRETE 特征 /////////////////////////////////
if ( ! ( strcmp(name, "?") ) ) {
Dv = 0;
}
else {
/* 查找屬性取值name在屬性取值A(chǔ)ttValName[Att]中的位置 */
Dv = Which(name, AttValName[Att], 1, AttValNum[Att]);
if ( ! Dv ) {
// Dv=0 表示屬性出現(xiàn)新的取值 //////////////////////////
if ( SpecialStatus[Att] == DISCRETE ) {
// DISCRETE 特征
Dv = ++AttValNum[Att]; /* 離散屬性取值個(gè)數(shù)加1 */
if ( Dv > (int) AttValName[Att][0] ) {
printf("\nToo many values for %s (max %d)\n", AttName[Att], (int) AttValName[Att][0]);
exit(1);
}
AttValName[Att][Dv] = CopyString(name);
}
else {
// SET 的特征不允許出現(xiàn)新的取值
Error(4, AttName[Att], name);
}
}
}
DVal(Dvec, Att) = Dv;
}
else {
// 連續(xù)數(shù)值處理
if ( ! ( strcmp(name, "?") ) ) {
/* 未知的連續(xù)值 */
Cv = Unknown;
}
else {
Cv = (float) strtod(name, &endname);
if ( endname == name || *endname != '\0' ) {
Error(4, AttName[Att], name);
}
}
CVal(Dvec, Att) = Cv;
}
ReadName(File_Hander, name);
} /* for end */
/* 讀取類值 */
if ( (Dv = Which(name, ClassName, 0, ClassNum)) < 0 ) {
Error(5, "", name);
Dv = 0;
}
Class(Dvec) = Dv;
return Dvec; /* 讀取了一條完整的數(shù)據(jù)并返回 */
}
else {
return NIL;
}
}
void GetData(char *Extension)
{
FILE *File_Hander;
char ch_FileName[100];
int Item_count, ItemSpace;
// 打開數(shù)據(jù)文件 ////////////////////////////////////////////////////////////////
strcpy(ch_FileName, FileName);
strcat(ch_FileName, Extension);
if ( ! ( File_Hander = fopen(ch_FileName, "r") ) ) Error(0, ch_FileName, "");
Item_count=0;
ItemSpace=0;
do {
ItemNum = Item_count;
if ( Item_count >= ItemSpace ) {
if ( ItemSpace ) {
ItemSpace += ITEM2K; /* 每次追加2k條空間 */
/* 追加分配空間 */
if( (Item = (Description *) realloc(Item, ItemSpace*sizeof(Description)) ) == NULL ) {
printf( "Can't realloc memory on Item\n" );
exit(1);
}
}
else {
/* 第一次分配空間 */
if( (Item = (Description *) malloc((ItemSpace=ITEM2K)*sizeof(Description)) ) == NULL ) {
printf( "Can't malloc memory on Item\n" );
exit(1);
}
}
}
Item[Item_count] = GetDescription(File_Hander);
} while ( Item[Item_count] != NIL && ++Item_count );
fclose(File_Hander);
ItemNum = Item_count - 1; /* 讀取的最大數(shù)據(jù)條數(shù) */
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -