-
Notifications
You must be signed in to change notification settings - Fork 0
Update main.cpp #9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
kindofman
wants to merge
2
commits into
master
Choose a base branch
from
kindofman-patch-9
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,183 @@ | ||
| /* | ||
| Задача 8. Хеш-таблица (10 баллов) | ||
| Реализуйте структуру данных типа “множество строк” на основе динамической хеш-таблицы с открытой адресацией. | ||
| Хранимые строки непустые и состоят из строчных латинских букв. | ||
| Хеш-функция строки должна быть реализована с помощью вычисления значения многочлена методом Горнера. | ||
| Начальный размер таблицы должен быть равным 8-ми. Перехеширование выполняйте при добавлении элементов в случае, | ||
| когда коэффициент заполнения таблицы достигает 3/4. | ||
| Структура данных должна поддерживать операции добавления строки в множество, удаления строки из множества и проверки | ||
| принадлежности данной строки множеству. | ||
|
|
||
| 1_2. Для разрешения коллизий используйте двойное хеширование. | ||
|
|
||
| Формат входных данных | ||
| Каждая строка входных данных задает одну операцию над множеством. Запись операции состоит из типа операции и следующей за | ||
| ним через пробел строки, над которой проводится операция. | ||
| Тип операции – один из трех символов: | ||
| + означает добавление данной строки в множество; | ||
| - означает удаление строки из множества; | ||
| ? означает проверку принадлежности данной строки множеству. | ||
| При добавлении элемента в множество НЕ ГАРАНТИРУЕТСЯ, что он отсутствует в этом множестве. При удалении элемента из множества | ||
| НЕ ГАРАНТИРУЕТСЯ, что он присутствует в этом множестве. | ||
| Формат выходных данных | ||
| Программа должна вывести для каждой операции одну из двух строк OK или FAIL, в зависимости от того, встречается ли данное | ||
| слово в нашем множестве. | ||
|
|
||
| */ | ||
|
|
||
| #include <cassert> | ||
| #include <iostream> | ||
| #include <string> | ||
| #include <memory.h> | ||
| #include <stdint.h> | ||
| #include <vector> | ||
| #include <queue> | ||
| #include <ctime> | ||
|
|
||
| #include <assert.h> | ||
|
|
||
| using std::cin; | ||
| using std::cout; | ||
| using std::vector; | ||
| using std::string; | ||
| using std::overflow_error; | ||
| using std::endl; | ||
|
|
||
| struct GetHash { | ||
| size_t operator() ( const string& key, size_t m ) const { | ||
| int a = 3571; | ||
| size_t hash_ = 0; | ||
| for (int i = 0; i < key.length(); i++) { | ||
| hash_ = ( hash_ * a + key[i] ) % m; | ||
| } | ||
| return hash_; | ||
| } | ||
| }; | ||
|
|
||
| template<class T, class H> | ||
| class HashTable { | ||
| public: | ||
| explicit HashTable(size_t initial_size, H get_hash); | ||
| bool has(const T& key) const; | ||
| bool add(const T& key); | ||
| bool remove(const T& key); | ||
|
|
||
| private: | ||
| const T DELETED_KEY = "Deleted"; | ||
| const T EMPTY = ""; | ||
| H get_hash; | ||
| bool is_Nil( const T& key ) { return key != DELETED_KEY ? key.empty() : true; } | ||
| size_t probe( size_t hash, int i, const T& key ) const; | ||
| vector<T> table; | ||
| size_t limit; | ||
| void rehash(); | ||
| }; | ||
|
|
||
| template<class T, class H> | ||
| HashTable<T, H>::HashTable(size_t initial_size, H get_hash) : table(initial_size, EMPTY), limit(initial_size) {} | ||
|
|
||
| template<class T, class H> | ||
| void HashTable<T, H>::rehash() { | ||
| vector<T> temp_table( table.size()*2, EMPTY ); | ||
| table.swap( temp_table ); | ||
| limit = table.size() * 3 / 4; | ||
| for( int i = 0; i < temp_table.size(); i++ ) { | ||
| if ( !is_Nil( temp_table[i] ) ) { | ||
| add( temp_table[i] ); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| template<class T, class H> | ||
| size_t HashTable<T, H>::probe(size_t hash, int i, const T& key ) const { | ||
| int sum_of_letters = 0; | ||
| if ( i == 0 ) { return hash; } //если i==0, то не будет лишний раз высчитывать h2 | ||
| for ( int i = 0; i < key.length(); i++ ) { | ||
| sum_of_letters += key[i]; | ||
| } | ||
| return (hash + i * ( 2*sum_of_letters + 1 ) ) % table.size(); | ||
| } | ||
|
|
||
| template<class T, class H> | ||
| bool HashTable<T, H>::has(const T& key) const { | ||
| assert(!key.empty()); | ||
| const size_t hash = get_hash(key, table.size()); | ||
| for ( int i = 0; i < table.size(); ++i ) { | ||
| size_t idx = probe( hash, i, key ); | ||
| if ( table[idx].empty() ) { | ||
| return false; | ||
| } | ||
| if ( table[idx] == key ) { | ||
| return true; | ||
| } | ||
| } | ||
| throw overflow_error( " no more space for a key " ); | ||
| } | ||
|
|
||
| // Вставка ключа в хеш-таблицу (без учета удаленных элементов). | ||
| template<class T, class H> | ||
| bool HashTable<T, H>::add(const T& key) { | ||
| assert(!key.empty()); | ||
| const size_t hash = get_hash(key, table.size()); | ||
| for ( int i = 0; i < table.size(); ++i ) { | ||
| size_t idx = probe( hash, i, key ); | ||
| if ( table[idx] == key ) { return false; } | ||
| if ( is_Nil( table[idx] ) ) { | ||
| if ( table[idx] != DELETED_KEY ) limit--; | ||
| table[idx] = key; | ||
| if ( limit == 0 ) rehash(); | ||
| return true; | ||
| } | ||
| } | ||
| throw overflow_error( " no more space for a key " ); | ||
| } | ||
|
|
||
| template<class T, class H> | ||
| bool HashTable<T, H>::remove(const T& key) { | ||
| assert(!key.empty()); | ||
| const size_t hash = get_hash(key, table.size()); | ||
| for ( int i = 0; i < table.size(); ++i ) { | ||
| size_t idx = probe( hash, i, key ); | ||
| if ( table[idx] == key ) { | ||
| table[idx] = DELETED_KEY; | ||
| return true; | ||
| } | ||
| if ( table[idx].empty() ) { | ||
| return false; | ||
| } | ||
| } | ||
| throw overflow_error( " no more space for a key " ); | ||
| } | ||
|
|
||
| int main() { | ||
| GetHash get_hash; | ||
| HashTable<string, GetHash> table( 8, get_hash ); | ||
| char command = ' '; | ||
| string key; | ||
|
|
||
| while (cin >> command >> key) { | ||
| switch (command) { | ||
| case '?': | ||
| cout << (table.has(key) ? "OK" : "FAIL") << endl; | ||
| break; | ||
| case '+': | ||
| cout << (table.add(key) ? "OK" : "FAIL") << endl; | ||
| break; | ||
| case '-': | ||
| cout << (table.remove(key) ? "OK" : "FAIL") << endl; | ||
| break; | ||
| } | ||
| } | ||
| return 0; | ||
| } | ||
|
|
||
| /* | ||
|
|
||
| + hello | ||
| + bye | ||
| ? bye | ||
| + bye | ||
| - bye | ||
| ? bye | ||
| ? hello | ||
| */ | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Давай сделаем Хеш-таблицу шаблонной с хеш-функцией передаваемой снаружи
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Готово