Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.88/104: Рейтинг темы: голосов - 104, средняя оценка - 4.88
1 / 1 / 0
Регистрация: 20.05.2020
Сообщений: 32
1

Хэширование и поиск

02.04.2021, 10:12. Показов 19157. Ответов 3

Author24 — интернет-сервис помощи студентам
Прошу помощи студентке 2 курса... В С++ очень слаба, прошу прощения за корявый код. Задание:
1. Разработать подпрограмму хеширования массива целых чисел методом прямого связывания и подпрограмму поиска в хэш-таблице элемента по заданному ключу. Вывести на экран построенную хэш-таблицу.
Номер ячейки 0 1 2 3 … … m-1
Число
2. Реализовать подпрограмму хеширования массива целых чисел методом открытой адресации. Для разрешения коллизий использовать линейные и квадратичные пробы.
Вывести на экран заполненные хеш-таблицы для m=11 в виде
3. Подсчитать и сравнить количество коллизий при линейных и квадратичных пробах. Построить таблицу и проанализировать полученные результаты:
4. Организовать поиск элемента с заданным ключом для метода открытой адресации (линейные и квадратичные пробы).

Реализация пока такая:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
#include "pch.h"
#include <iostream>
 
using namespace std;
 
int m; // Размер хеш-таблицы
int table[100]; // Хеш-таблица
int n; // Размер массива чисел
int a[100]; // Массив чисел
bool overflow; // Равна true, если было переполнение таблицы
int collisions; // Количество коллизий
// Вычисляет хеш-функцию
int HashF(int num)
{
    return num % m;
}
// Создает хеш-таблицу методом линейных проб
void CreateTable1()
{
    int i;
    for (i = 0; i < m; i++) // Очищаем хэш-таблицу
        table[i] = 0;
    collisions = 0;
    int h, h0, g;
    for (i = 0; i < n; i++) {
        h = HashF(a[i]);
        h0 = h;
        g = 1;
        while (1) {
            if (table[h] == a[i]) // Если число повторяется
                break;
            if (table[h] == 0) { // Если нашли пустое место в хэш-таблице
                table[h] = a[i];
                break;
            }
            if (g >= m) { // Если переполнение
                overflow = true;
                return;
            }
            collisions++;
            h = h0 + g;
            if (h >= m)
                h -= m;
            g++;
        }
    }
    overflow = false;
}
 
// Создает хеш-таблицу методом квадратичных проб
void CreateTable2()
{
    int i;
    for (i = 0; i < m; i++) // Очищаем хэш-таблицу
        table[i] = 0;
    collisions = 0;
    int h, d;
    for (i = 0; i < n; i++) {
        h = HashF(a[i]);
        d = 1;
        while (1) {
            if (table[h] == a[i]) // Если число повторяется
                break;
            if (table[h] == 0) { // Если нашли пустое место в хэш-таблице
                table[h] = a[i];
                break;
            }
            if (d >= m) { // Если переполнение
                overflow = true;
                return;
            }
            collisions++;
            h += d;
            if (h >= m)
                h -= m;
            d += 2;
        }
    }
    overflow = false;
}
// Выводит хеш-таблицу на экран
void ShowTable()
{
    if (m == 11) {
        cout << ("------------------------------------------------------------------------\n");
        cout << ("| Номер ячейки |  0 |  1 |  2 |  3 |  4 |  5 |  6 |  7 |  8 |  9 |  10 |\n");
        cout << ("------------------------------------------------------------------------\n");
        cout << ("| Число        | ");
        for (int i = 0; i < m; i++)
            if (table[i] != 0)
                cout << " " << table[i] << " |";
            else
                cout << "   | ";
        cout << endl;
        cout << ("-----------------------------------------------------------------------\n");
    }
    if (!overflow)
        cout << ("Переполнения таблицы не было\n");
    else
        cout << ("Возникло переполнение таблицы\n");
    cout << ("Количество коллизий: ");
    cout << collisions << endl;
}
// Ищет число в хеш-таблице, построенной методом линейных проб
bool Search1(int num)
{
    int h, h0, g;
    h = HashF(num);
    h0 = h;
    g = 1;
    while (1) {
        if (table[h] == num) // Если число найдено
            return true;
        if (g >= m) // Если переполнение
            return false;
        h = h0 + g;
        if (h >= m)
            h -= m;
        g++;
    }
}
// Ищет число в хеш-таблице, построенной методом квадратичных проб
bool Search2(int num)
{
    int h, d;
    h = HashF(num);
    d = 1;
    while (1) {
        if (table[h] == num) // Если число найдено
            return true;
        if (d >= m) // Если переполнение
            return false;
        h += d;
        if (h >= m)
            h -= m;
        d += 2;
    }
}
 
 
int main(int argc, char* argv[])
{
    setlocale(LC_CTYPE, "Russian");
    cout << ("Введите размер хеш-таблицы: ");
    cin >> m;
    cout << ("Введите количество исходных чисел: ");
    cin >> n;
    int num; // Число для поиска
 
    int i;
    for (i = 0; i < n; i++) // Заполним массив чисел
        a[i] = rand() % n + 10;
    cout << ("Метод линейных проб:\n");
    CreateTable1();
    ShowTable();
    cout << ("Введите число для поиска: ");
    cin >> num;
    if (Search1(num))
        cout << ("Число было найдено\n");
    else
        cout << ("Число было не найдено\n");
    cout << ("\nМетод квадратичных проб:\n");
    CreateTable2();
    ShowTable();
    cout << ("Введите число для поиска: ");
    cin >> num;
    if (Search2(num))
        cout << ("Число было найдено\n");
    else
        cout << ("Число было не найдено\n");
 
    system("pause");
    return 0;
}
вроде бы корректно, но все время вылазит то одна, то другая ошибка. Осложняется все вечными лагами Вижлы 2019, из-за этого непонятно, где именно мой косяк - приходится скакать с компа на комп, то на винду 10, то на семерку. Подскажите, пож, что можно исправить в коде
1
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
02.04.2021, 10:12
Ответы с готовыми решениями:

Хэширование
Здравствуйте... Объясните, пожалуйста, как написать телефонный справочник (по фамилии и/или имени...

Хэширование
Ребят, я вообще не понимаю хэширование(( помоги пожалуйста с задачкой, буду признателен. Составить...

Хэширование
Помогите пожалуйста. Реализуйте квадратичное сканирование как технику повторного хэширования.

хэширование
требуется разработать программу, реализующую комбинированный способ организации таблицы...

3
Just Do It!
3841 / 2286 / 636
Регистрация: 23.09.2014
Сообщений: 7,075
Записей в блоге: 3
18.04.2021, 16:09 2
GFox89,
сразу заметно, что для такого алгоритма вычисления хеша:
Цитата Сообщение от GFox89 Посмотреть сообщение
C++
13
14
15
16
int HashF(int num)
{
    return num % m;
}
количество ячеек, которые вам понадобятся будет равно = 10

а у вас тут:
Цитата Сообщение от GFox89 Посмотреть сообщение
C++
85
86
87
        cout << ("------------------------------------------------------------------------\n");
        cout << ("| Номер ячейки |  0 |  1 |  2 |  3 |  4 |  5 |  6 |  7 |  8 |  9 |  10 |\n");
        cout << ("------------------------------------------------------------------------\n");
их аж 11

это конешъ мелочь, но не для арифметики.
1
Just Do It!
3841 / 2286 / 636
Регистрация: 23.09.2014
Сообщений: 7,075
Записей в блоге: 3
18.04.2021, 17:57 3
Лучший ответ Сообщение было отмечено GFox89 как решение

Решение

Цитата Сообщение от GFox89 Посмотреть сообщение
но все время вылазит то одна, то другая ошибка
гляньте это:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#include "pch.h"
#include <iostream>
#include <iomanip>
 
using namespace std;
 
int m = 10;            // Размер хеш-таблицы
int table[1000] = {0}; // Хеш-таблица
int n;                 // Размер массива чисел
int a[1000];           // Массив чисел
bool overflow;         // Равна true, если было переполнение таблицы
int collisions;        // Количество коллизий
// Вычисляет хеш-функцию
int HashF(int num)
{   return num % m;
}
// Создает хеш-таблицу методом линейных проб
void CreateTable1()
{   int i;
    for (i = 0; i < 1000; i++) // Очищаем хэш-таблицу
        table[i] = -1;
    
    collisions = 0;
    
    int h, h0, g;
    for(i = 0; i < n; i++)
    {   h  = HashF(a[i]);
        h0 = h;
        g  = 1;
        while (1)
        {   if (table[h] == a[i]) // Если число повторяется
                break;
            if (table[h] == -1)   // Если нашли пустое место в хэш-таблице
            {   table[h] = a[i];
                break;
            }
            if (g >= m)           // Если переполнение
            {   overflow = true;
                return;
            }
            collisions++;
            h = h0 + g;
            if (h >= m)
                h -= m;
            g++;
        }
    }
    overflow = false;
}
 
// Создает хеш-таблицу методом квадратичных проб
void CreateTable2()
{   int i;
    for (i = 0; i < 1000; i++) // Очищаем хэш-таблицу
        table[i] = -1;
 
    collisions = 0;
    int h, d;
    for (i = 0; i < n; i++)
    {   h = HashF(a[i]);
        d = 1;
        while (1)
        {   if (table[h] == a[i]) // Если число повторяется
                break;
            if (table[h] == -1)   // Если нашли пустое место в хэш-таблице
            {   table[h] = a[i];
                break;
            }
            if (d >= m)   // Если переполнение
            {   overflow = true;
                return;
            }
            collisions++;
            h += d;
            if (h >= m)
                h -= m;
            d += 2;
        }
    }
    overflow = false;
}
 
// Выводит хеш-таблицу на экран
void ShowTable()
{
    cout << ("-----------------------------------------------------------\n");
    cout << ("| Хеш   |  0 |  1 |  2 |  3 |  4 |  5 |  6 |  7 |  8 |  9 |\n");
    cout << ("-----------------------------------------------------------\n");
    cout << ("| Число |");
    for (int i = 0; i < 10; i++)
        cout << setw(3) << table[i] << " |";
    cout << endl;
    cout << "------------------------------------------------------------\n";
    
    if (!overflow) cout << "Переполнения таблицы не было\n" ;
    else           cout << "Возникло переполнение таблицы\n";
    cout << "Количество коллизий: " << collisions << endl;
}
 
// Ищет число в хеш-таблице, построенной методом линейных проб
bool Search1(int num)
{   int h = HashF(num);
    for(int g = h; g < m; ++h)
    {   if (table[h] == num) // Если число найдено
            return true;
    }
    return false; // Если переполнение
}
 
// Ищет число в хеш-таблице, построенной методом квадратичных проб
bool Search2(int num)
{   int h, d;
    h = HashF(num);
    d = 1;
    while (1)
    {   if (table[h] == num) // Если число найдено
            return true;
        if (d >= m) // Если переполнение
            return false;
        h += d;
        if (h >= m)
            h -= m;
        d += 2;
    }
}
 
int main(int argc, char* argv[])
{   setlocale(LC_CTYPE, "Russian");
    cout << ("Введите размер хеш-таблицы       : ") << m << '\n'; //cin >> m;
    cout << ("Введите количество исходных чисел: "); cin >> n;
 
    for (int i = 0; i < n; i++)
    {   a[i] = rand() % m + 10;
        std::cout << a[i] << ' ';
    }
    
    cout << ("\n\nМетод линейных проб:\n");/////////////////////////////////////
    CreateTable1();
    ShowTable();
 
    // Число для поиска
    int k; cout << ("Введите число для поиска: "); cin >> k;
 
    if (Search1(k))
        cout << ("Число было найдено\n");
    else
        cout << ("Число было не найдено\n");
        
    cout << ("\nМетод квадратичных проб:\n");///////////////////////////////////
    CreateTable2();
    ShowTable   ();
 
    cout << ("Введите число для поиска: ");
    cin >> k;
 
    if (Search2(k))
        cout << ("Число было найдено\n");
    else
        cout << ("Число было не найдено\n");
 
    system("pause");
    return 0;
}
Хэширование и поиск

если что вылазит, то пишите конкретно со всеми подробностями про ошипку.
1
1 / 1 / 0
Регистрация: 08.10.2020
Сообщений: 2
21.09.2021, 21:45 4
Нашел проблему с коллизиями, при любом раскладе цифры в твоем примере будут совпадать с индексами, а если изменить немного рандом, то программа научится улавливать коллизии, еще можно добавить srand( time( NULL )); для полного кайфа, тогда все будет работать как часы
C++
1
a[i] = rand() % 100;
1
21.09.2021, 21:45
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
21.09.2021, 21:45
Помогаю со студенческими работами здесь

Хэширование
Здравствуйте, вот прям вообще не понимаю, что нужно делать и что есть что и где :D....

Хэширование
Хочу захэшировать структуру, но при вводе выдает одинаковый хэшкод у каждого нового элемента. Где...

Хэширование
Добрый день, коллеги! Вопрос в следующем, есть ли готовая реализация на 1С алгоритма хэширования...

Хэширование
Реализовать хэширование с открытой адресацией и квадратичным исследованием

Хэширование
Можете обьяснить что такое хэширование как это понимать??Я в википедии читал что это преобразование...

Хэширование
Здравствуйте. Возможно ли использовать функцию хэширования в аутентификации (в частности в пароле)...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru