user-0 提问: hash表处理文件信息

回复:
user: user-0
content: 没人回帖！！！！！

user: user-0
content: #include <stdio.h> #include <string.h> #include <assert.h> #include <stdlib.h> /**文件内容 global|test_global|10:12:23 logger|test_logger|20:12:56 */  typedef struct info__ {     char name[128];     char func[128];     int  num[10]; }Info;  Info Infotable[1000]; ///<  这里定义一个 Info 类型的数组或者Info* 类型的数组，两者那个好一些？   void write_info() {     FILE* fp = fopen("filte_file", "r");     assert(fp != NULL);     Info* info = (Info*)malloc(sizeof(Info));     assert(info != NULL);          char tmp[1024];     char* p = NULL;     char dst[512];          unsigned int index = 0;          while(fgets(tmp, 1024, fp) != NULL)     {          int count = 0;         p = strtok(tmp, "|");                strcpy(info->name, p);                  if((p = strtok(NULL, "|")) != NULL)             strcpy(info->func, p);                             if((p = strtok(NULL, "|")) != NULL)         {                         strcpy(dst, p);             p = strtok(dst, ":");             info->num[count++] = atoi(p);                         while((p = strtok(NULL, ":")) && count <= 10)             {                 info->num[count++] = atoi(p);                            }         }           printf("%s\n", info->name);         printf("%s\n", info->func);         int i = 0;         for(i; i < count; i++)         {             printf("%d ", info->num[i]);         }         printf("\n");     }        ///<  如果是定义的Info 类型的数组     ///<  这里这么将 Info* info这么变量存在数组中     ///<  Infotable[0] = *info;   不可行     ///<  如果是Info* 类型的数组     ///<  Infotable[0] = info;  不可行     fclose(fp); }            int main() {     write_info();     return 0; }

user: user-1
content: 引用 3 楼 u012889234 的回复:[quote=引用 2 楼 zhao4zhong1 的回复:] 搜“暴雪哈希算法” 那个用不上吧，太复杂了！！[/quote] 复杂吗？总共也就218行，注释都算进去了。

user: user-1
content: 拿来主义！ ///////////////////////////////////////////////////////////////////////////// // Name:        DebugMain.cpp // Purpose:     测试Hash算法封装的类，完成索引表的填充和查找功能的测试。 // Author:      陈相礼 // Modified by: // Created:     07/30/09 // RCS-ID:      $Id: treetest.h 43021 2009-07-30 16:36:51Z VZ $ // Copyright:   (C) Copyright 2009, TSong Corporation, All Rights Reserved. // Licence: ///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // 测试参数设定宏 #define TESTNUM 32 #include <iostream> #include <fstream> #include "HashAlgo.h" using namespace std; ////////////////////////////////////////////////////////////////////////// // 测试主函数开始 int main( int argc, char **argv ) {     int i;     CHashAlgo hash_test( TESTNUM );     cout << "取得初始化散列索引表长为：" << hash_test.GetTableLength() << endl;     bool is_success = hash_test.SetHashTable( "test" );     if ( is_success ) {         cout << "散列结果一：成功！" << endl;     } else {         cout << "散列结果一：失败！" << endl;     }     is_success = hash_test.SetHashTable( "测试" );     if ( is_success ) {         cout << "散列结果二：成功！" << endl;     } else {         cout << "散列结果二：失败！" << endl;     }     long pos = hash_test.GetHashTablePos( "test" );     cout << "查找测试字符串：\"test\" 的散列位置：" << pos << endl;     pos = hash_test.GetHashTablePos( "测试" );     cout << "查找测试字符串：“测试” 的散列位置：" << pos << endl;     //////////////////////////////////////////////////////////////////////////     // 散列测试     for (i = 0; i < TESTNUM; i++ ) {         char buff[32];         sprintf(buff, "abcdefg%d.", i);         is_success = hash_test.SetHashTable(buff);         is_success ? cout << buff << "散列结果：成功！位置：" << hash_test.testid << endl : cout << buff << "散列结果：失败！" << endl;     }     system( "pause" );     //////////////////////////////////////////////////////////////////////////     // 查找测试     for (i = 0; i < TESTNUM; i++ ) {         char buff[32];         sprintf(buff, "abcdefg%d.", i);         pos = hash_test.GetHashTablePos( buff );         pos != -1 ?  cout << "查找测试字符串："<< buff <<" 的散列位置：" << pos << endl : cout << buff << "存在冲突！" << endl;     }     system( "pause" );     return 0; }  ///////////////////////////////////////////////////////////////////////////// // Name:        HashAlgo.h // Purpose:     使用魔兽Hash算法，实现索引表的填充和查找功能。 // Author:      陈相礼 // Modified by: // Created:     07/30/09 // RCS-ID:      $Id: treetest.h 43021 2009-07-30 16:36:51Z VZ $ // Copyright:   (C) Copyright 2009, TSong Corporation, All Rights Reserved. // Licence: ///////////////////////////////////////////////////////////////////////////// #pragma warning(disable:4996) #define MAXFILENAME 255     // 最大文件名长度 #define MAXTABLELEN 1024    // 默认哈希索引表大小 ////////////////////////////////////////////////////////////////////////// // 测试宏定义，正式使用时关闭 #define DEBUGTEST 1 ////////////////////////////////////////////////////////////////////////// // 哈希索引表定义 typedef struct MPQHASHTABLEtag {     long nHashA;     long nHashB;     bool bExists;     char test_filename[MAXFILENAME]; } MPQHASHTABLE; ////////////////////////////////////////////////////////////////////////// // 对哈希索引表的算法进行封装 class CHashAlgo {     public: #if DEBUGTEST     long  testid;   // 测试之用 #endif CHashAlgo( const long nTableLength = MAXTABLELEN )// 创建指定大小的哈希索引表，不带参数的构造函数创建默认大小的哈希索引表 {     prepareCryptTable();     m_tablelength = nTableLength;     m_HashIndexTable = new MPQHASHTABLE[nTableLength];     for ( int i = 0; i < nTableLength; i++ ) {         m_HashIndexTable[i].nHashA = -1;         m_HashIndexTable[i].nHashB = -1;         m_HashIndexTable[i].bExists = false;         m_HashIndexTable[i].test_filename[0] = '\0';     } } void prepareCryptTable();                                               // 对哈希索引表预处理 unsigned long HashString(char *lpszFileName, unsigned long dwHashType); // 求取哈希值 long GetHashTablePos( char *lpszString );                               // 得到在定长表中的位置 bool SetHashTable( char *lpszString );                                  // 将字符串散列到哈希表中 unsigned long GetTableLength(void); void SetTableLength( const unsigned long nLength ); ~CHashAlgo() {     if ( NULL != m_HashIndexTable ) {         delete []m_HashIndexTable;         m_HashIndexTable = NULL;         m_tablelength = 0;     } } protected: private: unsigned long cryptTable[0x500]; unsigned long m_tablelength;    // 哈希索引表长度 MPQHASHTABLE *m_HashIndexTable; };  ///////////////////////////////////////////////////////////////////////////// // Name:        HashAlgo.cpp // Purpose:     使用魔兽Hash算法，实现索引表的填充和查找功能。 // Author:      陈相礼 // Modified by: // Created:     07/30/09 // RCS-ID:      $Id: treetest.h 43021 2009-07-30 16:36:51Z VZ $ // Copyright:   (C) Copyright 2009, TSong Corporation, All Rights Reserved. // Licence: ///////////////////////////////////////////////////////////////////////////// #include "windows.h" #include "HashAlgo.h" ////////////////////////////////////////////////////////////////////////// // 预处理 void CHashAlgo::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 );         }     } } ////////////////////////////////////////////////////////////////////////// // 求取哈希值 unsigned long CHashAlgo::HashString(char *lpszFileName, unsigned long dwHashType) {     unsigned char *key = (unsigned char *)lpszFileName;     unsigned long seed1 = 0x7FED7FED, seed2 = 0xEEEEEEEE;     int ch;     while(*key != 0) {         ch = toupper(*key++);         seed1 = cryptTable[(dwHashType << 8) + ch] ^ (seed1 + seed2);         seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3;     }     return seed1; } ////////////////////////////////////////////////////////////////////////// // 得到在定长表中的位置 long CHashAlgo::GetHashTablePos(char *lpszString) {     const unsigned long HASH_OFFSET = 0, HASH_A = 1, HASH_B = 2;     unsigned long nHash = HashString(lpszString, HASH_OFFSET);     unsigned long nHashA = HashString(lpszString, HASH_A);     unsigned long nHashB = HashString(lpszString, HASH_B);     unsigned long nHashStart = nHash % m_tablelength,                                nHashPos = nHashStart;     while ( m_HashIndexTable[nHashPos].bExists) {         if (m_HashIndexTable[nHashPos].nHashA == nHashA && m_HashIndexTable[nHashPos].nHashB == nHash)             return nHashPos;         else             nHashPos = (nHashPos + 1) % m_tablelength;         if (nHashPos == nHashStart)             break;     }     return -1; //没有找到 } ////////////////////////////////////////////////////////////////////////// // 通过传入字符串，将相应的表项散列到索引表相应位置中去 bool CHashAlgo::SetHashTable( char *lpszString ) {     const unsigned long HASH_OFFSET = 0, HASH_A = 1, HASH_B = 2;     unsigned long nHash = HashString(lpszString, HASH_OFFSET);     unsigned long nHashA = HashString(lpszString, HASH_A);     unsigned long nHashB = HashString(lpszString, HASH_B);     unsigned long nHashStart = nHash % m_tablelength,                                nHashPos = nHashStart;     while ( m_HashIndexTable[nHashPos].bExists) {         nHashPos = (nHashPos + 1) % m_tablelength;         if (nHashPos == nHashStart) { #if DEBUGTEST             testid = -1; #endif             return false;         }     }     m_HashIndexTable[nHashPos].bExists = true;     m_HashIndexTable[nHashPos].nHashA = nHashA;     m_HashIndexTable[nHashPos].nHashB = nHash;     strcpy( m_HashIndexTable[nHashPos].test_filename, lpszString ); #if DEBUGTEST     testid = nHashPos; #endif     return true; } ////////////////////////////////////////////////////////////////////////// // 取得哈希索引表长 unsigned long CHashAlgo::GetTableLength(void) {     return m_tablelength; } ////////////////////////////////////////////////////////////////////////// // 设置哈希索引表长 void CHashAlgo::SetTableLength( const unsigned long nLength ) {     m_tablelength = nLength;     return; }

user: user-0
content: 引用 2 楼 zhao4zhong1 的回复:搜“暴雪哈希算法” 那个用不上吧，太复杂了！！

user: user-1
content: 搜“暴雪哈希算法”

user: user-0
content: 来人跟帖啊！！！