Я новичок в программировании на C и пытаюсь понять различия между двумя программами, которые проверяют наличие повторяющихся элементов в массиве, используя хэш-таблицы с библиотекой uthash. Я заметил некоторые различия в их реализации и не уверен, что изменения в Программе 1 действительно являются улучшениями по сравнению с Программой 2. Не могли бы вы помочь мне понять эти различия и их последствия?
Программа 1
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "uthash.h"
typedef struct {
int key;
UT_hash_handle hh;
} hash_table;
bool containsDuplicate(int* nums, int numsSize) {
if (numsSize == 1) {
return false;
}
hash_table *hash = NULL;
hash_table *elem = NULL;
bool flag = false;
for (int i = 0; i < numsSize; i++) {
HASH_FIND_INT(hash, &nums[i], elem);
if (!elem) {
elem = (hash_table *)malloc(sizeof(hash_table));
elem->key = nums[i];
HASH_ADD_INT(hash, key, elem);
} else {
flag = true;
break;
}
}
hash_table *tmp;
HASH_ITER(hh, hash, elem, tmp) {
HASH_DEL(hash, elem);
free(elem);
}
return flag;
}
Программа2
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "uthash.h"
typedef struct {
int key;
UT_hash_handle hh;
} hash_table;
hash_table *hash = NULL, *elem, *tmp;
bool containsDuplicate(int* nums, int numsSize){
if (numsSize == 1) {
return false;
}
bool flag = false;
for (int i=0; i<numsSize; i++) {
HASH_FIND_INT(hash, &nums[i], elem);
if (!elem) {
elem = malloc(sizeof(hash_table));
elem->key = nums[i];
HASH_ADD_INT(hash, key, elem);
} else {
flag = true;
break;
}
}
HASH_ITER(hh, hash, elem, tmp) {
HASH_DEL(hash, elem); free(elem);
}
return flag;
}
С точки зрения новичка, основные различия, которые я вижу, заключаются в следующем:
Я пытаюсь понять:





Единственное существенное отличие заключается в том, что ваша первая программа использует локальные переменные, а вторая программа использует глобальные переменные для ваших хеш-таблиц. О глобальных переменных в вашей программе труднее рассуждать, поскольку вам приходится проверять всю программу, чтобы выяснить, что читает или записывает в любую из этих трех глобальных переменных. Глобальные переменные усложняют тестирование вашего кода.
Если у вас есть другие варианты использования хеш-таблицы, то имеет смысл сохранить ее, а не делать деталью реализации containsDuplicate(). Построение хеш-таблицы стоило O(n), но только O(1) чтобы проверить, присутствует ли уже новое значение. Ни одна программа в настоящее время не поддерживает это.
Не используйте void * из malloc(). Это может скрыть проблемы с типом.
Предпочитайте sizeof *elem вместо sizeof(hash_table). Первый является чисто механическим и приводит к меньшему дублированию.
Если это ответило на ваш вопрос, примите его, нажав на галочку рядом с ним.
Вопрос не обязательно ограничивается хеш-таблицами. Вы можете спросить его о любом другом типе/структуре данных, и ответ всегда будет одинаковым. Избегайте глобальных данных.