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