HashTable в C ++

0

Мне нужно реализовать HashTable в C++. Я думал об использовании Array. Но я точно не знаю, как создать массив фиксированного размера. Допустим, что мой класс называется HT. В конструкторе я хочу указать размер массива, но я не знаю, как это сделать. У меня размер size_type членов; и string [] t; в заголовке HT. Как я могу определить размер t от конструктора?

HT(size_type s):size(s) {

}

Если невозможно, какую структуру данных я должен использовать для реализации хеш-таблицы?

  • 0
    Если вы знаете размер во время компиляции, вы можете использовать std::array . Если размер не известен до времени выполнения, вы можете использовать std::vector .
  • 0
    Можно ли использовать вектор для реализации хеш-таблицы? Я получу размер в качестве аргумента для конструктора.
Показать ещё 1 комментарий
Теги:

3 ответа

0

Вы можете сделать как std :: array и сделать размер параметром времени компиляции.

Если нет, то нет смысла пытаться избежать std :: vector, так как вы будете делать динамическое размещение независимо от того, что.

Итак, пока вы могли

struct HT
{ 
    HT(size_t size) : _size(size), _data(new std::string[size]) {}
private:
    size_t const _size;
    std::unique_ptr<std::string[]> _data;
}; 

Это только делает ваш класс более сложным, менее гибким и, как правило, менее элегантным, поэтому я бы пошел с вектором:

#include <memory> 

using namespace std; 

struct HT
{ 
    HT(size_t size) : _size(size), _data(new std::string[size]) {}
  private:
    size_t const _size;
    std::unique_ptr<std::string[]> _data;
}; 

#include <vector> 
struct HT2
{ 
    HT2(size_t size) : _data(size) {}
  private:
    std::vector<std::string> _data;
}; 


int main()
{
    HT  table1(31);
    HT2 table2(31);
} 
0

В конструкторе для HT класса передайте (или по умолчанию 0) переменную (s) размера, чтобы указать размер массива. Затем установите t в новый массив строк размера s

Итак, что-то вроде:

 HT::HT(size_type s)
 {
     t = new string[s];
 }
  • 0
    Но чем мне придется удалить это правильно? я должен использовать уникальный указатель?
  • 0
    Исходя из моего опыта, управление своими указателями самостоятельно всегда идеально. Но, возможно, кто-то с немного большим опытом может лучше понять, когда лучше использовать уникальные указатели
Показать ещё 6 комментариев
-1

Большинство предложений, похоже, предполагают, что он реализует ваш контейнерный класс хеш-таблицы с точки зрения стандартной библиотеки. Интересно, какова ваша ситуация; как это получилось, эта "необходимость" для реализации примитивного класса контейнера? Это действительно здорово, если вы зависите от другой библиотеки?

Однако все остальные думают так. Я думаю, std действительно является фундаментальным компонентом языка C++, теперь...

Глядя на другие ответы, я вижу std :: vector, std :: string, std :: unique_pointer...

Но дорога не заканчивается. Даже не близко.

#include <unordered_map>
#include <string>
#include <iostream>

template <typename T>
class CHashTable {
    typedef std::string KEYTYPE;
    struct HASH_FUNCTOR {
        size_t operator ()(const KEYTYPE& key) const {
            return CHashTable::MyAmazingHashFunc(key);
    }   };
    typename std::unordered_map<KEYTYPE, T, HASH_FUNCTOR> m_um;
public:
    static size_t MyAmazingHashFunc(const KEYTYPE& key) {
        size_t h = key.length();
        for(auto c : key) {
            h = h*143401 + static_cast<size_t>(c)*214517 + 13;
        }
        h = (~h << (sizeof(h)*4)) + (h >> (sizeof(h)*4));
        return h;
    }

    template <typename KT>
    T& operator [] (const KT& key) {
        return m_um[KEYTYPE(key)];
    }
    template <typename KT>
    const T& operator [] (const KT& key) const {
        return m_um.at(KEYTYPE(key));
    }
    void DeleteAll() {
        m_um.clear();
    }
    template <typename KT>
    void Delete(const KT& key) {
        m_um.erase(KEYTYPE(key));
    }
    template <typename KT>
    bool Exists(const KT& key) const {
        const auto fit = m_um.find(KEYTYPE(key));
        return fit != m_um.end();
    }
};

int main() {
    CHashTable<int> ht;
    // my Universal Translator, a "WIP"
    ht["uno"]  = 1;
    ht["un"]   = 1;
    ht["one"]  = 1;
    ht["dos"]  = 2;
    ht["deux"] = 2;
    ht["two"]  = 2;

    const char* key = "deux";
    int value = ht[key];
    std::cout << '[' << key << "] => " << value << std::endl;

    key = "un";
    bool exists = ht.Exists(key);
    std::cout << '[' << key << "]  "
        << (exists ? "exists" : "does not exist") << std::endl;

    key = "trois";
    exists = ht.Exists(key);
    std::cout << '[' << key << "]  "
        << (exists ? "exists" : "does not exist") << std::endl;

    return 0;
}

main():

[deux] => 2
[un]  exists
[trois]  does not exist

И это даже не конец Hash Table std :: Highway! Конец является резким, в классе, который просто наследуется от std :: unordered_map. Но я бы никогда не предложил ЭТО в ответе, потому что я не хочу встречаться с саркастическим смартфоном.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню