Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <string>
- #define PRIME_SIZE 29 // Не говорящее имя переменной, HASH_TABLE_DEF_SIZE куда лучше
- using namespace std;
- class Person // Класс, который содержит немного информации о человеке.
- {
- public:
- Person *next; // Нарушение инкапсуляции, атрибуты класса в общем лучае не должны быть public
- string name;
- string surname;
- int age;
- Person() // Нет инициализации атрибутов (age и next) по умолчанию в этом конструкторе
- {
- this->next = NULL;
- }
- //Person (string name, string surname, int age = 0)
- Person (string name_, string surname_, int age_ = 0) : name(name), surname(surname), age(age_), next(NULL) // лучше так, почему лучше гуглите
- {
- this->name = name; // это удалить, инициализация уже была проведена в списке инициализации
- this->surname = surname;
- this->age = age;
- this->next = NULL;
- }
- ~Person()
- {
- //cout << "Delete " << this->name << endl; // из финального кода такие комментарии должны быть убраны
- if ( this->next != NULL ) // удаление нулевого указателя валидно, потому вместо такой проверки лучше убедитесь что он был проинициализирован в конструкторе
- {
- delete this->next;
- }
- }
- };
- // контейнер нужно сделать шаблонным
- class HashTable // Хеш-таблица, представленная в виде массива элементов (которые в свою очередь представляют список).
- {
- Person *table[PRIME_SIZE]; // использование "голого массива". или замените на вектор, или используйте std::array
- // вообще наличие комментариев говорит о том, что код не очень хорош. хороший код можно прочитать и без комментариев
- // потому лучше постарайтесь написать понятный код, чем полупонятный с объясняющими комментариями.
- // Самая простоя хеш-функция. Считает сумму ASCII кодов, делит на константу и
- // получает остаток от деления.
- // зачем эта функция сделана статической? почему не обойтись простой функцией?
- static int hash ( string str )
- {
- int asciisum = 0;
- for ( int i = 0; i < str.length(); i++ ) // этот циакл можно заменить на std::accumulate
- {
- asciisum += str[i];
- }
- return asciisum % PRIME_SIZE;
- }
- public:
- HashTable()
- {
- // а что если PRIME_SIZE будет отрицательный?
- // при обоходе по индексу лучше использовать size_t, а не int. подробней си. на viva64
- for ( int i = 0; i < PRIME_SIZE; i++ )
- {
- table[i] = NULL;
- }
- }
- ~HashTable()
- {
- //cout << "Delete table\n";
- for ( int i = 0; i < PRIME_SIZE; i++ )
- {
- delete table[i];
- }
- }
- // Вставляет элемент в таблицу
- void push ( string name, string surname, int age ) // лучше название "insert"
- {
- int hashNumber = hash(name); // переменные которые не меняются, должны быть описаны как const
- Person *pers = new Person(name, surname, age);
- Person *place = table[hashNumber];
- if ( place == NULL )
- {
- table[hashNumber] = pers;
- return;
- }
- while ( place->next != NULL )
- {
- place = place->next;
- }
- place->next = pers;
- }
- // Получает элемент из таблицы по его имени.
- Person* find ( string name )
- {
- int hashNumber = hash ( name );
- Person *result = table[hashNumber];
- if ( !result )
- {
- // очень плохо, в классах контейнерах не должно быть никаких cout,
- // это не задача класса выводить что-то.
- // а если этот код будет использоваться в оконном приложении, там cout будет доступен?
- cout << "Element not found" << endl;
- return NULL;
- }
- while ( result->name != name )
- {
- if ( !result->next )
- {
- cout << "Element not found" << endl;
- break;
- }
- result = result->next;
- }
- return result;
- }
- };
- int main()
- {
- HashTable newTable;
- newTable.push("Artyom", "Devyatov", 20);
- newTable.push("Vasya", "Petrov", 23);
- newTable.push("Ilja", "Saveljev", 28);
- newTable.push("Ilaj", "Savanna", 43); // Имеет коллизию с Ilja
- newTable.push("Dmitry", "Kuzychev", 31);
- Person * search = newTable.find("Ilaj");
- if ( search )
- {
- cout << search->surname << endl;
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement