2010-05-19 48 views
1

我需要創建一個哈希表,其中有一個鍵作爲字符串,並將值作爲int。我不能在我的目標上使用STL容器。有沒有適合此目的的哈希表類?使用STL的C++哈希表w/o

+3

你可以使用什麼*你在尋找關於實現散列表或替代現有實現的提示嗎? – 2010-05-19 15:23:53

+0

你最好有一個非常好的理由不使用STL。這可能是家庭作業嗎? – AshleysBrain 2010-05-19 15:29:56

+1

單詞目標意味着某種嵌入式系統給我。 – 2010-05-19 15:45:20

回答

2

這是我剛剛寫的一個很髒的C哈希。編譯,但未經本地測試。不過,這個想法在你需要的時候可以運行。這個性能完全依賴於keyToHash函數。我的版本不會高性能,但再次演示如何去做。


static const int kMaxKeyLength = 31; 
static const int kMaxKeyStringLength = kMaxKeyLength + 1; 

struct HashEntry 
{ 
    int value; 
    char key[kMaxKeyLength]; 
}; 

static const char kEmptyHash[2] = ""; 

static const int kHashPowerofTwo = 10; 
static const int kHashSize = 1 << kHashPowerofTwo; 
static const int kHashMask = kHashSize - 1; 

static const int kSmallPrimeNumber = 7; 

static HashEntry hashTable[kHashSize]; 

int keyToHash(const char key[]) 
{ 
    assert(strlen(key) < kMaxKeyLength); 

    int hashValue = 0; 
    for(int i=0; < strlen(key); i++) 
    { 
    hashValue += key[i]; 
    } 

    return hashValue; 
} 

bool hashAdd(const char key[], const int value) 
{ 
    int hashValue = keyToHash(key); 

    int hashFullSentinal = 0; 
    while(strcmp(hashTable[hashValue & kHashMask].key, kEmptyHash)) 
    { 
    hashValue += kSmallPrimeNumber; 

    if(hashFullSentinal++ >= (kHashSize - 1)) 
    { 
     return false; 
    } 
    } 

    strcpy(hashTable[hashValue & kHashMask].key, key); 
    hashTable[hashValue & kHashMask].value = value; 

    return true; 
} 

bool hashFind(const char key[], int *value) 
{ 
    int hashValue = keyToHash(key); 

    while(strcmp(hashTable[hashValue & kHashMask].key, kEmptyHash)) 
    { 
    if(!strcmp(hashTable[hashValue & kHashMask].key, key)) 
    { 
     *value = hashTable[hashValue & kHashMask].value; 
     return true; 
    } 
    } 

    return false; 
} 

bool hashRemove(const char key[]) 
{ 
    int hashValue = keyToHash(key); 

    while(strcmp(hashTable[hashValue & kHashMask].key, kEmptyHash)) 
    { 
    if(!strcmp(hashTable[hashValue & kHashMask].key, key)) 
    { 
     hashTable[hashValue & kHashMask].value = 0; 
     hashTable[hashValue & kHashMask].key[0] = 0; 
     return true; 
    } 
    } 

    return false; 
} 

0

您可以使用Boost,也就是unordered associative containerboost::unordered_map,其中按照哈希表來實現。

+0

儘管海報反對STL會是有趣的。如果是使用模板的事實,那麼提升也是一樣。 – 2010-05-19 15:25:22

+1

@mjmarsh:沒錯,但在這種情況下,更多的信息會有幫助。就我而言,即使排除STL也是不合理的要求,但由於沒有提及其他限制,我認爲使用Boost庫可能是明顯的選擇。 – 2010-05-19 15:28:24

0

由於STL沒有散列表容器,所以這是一個有爭議的問題; std :: map將是替代方案。對於大多數目的而言,沒有理由不使用std :: map。對於需要散列表的應用,boost :: unordered_map是最好的選擇(我認爲它與在新的C++ TR1標準中定義的散列表相匹配。有些編譯器 - 但我不能命名它們 - 可能會將TR1散列表作爲的std :: tr1 :: unordered_map

1

在,你知道你的時間提前鍵列表的情況下(或其某些超集),您可以使用perfect hash function生成器如gperfgperf將吐出C或C++代碼。

(您可能會編輯做一些工作,實際上建立一個容器,雖然給定了散列函數)。