Хеширование с++
#include <iostream>
#include <string>
#include <list>
#include <vector>
#include <iterator>
using namespace std;
vector< list<string>*> hash_table;
void hash_(string word) {
int sum = 0;
int num = 0;
hash_table.resize(10);
char numbers1[] = { '0','А', 'Б', 'В', 'Г', 'Д', 'Е', 'Ё', 'Ж', 'З', 'И', 'К', 'Л', 'М', 'Н', 'О', 'П', 'Р', 'С', 'Т', 'У', 'Ф', 'Х', 'Ц', 'Ч', 'Ш', 'Щ', 'Ъ', 'Ы', 'Ь', 'Э', 'Ю', 'Я' };
char numbers2[] = { '0','а', 'б', 'в', 'г', 'д', 'е', 'ё', 'ж', 'з', 'и', 'к', 'л', 'м', 'н', 'о', 'п', 'р', 'с', 'т', 'у', 'ф', 'х', 'ц', 'ч', 'ш', 'щ', 'ъ', 'ы', 'ь', 'э', 'ю', 'я' };
for (int k = 0; k < word.size(); k++) {
for (int m = 0; m < sizeof(numbers1); m++) {
if (word[k] == numbers1[m]) {
sum += m;
num++;
}
}
for (int t = 0; t < sizeof(numbers2); t++) {
if (word[k] == numbers2[t]) {
sum += t;
num++;
}
}
}
sum = sum % 10;
list<string> list1;
list1.push_front(word);
list<string>* ptr = &list1;
hash_table[sum] = ptr;
cout << "Слово " << num << " : " << sum << endl;
sum = 0;
}
int getHash(string word) {
int sum = 0;
int num = 0;
char numbers1[] = { '0','А', 'Б', 'В', 'Г', 'Д', 'Е', 'Ё', 'Ж', 'З', 'И', 'К', 'Л', 'М', 'Н', 'О', 'П', 'Р', 'С', 'Т', 'У', 'Ф', 'Х', 'Ц', 'Ч', 'Ш', 'Щ', 'Ъ', 'Ы', 'Ь', 'Э', 'Ю', 'Я' };
char numbers2[] = { '0','а', 'б', 'в', 'г', 'д', 'е', 'ё', 'ж', 'з', 'и', 'к', 'л', 'м', 'н', 'о', 'п', 'р', 'с', 'т', 'у', 'ф', 'х', 'ц', 'ч', 'ш', 'щ', 'ъ', 'ы', 'ь', 'э', 'ю', 'я' };
for (int k = 0; k < word.size(); k++) {
for (int m = 0; m < sizeof(numbers1); m++) {
if (word[k] == numbers1[m]) {
sum += m;
num++;
}
}
for (int t = 0; t < sizeof(numbers2); t++) {
if (word[k] == numbers2[t]) {
sum += t;
num++;
}
}
}
sum = sum % 10;
return sum;
}
void string_find(string word) {
int num = getHash(word);
cout<< *hash_table[num]->begin();
}
int main()
{
setlocale(LC_ALL, "Russian");
cout << "Задание 1: " << endl;
vector<string> words = { "Ноутбук","Компьютер","Телефон","Планшет","Приставка","Умные часы","Наушники" };
//hash1(words, 7, listwords);
for (int i = 0; i < 7; i++) {
hash_(words[i]);
}
string_find(words[0]);
cout << endl << "Задание 2: " << endl;
return 0;
}
Сделал функцию хеширования,которая берет сумму номеров букв в алфавите и берет остаток от деления на 10(да функция очень плохая,но по заданию так надо). Вообщем я слова заношу в разные списки.И указатели на списки храню в массиве.Но в функции поиска слова,я не могу получить слово из списка. Вылазит исключение: нарушение доступа для чтения. _Mycont было 0xDDDDDDDD.Что не так?
Ответы (1 шт):
Проблема в том, что вы присваиваете указатель на локальный объект, который тут же при выходе из функции уничтожается. И у вас сохраненный указатель указывает в никуда.
list<string> list1; // создается локальный объект
list<string>* ptr = &list1;
hash_table[sum] = ptr; // сохраняется указатель на него
} // в конце функции локальный list1 уничтожается, и теперь сохраненный указатель указывает в никуда
И при обращении по указателю на несуществующий объект происходит ошибка.
Поскольку вы работаете с контейнерами, нет смысла хранить указатели. Храните сразу списки:
vector< list<string> > hash_table(10); // поскольку максимум будет 10 строк
// и кстати необязательно использовать `list<string>`, можно использовать `vector<string>`
И тогда использование будет
hash_table[sum].push_back(word);
Несколько замечаний:
- уже есть функция
int getHash(string word) {}, зачем дублирование кода в_hash()? - Поскольку в
getHash()массивы одинаковые, то достаточно 1 цикла внутри цикла по слову
for (int m = 0; m < sizeof(numbers1); m++)
if (word[k] == numbers1[m] || word[k] == numbers2[m])
sum += m;
mв этом цикле должна начинаться с 1, т.к. нулевой элемент это ноль, а не буква- вывод списка в поток неправильный.
cout<< *hash_table[num]->begin();вы выводите значение итератора, в данный момент указывающего на начало списка, что абсолютно бессмысленное действие. Нужно в цикле пройти по списку и вывести каждый элемент:
for(auto item : hash_table[num])
cout << item << "\t";