해시 알고리즘 - 폭 설 mpq 기술

포럼 에서 발췌:http://bbs.csdn.net/topics/300172062저장 하 다
 
폭 설 mpq 기술 을 사용 하 는 것 을 강력 히 추천 합 니 다. 저 는 개인 기기 에서 4000 만 개의 문자열 저장 을 실 현 했 습 니 다. 충돌 이 적 고 코드 가 필요 하 다 면 메 일 을 남 겨 주세요.
여 기 는 내 가 이전에 사 용 했 던 작은 프로그램 을 남 겨 두 었 다. 조금 만 고치 면 너의 요 구 를 만족 시 킬 수 있 을 것 이다.
#include <iostream>
 using namespace std;
 
#define nTableSize  40000000
 #define nMaxStrLen  20
 
unsigned long cryptTable[0x1000];
 typedef struct _MPQHASHTABLE
 {    
 char bExists;
 }MPQHASHTABLE;
 
MPQHASHTABLE    HashTable[nTableSize];
 int                HashATable[nTableSize];
 int                HashBTable[nTableSize]; 
 
char            data[nTableSize][nMaxStrLen];
 
class CHashForMpq
 {

 public:
  int insert_string(const char *string_in)
  {
   const int HASH_OFFSET = 0, HASH_A = 1, HASH_B = 2;//      
 /*  lpszString                     */
  unsigned int nHash = HashString(string_in, HASH_OFFSET);//     hash     
 unsigned int nHashA = HashString(string_in, HASH_A);//   hashA     
 unsigned int nHashB = HashString(string_in, HASH_B);//   hashB     
 unsigned int nHashStart = nHash % nTableSize;//        
 unsigned int nHashPos = nHashStart;//           
     
  while (HashTable[nHashPos].bExists)//     
{ 
 //      
 if (HashATable[nHashPos]  == nHashA && HashBTable[nHashPos] == nHashB) 
 break; //         ,     :1.     ,2.        
 else 
  nHashPos = (nHashPos + 1) % nTableSize;//        ,          ,           ,         
       
  if (nHashPos == nHashStart) 
  {
 cout<<"   ,      "<<endl;
  return 0; 
  }
 }
  /*     */
  if (!HashTable[nHashPos].bExists && (strlen(string_in) < nMaxStrLen))
  {   
  HashATable[nHashPos] = nHashA;
  HashBTable[nHashPos] = nHashB;
  strcpy(data[nHashPos], string_in);
  HashTable[nHashPos].bExists = 1;
            cout<<"   "<<string_in<<"    ,  "<<nHashPos<<endl;
  }
  else
  {
  if(HashTable[nHashPos].bExists)
 cout<<"   "<<string_in<<"      ,    "<<endl;
  else
 cout<<"   "<<string_in<<"    ,    "<<endl;
  }
  return nHashPos;

  }
 
  int search_string(const char *string_in)
  {
   const int HASH_OFFSET = 0, HASH_A = 1, HASH_B = 2;//      
 /*  lpszString                     */
  unsigned int nHash = HashString(string_in, HASH_OFFSET);//     hash     
 unsigned int nHashA = HashString(string_in, HASH_A);//   hashA     
 unsigned int nHashB = HashString(string_in, HASH_B);//   hashB     
 unsigned int nHashStart = nHash % nTableSize;//        
 unsigned int nHashPos = nHashStart;//           
         
  while (HashTable[nHashPos].bExists)//     
{ 
 //      
 if (HashATable[nHashPos]  == nHashA && HashBTable[nHashPos] == nHashB) 
 break; //         ,     :1.     ,2.        
 else 
  nHashPos = (nHashPos + 1) % nTableSize;//        ,          ,           ,         
       
  if (nHashPos == nHashStart) 
  cout<<"   "<<string_in<<"    "<<endl;
  return 0; 
 }
  if(strlen(data[nHashPos]))
  {
  cout<<"   "<<string_in<<"   "<<nHashPos<<endl;
  return nHashPos;
  }
  else
 
 cout<<"   "<<string_in<<"    "<<endl;

  }
 



/*     */
void prepareCryptTable()
 { 
 unsigned long seed = 0x00100001, index1 = 0, index2 = 0, i;
  
 for( index1 = 0; index1 < 0x100; index1++ )
 { 
  for( index2 = index1, i = 0; i < 5; i++, index2 += 0x100 )
 { 
  unsigned long temp1, temp2;
  seed = (seed * 125 + 3) % 0x2AAAAB;
  temp1 = (seed & 0xFFFF) << 0x10;
  seed = (seed * 125 + 3) % 0x2AAAAB;
  temp2 = (seed & 0xFFFF);
  cryptTable[index2] = ( temp1 | temp2 ); 
 } 
  } 
 }
 private:
     /*  dwHashType          lpszFileName   hash */
unsigned long HashString(const char *lpszFileName, unsigned long dwHashType )
 { 
  unsigned char *key  = (unsigned char *)lpszFileName;
  unsigned long seed1 = 0x7FED7FED;
  unsigned long seed2 = 0xEEEEEEEE;
  int ch;
 
 while( *key != 0 )
  { 
 ch = *key++;
 seed1 = cryptTable[(dwHashType << 8) + ch] ^ (seed1 + seed2);
     seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3; 
  }
 
 return seed1; 
  }
 
};
 
void main()
 {
 CHashForMpq cHashForMpq;
 cHashForMpq.prepareCryptTable();
     
     cHashForMpq.insert_string("abcdefghijklmnopqrstuvwxyz");
     cHashForMpq.insert_string("abcd");
     cHashForMpq.insert_string("ab");
 cHashForMpq.insert_string("ab");
 
cHashForMpq.search_string("abcd");
 
    cHashForMpq.search_string("efd");
 
   getchar();
 } 

좋은 웹페이지 즐겨찾기