www.pudn.com > apdb2ndb.rar > atn_sfx.cc
#ifndef lint
static char copyright[] = "Copyright (C) FUJITSU LIMITED 2001" ;
static char id[] = "$Id: atn_sfx.cc,v 1.1 2001/02/13 10:35:35 JST rad1 Exp $" ;
#endif
/*
* $Log: atn_sfx.cc,v $
* Revision 1.1 2001/02/13 10:35:35 JST rad1
* $B:eK\(B(TSL)
* $B!&%5%U%#%C%/%9$K$h$k%=!<%H%/%i%9(B
*
* $Com: 阪本(TSL)
* $Com: ・サフィックスによるソートクラス
*/
//
// サフィックス->インデックス変換
//
#include "atn_inc.h"
atn_sfx::atn_sfx(void)
{
ascending_1 = false;
descending_1 = false;
ascending = false;
descending = false;
num_of_sfx_rec =0;
cur_num_of_sfx_rec =0;
num_of_digits=0;
sfx_rec = NULL;
min_sfx= 0 ;
max_sfx = 0;
sorted_sfx_rec = NULL;
num_of_alpha_num = 0;
num_of_sorted_rec = 0;
pnidx = 0;
};
int atn_sfx::clear(void)
{
ascending_1 = false;
descending_1 = false;
ascending = false;
descending = false;
num_of_sfx_rec =0;
cur_num_of_sfx_rec =0;
num_of_digits=0;
sfx_rec = NULL;
min_sfx=max_sfx = 0;
sorted_sfx_rec = NULL;
num_of_alpha_num = 0;
num_of_sorted_rec = 0;
pnidx = 0;
return 0;
};
int atn_sfx::set_num(int num)
{
num_of_sfx_rec = num;
try {
sfx_rec = new atn_sfx_rec[num+1];
}
catch(...) {
/* fatal error */
return -1;
abort();
}
return 0;
}
/*
* 文字列を整数に変換、与えられた文字列が数字以外を含むとき、
* にfalseを設定する
*/
atn_str2int(const char *nptr,bool &isDigit)
{
int rc;
char *endptr = NULL;
if(nptr == NULL) return false;
rc = strtol(nptr,&endptr,10);
if(endptr == NULL ) isDigit = false;
else if(endptr[0] == 0 || isspace(endptr[0]))
isDigit = true;
else
isDigit = false;
return rc;
}
int atn_sfx::entry1(const char *suffix,int64_t aid,int idx)
{
int i ;
i = cur_num_of_sfx_rec ;
/* 整数値の変数の格納 */
if(sfx_rec == 0)
{
return -1;
}
if(i >= num_of_sfx_rec)
{
return -2;
}
sfx_rec[i].suffix = strdup(suffix);
sfx_rec[i].aid = aid;
sfx_rec[i].idx = idx;
/* 文字列が数字かどうかを判定し、値を格納 */
bool isDigit = false;
int val = 0;
val = atn_str2int(suffix,isDigit);
sfx_rec[i].digit_flag = isDigit;
sfx_rec[i].val = val;
/* 数字の最大値を算出 */
if(isDigit)
{
val;
min_sfx;
max_sfx;
if(val < min_sfx)
min_sfx = val;
if(val >= max_sfx)
max_sfx = val;
}
/* 各種カウンタの更新 */
cur_num_of_sfx_rec++;
if(isDigit) num_of_digits ++;
else num_of_alpha_num ++;
return 0;
}
// すべて数字だったらtrue
bool atn_sfx::chk_all_digits()
{
bool rc = true;
for(int i=0;i= prev_value)
{
rc = false;
break;
}
prev_value = sfx_rec[i].val;
rc = true;
}
return rc;
}
// ソート関数
int atn_sfx::sort(void)
{
int rc = 0;
if(num_of_sfx_rec == 1)
{
num_of_sorted_rec = num_of_sfx_rec;
sorted_sfx_rec = (atn_sfx_rec **)
calloc(num_of_sorted_rec,sizeof(atn_sfx_rec **));
sorted_sfx_rec[0] = &sfx_rec[0];
goto exit_func;
}
/* 昇順の場合,降順の場合 1変化 */
ascending_1 = chk_ascending_1();
descending_1 = chk_descending_1();
if(ascending_1 || descending_1)
{
num_of_sorted_rec = num_of_sfx_rec;
sorted_sfx_rec = (atn_sfx_rec **)
calloc(num_of_sorted_rec,sizeof(atn_sfx_rec **));
for(int i = 0;i < num_of_sorted_rec;i++)
this->sorted_sfx_rec[i] = &sfx_rec[i];
rc = 0;
goto exit_func;
}
/* 昇順iiまたは降順で、英数字がない場合 */
ascending = chk_ascending();
descending = chk_descending();
if((ascending||descending ) && num_of_alpha_num==0)
{
num_of_sorted_rec = max_sfx-min_sfx+1;
sorted_sfx_rec = (atn_sfx_rec **)
calloc(num_of_sorted_rec+2,sizeof(atn_sfx_rec **));
int pos;
for(int i = 0;i < num_of_sfx_rec;i++)
{
if(ascending)
{
pos = sfx_rec[i].val - min_sfx;
}
else
{
pos = max_sfx -sfx_rec[i].val;
}
this->sorted_sfx_rec[pos] = &sfx_rec[i];
}
rc = 0;
goto exit_func;
}
/* 昇順iiまたは降順で、英数字がある場合 */
ascending = chk_ascending();
descending = chk_descending();
if((ascending||descending ) && num_of_alpha_num != 0)
{
num_of_sorted_rec = max_sfx-min_sfx+ num_of_alpha_num+3;
sorted_sfx_rec = (atn_sfx_rec **)
calloc(num_of_sorted_rec+2,sizeof(atn_sfx_rec **));
int pos;
for(int i = 0;i < num_of_sfx_rec;i++)
{
if(sfx_rec[i].digit_flag == false)
{
continue;
}
if(ascending)
{
pos = sfx_rec[i].val - min_sfx;
}
else
{
pos = max_sfx -sfx_rec[i].val;
}
this->sorted_sfx_rec[pos] = &sfx_rec[i];
}
int num_pos = pos+1;
int si=0;
pos = 0;
for(;;)
{
/* get alpha_num */
for(;sisorted_sfx_rec[pos] = &sfx_rec[si];
si++;
pos ++;
if(si >= num_of_sfx_rec || pos >= num_of_sorted_rec)
break;
}
int alpha_pos = pos+1;
num_of_sorted_rec = ( alpha_pos> num_pos? alpha_pos : num_pos);
goto exit_func;
}
/* 数字のみで、整列してないとき降順に整列させる */
if(num_of_alpha_num==0)
{
num_of_sorted_rec = max_sfx-min_sfx+1;
sorted_sfx_rec = (atn_sfx_rec **)
calloc(num_of_sorted_rec+2,sizeof(atn_sfx_rec **));
int pos;
for(int i = 0;i < num_of_sfx_rec;i++)
{
pos = max_sfx -sfx_rec[i].val;
sorted_sfx_rec[pos] = &sfx_rec[i];
}
rc = 0;
goto exit_func;
}
/* 上記以外の場合 */
num_of_sorted_rec = num_of_sfx_rec;
sorted_sfx_rec = (atn_sfx_rec **)
calloc(num_of_sorted_rec,sizeof(atn_sfx_rec **));
for(int i = 0;i < num_of_sorted_rec;i++)
sorted_sfx_rec[i] = &sfx_rec[i];
exit_func:
return rc;
}
//
// 配列の範囲をとる
//
int atn_sfx::get_range(int &left, int &right)
{
if(sorted_sfx_rec[0] == NULL
|| sorted_sfx_rec[num_of_sorted_rec-1]== NULL)
{
return -1;
}
if(sorted_sfx_rec[0]->digit_flag == false)
{
left = num_of_sorted_rec-1;
right = 0;
return 0;
}
/* now 1st entry is digit */
if(ascending_1 || descending_1)
{
left = sorted_sfx_rec[0]->val;
right = sorted_sfx_rec[num_of_sorted_rec-1]->val;
return 0;
}
left = sorted_sfx_rec[0]->val;
if(ascending)
{
right = left + num_of_sorted_rec-1;
}
else
{
right = left - num_of_sorted_rec+1;
}
return 0;
}
//
//
// ダンプ関数
//
void atn_sfx::dump(void)
{
cout << "=== INPUT ===\n";
cout << "entry number " << num_of_sfx_rec << '\n';
for(int i=0;i