Skip to main content
Code Review

Return to Question

Became Hot Network Question
Do not include incorrect tags. The code is C, not C++.
Link
Madagascar
  • 10.2k
  • 1
  • 15
  • 51
added 1 character in body
Source Link
toolic
  • 14.6k
  • 5
  • 29
  • 204

I wrote code that implements perfect hash table, according to its description in the book "Introduction to Algorithms by Thomas H Cormen", but the code does not pass time tests in contest. I would really appreciate any help in making this code run faster (code must be in clear C).

(Regarding Regarding the main function, we enter the number of elements in the set Then the elements themselves. Then requests, we respond to requests with "YES"|"NO" We finish reading requests when we encounter '.')

#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#include <time.h>
#include <string.h>
#define BUFFER_SIZE 1024 // Size of buffer for input
#define P_VALUE 4294967311
struct Node {
 int key;
 int value;
};
// Define the structure for the hash table
struct SecondLevelHashTable {
 size_t size;
 size_t numElements;
 struct Node** table;
 size_t a;
 size_t b;
};
// Define the structure for the hash table
struct FirstLevelHashTable {
 size_t size;
 size_t numElements;
 struct SecondLevelHashTable** table;
 size_t a;
 size_t b;
};
// Define the hash function
size_t universalHash(int key, size_t a, size_t b, size_t m);
// Function to check if a number is prime
bool isPrime(int n);
// Function to find the minimum prime number greater than m
int findNextPrime(int m);
// Function to generate random values for a and b
void generateRandomValues(size_t *a, size_t *b);
// Function to initialize node
struct Node* initializeNode(int key, int value);
// Function to create a second-level hash table
struct SecondLevelHashTable* createSecondLevelHashTable(size_t size);
// Function to create a first-level hash table
struct FirstLevelHashTable* createFirstLevelHashTable(size_t size);
// Function to create an array of counts based on hash function results
size_t* countElementsByHash(int* keys, struct FirstLevelHashTable *firstLevelHashTable, size_t numKeys);
// Function to initialize second-level hash tables based on counts
void initializeSecondLevelHashTables(struct FirstLevelHashTable* firstLevelHashTable, size_t* counts);
// Function to initialize hash for second-level hash tables
void initializeHashForSecondHashTables(struct SecondLevelHashTable* secondLevelHashTable, struct FirstLevelHashTable* firstLevelHashTable, int* keys, size_t numKeys, size_t index);
// Function to check if an element exists in the hash table
bool locate(int x, struct FirstLevelHashTable* firstLevelHashTable);
void freeFirstLevelHashTable(struct FirstLevelHashTable* firstLevelHashTable);
void freeSecondLevelHashTable(struct SecondLevelHashTable* secondLevelHashTable);
// Define the hash function
size_t universalHash(int key, size_t a, size_t b, size_t m) {
 return ((a * key + b) % P_VALUE) % m;
}
// Function to generate random values for a and b
void generateRandomValues(size_t *a, size_t *b) {
 // Generate random values for a and b
 *a = (rand() % (P_VALUE - 1)) + 1; // Ensure a falls within the range [1, p - 1]
 *b = rand() % P_VALUE; // Ensure b falls within the range [0, p - 1]
}
// Function to initialize node
struct Node* initializeNode(int key, int value) {
 // Allocate memory for the new node
 struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
 if (newNode == NULL) {
 // Handle memory allocation failure
 perror("Memory allocation failed");
 return NULL;
 }
 // Assign key and value to the node
 newNode->key = key;
 newNode->value = value;
 return newNode;
}
struct SecondLevelHashTable* createSecondLevelHashTable(size_t size) {
 // Allocate memory for the hash table structure
 struct SecondLevelHashTable* secondLevelHashTable = (struct SecondLevelHashTable*)malloc(sizeof(struct SecondLevelHashTable));
 if (secondLevelHashTable == NULL) {
 freeSecondLevelHashTable(secondLevelHashTable);
 perror("Memory allocation failed");
 return NULL;
 }
 // Allocate memory for the array of pointers to doubly linked lists
 secondLevelHashTable->table = (struct Node**)malloc(size * sizeof(struct Node*));
 if (secondLevelHashTable->table == NULL) {
 freeSecondLevelHashTable(secondLevelHashTable);
 perror("Memory allocation failed");
 return NULL;
 }
 // Initialize each pointer in the array to NULL
 for (int i = 0; i < size; i++) {
 secondLevelHashTable->table[i] = NULL;
 }
 // Set the size and number of elements
 secondLevelHashTable->size = size;
 secondLevelHashTable->numElements = 0;
 return secondLevelHashTable;
}
struct FirstLevelHashTable* createFirstLevelHashTable(size_t size) {
 // Allocate memory for the hash table structure
 struct FirstLevelHashTable* firstLevelHashTable = (struct FirstLevelHashTable*)malloc(sizeof(struct FirstLevelHashTable));
 if (firstLevelHashTable == NULL) {
 freeFirstLevelHashTable(firstLevelHashTable);
 perror("Memory allocation failed");
 return NULL;
 }
 // Allocate memory for the array of pointers to second-level hash tables
 firstLevelHashTable->table = (struct SecondLevelHashTable**)malloc(size * sizeof(struct SecondLevelHashTable*));
 if (firstLevelHashTable->table == NULL) {
 freeFirstLevelHashTable(firstLevelHashTable);
 perror("Memory allocation failed");
 return NULL;
 }
 /**
 // Initialize each pointer in the array to NULL
 for (int i = 0; i < size; i++) {
 firstLevelHashTable->table[i] = createSecondLevelHashTable(1LL<<14);
 }
 **/
 firstLevelHashTable->size = size;
 firstLevelHashTable->numElements = 0;
 firstLevelHashTable->a = 0;
 firstLevelHashTable->b = 0;
 generateRandomValues(&firstLevelHashTable->a, &firstLevelHashTable->b);
 return firstLevelHashTable;
}
// Function to create an array of counts based on hash function results
size_t* countElementsByHash(int* keys, struct FirstLevelHashTable *firstLevelHashTable, size_t numKeys) {
 // Allocate memory for the array of counts
 size_t* counts = (size_t*)calloc(firstLevelHashTable->size, sizeof(size_t));
 if (counts == NULL) {
 perror("Memory allocation failed");
 return NULL;
 }
 // Iterate over each key
 for (size_t i = 0; i < numKeys; i++) {
 // Calculate the hash value for the current key
 size_t hashValue = universalHash(keys[i], firstLevelHashTable->a, firstLevelHashTable->b, firstLevelHashTable->size);
 // Increment the count at the corresponding index
 counts[hashValue]++;
 }
 return counts;
}
void initializeSecondLevelHashTables(struct FirstLevelHashTable* firstLevelHashTable, size_t* counts) {
 if (firstLevelHashTable == NULL || counts == NULL) {
 return;
 }
 // Iterate over each index in the first-level hash table
 for (size_t i = 0; i < firstLevelHashTable->size; ++i) {
 size_t size = counts[i] * counts[i] + 1; // Get the size from the counts array
 // Allocate memory for the second-level hash table
 struct SecondLevelHashTable* secondLevelHashTable = createSecondLevelHashTable(size);
 if (secondLevelHashTable == NULL) {
 freeSecondLevelHashTable(secondLevelHashTable);
 return;
 }
 // Assign the second-level hash table to the first-level hash table
 firstLevelHashTable->table[i] = secondLevelHashTable;
 }
}
void initializeHashForSecondHashTables(struct SecondLevelHashTable* secondLevelHashTable, struct FirstLevelHashTable* firstLevelHashTable, int* keys, size_t numKeys, size_t index) {
 if (secondLevelHashTable == NULL || keys == NULL) {
 return;
 }
 secondLevelHashTable->a = 0;
 secondLevelHashTable->b = 0;
 bool isCorrect = true;
 do {
 generateRandomValues(&secondLevelHashTable->a, &secondLevelHashTable->b);
 // Iterate over each key
 for (size_t i = 0; i < numKeys; i++) {
 // Calculate the hash value for the current key
 size_t firstHashValue = universalHash(keys[i], firstLevelHashTable->a,
 firstLevelHashTable->b,
 firstLevelHashTable->size);
 // Increment the count at the corresponding index
 if (firstHashValue == index) {
 size_t secondHashValue = universalHash(keys[i], secondLevelHashTable->a,
 secondLevelHashTable->b,
 secondLevelHashTable->size);
 //printf("%lld\n", secondLevelHashTable->size);
 if (secondLevelHashTable->table[secondHashValue] == NULL) {
 secondLevelHashTable->table[secondHashValue] = initializeNode(keys[i], 1);
 } else {
 isCorrect = false;
 break;
 }
 }
 }
 } while (isCorrect != true);
}
bool locate(int x, struct FirstLevelHashTable* firstLevelHashTable) {
 // Calculate the hash value for the input key
 size_t firstHashValue = universalHash(x, firstLevelHashTable->a, firstLevelHashTable->b, firstLevelHashTable->size);
 // Get the corresponding second-level hash table
 struct SecondLevelHashTable* secondLevelHashTable = firstLevelHashTable->table[firstHashValue];
 if (secondLevelHashTable == NULL) {
 return false; // No elements at this index
 }
 // Calculate the hash value for the input key in the second-level hash table
 size_t secondHashValue = universalHash(x, secondLevelHashTable->a, secondLevelHashTable->b, secondLevelHashTable->size);
 // Check if the key exists in the second-level hash table
 if (secondLevelHashTable->table[secondHashValue] != NULL && secondLevelHashTable->table[secondHashValue]->key == x) {
 return true; // Key exists
 }
 return false; // Key does not exist
}
void freeFirstLevelHashTable(struct FirstLevelHashTable* firstLevelHashTable) {
 if (firstLevelHashTable == NULL) {
 return;
 }
 for (size_t i = 0; i < firstLevelHashTable->size; ++i) {
 struct SecondLevelHashTable* secondLevelHashTable = firstLevelHashTable->table[i];
 freeSecondLevelHashTable(secondLevelHashTable);
 }
 free(firstLevelHashTable->table);
 free(firstLevelHashTable);
}
void freeSecondLevelHashTable(struct SecondLevelHashTable* secondLevelHashTable) {
 if (secondLevelHashTable == NULL) {
 return;
 }
 for (size_t i = 0; i < secondLevelHashTable->size; i++) {
 free(secondLevelHashTable->table[i]);
 }
 free(secondLevelHashTable->table);
 free(secondLevelHashTable);
}
int main() {
 // Seed the random number generator
 srand(time(NULL));
 size_t num_elements, i;
 int query;
 char buffer[BUFFER_SIZE];
 // Reading the number of elements in the set
 if (!fgets(buffer, sizeof(buffer), stdin) || sscanf(buffer, "%zu", &num_elements) != 1 || num_elements <= 0) {
 fprintf(stderr, "Error: invalid input for the number of elements.\n");
 return EXIT_FAILURE;
 }
 int* elements = (int*)malloc(num_elements * sizeof(int*));
 if (!elements) {
 fprintf(stderr, "Error: memory allocation failed.\n");
 return EXIT_FAILURE;
 }
 // Reading the elements of the set
 if (!fgets(buffer, sizeof(buffer), stdin)) {
 fprintf(stderr, "Error: invalid input for elements.\n");
 free(elements);
 return EXIT_FAILURE;
 }
 char *token = strtok(buffer, " \t\n");
 for (i = 0; i < num_elements; i++) {
 if (!token) {
 fprintf(stderr, "Error: insufficient elements in the input.\n");
 free(elements);
 return EXIT_FAILURE;
 }
 elements[i] = (int)(uintptr_t)strtoull(token, NULL, 10);
 token = strtok(NULL, " \t\n");
 }
 struct FirstLevelHashTable* firstLevelHashTable = createFirstLevelHashTable(1LL << 3);
 if (!firstLevelHashTable) {
 fprintf(stderr, "Error: failed to create first-level hash table.\n");
 free(elements);
 return EXIT_FAILURE;
 }
 size_t* counts = countElementsByHash(elements, firstLevelHashTable, num_elements);
 if (!counts) {
 fprintf(stderr, "Error: failed to count elements by hash.\n");
 free(firstLevelHashTable);
 free(elements);
 return EXIT_FAILURE;
 }
 initializeSecondLevelHashTables(firstLevelHashTable, counts);
 for (size_t j = 0; j < firstLevelHashTable->size; j++) {
 struct SecondLevelHashTable *secondLevelHashTable = firstLevelHashTable->table[j];
 if (!secondLevelHashTable) {
 fprintf(stderr, "Error: failed to initialize second-level hash table.\n");
 free(counts);
 free(firstLevelHashTable);
 free(elements);
 return EXIT_FAILURE;
 }
 initializeHashForSecondHashTables(secondLevelHashTable, firstLevelHashTable,elements,num_elements,j);
 }
 while (1) {
 if (!fgets(buffer, sizeof(buffer), stdin)) {
 fprintf(stderr, "Error reading input.\n");
 freeFirstLevelHashTable(firstLevelHashTable);
 free(elements);
 free(counts);
 return EXIT_FAILURE;
 }
 // Check if the input is '.'
 if (buffer[0] == '.') {
 break; // End of input
 }
 // Convert input to a long long integer
 if (sscanf(buffer, "%lld", &query) != 1) {
 fprintf(stderr, "Error: incorrect input format.\n");
 freeFirstLevelHashTable(firstLevelHashTable);
 free(elements);
 free(counts);
 return EXIT_FAILURE;
 }
 if (locate(query, firstLevelHashTable)) {
 printf("YES\n");
 } else {
 printf("NO\n");
 }
 }
 freeFirstLevelHashTable(firstLevelHashTable);
 free(elements);
 free(counts);
 return EXIT_SUCCESS;
}
```

I wrote code that implements perfect hash table, according to its description in the book "Introduction to Algorithms by Thomas H Cormen" but the code does not pass time tests in contest. I would really appreciate any help in making this code run faster (code must be in clear C).

(Regarding the main function, we enter the number of elements in the set Then the elements themselves. Then requests, we respond to requests with "YES"|"NO" We finish reading requests when we encounter '.')

#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#include <time.h>
#include <string.h>
#define BUFFER_SIZE 1024 // Size of buffer for input
#define P_VALUE 4294967311
struct Node {
 int key;
 int value;
};
// Define the structure for the hash table
struct SecondLevelHashTable {
 size_t size;
 size_t numElements;
 struct Node** table;
 size_t a;
 size_t b;
};
// Define the structure for the hash table
struct FirstLevelHashTable {
 size_t size;
 size_t numElements;
 struct SecondLevelHashTable** table;
 size_t a;
 size_t b;
};
// Define the hash function
size_t universalHash(int key, size_t a, size_t b, size_t m);
// Function to check if a number is prime
bool isPrime(int n);
// Function to find the minimum prime number greater than m
int findNextPrime(int m);
// Function to generate random values for a and b
void generateRandomValues(size_t *a, size_t *b);
// Function to initialize node
struct Node* initializeNode(int key, int value);
// Function to create a second-level hash table
struct SecondLevelHashTable* createSecondLevelHashTable(size_t size);
// Function to create a first-level hash table
struct FirstLevelHashTable* createFirstLevelHashTable(size_t size);
// Function to create an array of counts based on hash function results
size_t* countElementsByHash(int* keys, struct FirstLevelHashTable *firstLevelHashTable, size_t numKeys);
// Function to initialize second-level hash tables based on counts
void initializeSecondLevelHashTables(struct FirstLevelHashTable* firstLevelHashTable, size_t* counts);
// Function to initialize hash for second-level hash tables
void initializeHashForSecondHashTables(struct SecondLevelHashTable* secondLevelHashTable, struct FirstLevelHashTable* firstLevelHashTable, int* keys, size_t numKeys, size_t index);
// Function to check if an element exists in the hash table
bool locate(int x, struct FirstLevelHashTable* firstLevelHashTable);
void freeFirstLevelHashTable(struct FirstLevelHashTable* firstLevelHashTable);
void freeSecondLevelHashTable(struct SecondLevelHashTable* secondLevelHashTable);
// Define the hash function
size_t universalHash(int key, size_t a, size_t b, size_t m) {
 return ((a * key + b) % P_VALUE) % m;
}
// Function to generate random values for a and b
void generateRandomValues(size_t *a, size_t *b) {
 // Generate random values for a and b
 *a = (rand() % (P_VALUE - 1)) + 1; // Ensure a falls within the range [1, p - 1]
 *b = rand() % P_VALUE; // Ensure b falls within the range [0, p - 1]
}
// Function to initialize node
struct Node* initializeNode(int key, int value) {
 // Allocate memory for the new node
 struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
 if (newNode == NULL) {
 // Handle memory allocation failure
 perror("Memory allocation failed");
 return NULL;
 }
 // Assign key and value to the node
 newNode->key = key;
 newNode->value = value;
 return newNode;
}
struct SecondLevelHashTable* createSecondLevelHashTable(size_t size) {
 // Allocate memory for the hash table structure
 struct SecondLevelHashTable* secondLevelHashTable = (struct SecondLevelHashTable*)malloc(sizeof(struct SecondLevelHashTable));
 if (secondLevelHashTable == NULL) {
 freeSecondLevelHashTable(secondLevelHashTable);
 perror("Memory allocation failed");
 return NULL;
 }
 // Allocate memory for the array of pointers to doubly linked lists
 secondLevelHashTable->table = (struct Node**)malloc(size * sizeof(struct Node*));
 if (secondLevelHashTable->table == NULL) {
 freeSecondLevelHashTable(secondLevelHashTable);
 perror("Memory allocation failed");
 return NULL;
 }
 // Initialize each pointer in the array to NULL
 for (int i = 0; i < size; i++) {
 secondLevelHashTable->table[i] = NULL;
 }
 // Set the size and number of elements
 secondLevelHashTable->size = size;
 secondLevelHashTable->numElements = 0;
 return secondLevelHashTable;
}
struct FirstLevelHashTable* createFirstLevelHashTable(size_t size) {
 // Allocate memory for the hash table structure
 struct FirstLevelHashTable* firstLevelHashTable = (struct FirstLevelHashTable*)malloc(sizeof(struct FirstLevelHashTable));
 if (firstLevelHashTable == NULL) {
 freeFirstLevelHashTable(firstLevelHashTable);
 perror("Memory allocation failed");
 return NULL;
 }
 // Allocate memory for the array of pointers to second-level hash tables
 firstLevelHashTable->table = (struct SecondLevelHashTable**)malloc(size * sizeof(struct SecondLevelHashTable*));
 if (firstLevelHashTable->table == NULL) {
 freeFirstLevelHashTable(firstLevelHashTable);
 perror("Memory allocation failed");
 return NULL;
 }
 /**
 // Initialize each pointer in the array to NULL
 for (int i = 0; i < size; i++) {
 firstLevelHashTable->table[i] = createSecondLevelHashTable(1LL<<14);
 }
 **/
 firstLevelHashTable->size = size;
 firstLevelHashTable->numElements = 0;
 firstLevelHashTable->a = 0;
 firstLevelHashTable->b = 0;
 generateRandomValues(&firstLevelHashTable->a, &firstLevelHashTable->b);
 return firstLevelHashTable;
}
// Function to create an array of counts based on hash function results
size_t* countElementsByHash(int* keys, struct FirstLevelHashTable *firstLevelHashTable, size_t numKeys) {
 // Allocate memory for the array of counts
 size_t* counts = (size_t*)calloc(firstLevelHashTable->size, sizeof(size_t));
 if (counts == NULL) {
 perror("Memory allocation failed");
 return NULL;
 }
 // Iterate over each key
 for (size_t i = 0; i < numKeys; i++) {
 // Calculate the hash value for the current key
 size_t hashValue = universalHash(keys[i], firstLevelHashTable->a, firstLevelHashTable->b, firstLevelHashTable->size);
 // Increment the count at the corresponding index
 counts[hashValue]++;
 }
 return counts;
}
void initializeSecondLevelHashTables(struct FirstLevelHashTable* firstLevelHashTable, size_t* counts) {
 if (firstLevelHashTable == NULL || counts == NULL) {
 return;
 }
 // Iterate over each index in the first-level hash table
 for (size_t i = 0; i < firstLevelHashTable->size; ++i) {
 size_t size = counts[i] * counts[i] + 1; // Get the size from the counts array
 // Allocate memory for the second-level hash table
 struct SecondLevelHashTable* secondLevelHashTable = createSecondLevelHashTable(size);
 if (secondLevelHashTable == NULL) {
 freeSecondLevelHashTable(secondLevelHashTable);
 return;
 }
 // Assign the second-level hash table to the first-level hash table
 firstLevelHashTable->table[i] = secondLevelHashTable;
 }
}
void initializeHashForSecondHashTables(struct SecondLevelHashTable* secondLevelHashTable, struct FirstLevelHashTable* firstLevelHashTable, int* keys, size_t numKeys, size_t index) {
 if (secondLevelHashTable == NULL || keys == NULL) {
 return;
 }
 secondLevelHashTable->a = 0;
 secondLevelHashTable->b = 0;
 bool isCorrect = true;
 do {
 generateRandomValues(&secondLevelHashTable->a, &secondLevelHashTable->b);
 // Iterate over each key
 for (size_t i = 0; i < numKeys; i++) {
 // Calculate the hash value for the current key
 size_t firstHashValue = universalHash(keys[i], firstLevelHashTable->a,
 firstLevelHashTable->b,
 firstLevelHashTable->size);
 // Increment the count at the corresponding index
 if (firstHashValue == index) {
 size_t secondHashValue = universalHash(keys[i], secondLevelHashTable->a,
 secondLevelHashTable->b,
 secondLevelHashTable->size);
 //printf("%lld\n", secondLevelHashTable->size);
 if (secondLevelHashTable->table[secondHashValue] == NULL) {
 secondLevelHashTable->table[secondHashValue] = initializeNode(keys[i], 1);
 } else {
 isCorrect = false;
 break;
 }
 }
 }
 } while (isCorrect != true);
}
bool locate(int x, struct FirstLevelHashTable* firstLevelHashTable) {
 // Calculate the hash value for the input key
 size_t firstHashValue = universalHash(x, firstLevelHashTable->a, firstLevelHashTable->b, firstLevelHashTable->size);
 // Get the corresponding second-level hash table
 struct SecondLevelHashTable* secondLevelHashTable = firstLevelHashTable->table[firstHashValue];
 if (secondLevelHashTable == NULL) {
 return false; // No elements at this index
 }
 // Calculate the hash value for the input key in the second-level hash table
 size_t secondHashValue = universalHash(x, secondLevelHashTable->a, secondLevelHashTable->b, secondLevelHashTable->size);
 // Check if the key exists in the second-level hash table
 if (secondLevelHashTable->table[secondHashValue] != NULL && secondLevelHashTable->table[secondHashValue]->key == x) {
 return true; // Key exists
 }
 return false; // Key does not exist
}
void freeFirstLevelHashTable(struct FirstLevelHashTable* firstLevelHashTable) {
 if (firstLevelHashTable == NULL) {
 return;
 }
 for (size_t i = 0; i < firstLevelHashTable->size; ++i) {
 struct SecondLevelHashTable* secondLevelHashTable = firstLevelHashTable->table[i];
 freeSecondLevelHashTable(secondLevelHashTable);
 }
 free(firstLevelHashTable->table);
 free(firstLevelHashTable);
}
void freeSecondLevelHashTable(struct SecondLevelHashTable* secondLevelHashTable) {
 if (secondLevelHashTable == NULL) {
 return;
 }
 for (size_t i = 0; i < secondLevelHashTable->size; i++) {
 free(secondLevelHashTable->table[i]);
 }
 free(secondLevelHashTable->table);
 free(secondLevelHashTable);
}
int main() {
 // Seed the random number generator
 srand(time(NULL));
 size_t num_elements, i;
 int query;
 char buffer[BUFFER_SIZE];
 // Reading the number of elements in the set
 if (!fgets(buffer, sizeof(buffer), stdin) || sscanf(buffer, "%zu", &num_elements) != 1 || num_elements <= 0) {
 fprintf(stderr, "Error: invalid input for the number of elements.\n");
 return EXIT_FAILURE;
 }
 int* elements = (int*)malloc(num_elements * sizeof(int*));
 if (!elements) {
 fprintf(stderr, "Error: memory allocation failed.\n");
 return EXIT_FAILURE;
 }
 // Reading the elements of the set
 if (!fgets(buffer, sizeof(buffer), stdin)) {
 fprintf(stderr, "Error: invalid input for elements.\n");
 free(elements);
 return EXIT_FAILURE;
 }
 char *token = strtok(buffer, " \t\n");
 for (i = 0; i < num_elements; i++) {
 if (!token) {
 fprintf(stderr, "Error: insufficient elements in the input.\n");
 free(elements);
 return EXIT_FAILURE;
 }
 elements[i] = (int)(uintptr_t)strtoull(token, NULL, 10);
 token = strtok(NULL, " \t\n");
 }
 struct FirstLevelHashTable* firstLevelHashTable = createFirstLevelHashTable(1LL << 3);
 if (!firstLevelHashTable) {
 fprintf(stderr, "Error: failed to create first-level hash table.\n");
 free(elements);
 return EXIT_FAILURE;
 }
 size_t* counts = countElementsByHash(elements, firstLevelHashTable, num_elements);
 if (!counts) {
 fprintf(stderr, "Error: failed to count elements by hash.\n");
 free(firstLevelHashTable);
 free(elements);
 return EXIT_FAILURE;
 }
 initializeSecondLevelHashTables(firstLevelHashTable, counts);
 for (size_t j = 0; j < firstLevelHashTable->size; j++) {
 struct SecondLevelHashTable *secondLevelHashTable = firstLevelHashTable->table[j];
 if (!secondLevelHashTable) {
 fprintf(stderr, "Error: failed to initialize second-level hash table.\n");
 free(counts);
 free(firstLevelHashTable);
 free(elements);
 return EXIT_FAILURE;
 }
 initializeHashForSecondHashTables(secondLevelHashTable, firstLevelHashTable,elements,num_elements,j);
 }
 while (1) {
 if (!fgets(buffer, sizeof(buffer), stdin)) {
 fprintf(stderr, "Error reading input.\n");
 freeFirstLevelHashTable(firstLevelHashTable);
 free(elements);
 free(counts);
 return EXIT_FAILURE;
 }
 // Check if the input is '.'
 if (buffer[0] == '.') {
 break; // End of input
 }
 // Convert input to a long long integer
 if (sscanf(buffer, "%lld", &query) != 1) {
 fprintf(stderr, "Error: incorrect input format.\n");
 freeFirstLevelHashTable(firstLevelHashTable);
 free(elements);
 free(counts);
 return EXIT_FAILURE;
 }
 if (locate(query, firstLevelHashTable)) {
 printf("YES\n");
 } else {
 printf("NO\n");
 }
 }
 freeFirstLevelHashTable(firstLevelHashTable);
 free(elements);
 free(counts);
 return EXIT_SUCCESS;
}
```

I wrote code that implements perfect hash table, according to its description in the book "Introduction to Algorithms by Thomas H Cormen", but the code does not pass time tests in contest. I would really appreciate any help in making this code run faster (code must be in clear C).

Regarding the main function, we enter the number of elements in the set Then the elements themselves. Then requests, we respond to requests with "YES"|"NO" We finish reading requests when we encounter '.'

#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#include <time.h>
#include <string.h>
#define BUFFER_SIZE 1024 // Size of buffer for input
#define P_VALUE 4294967311
struct Node {
 int key;
 int value;
};
// Define the structure for the hash table
struct SecondLevelHashTable {
 size_t size;
 size_t numElements;
 struct Node** table;
 size_t a;
 size_t b;
};
// Define the structure for the hash table
struct FirstLevelHashTable {
 size_t size;
 size_t numElements;
 struct SecondLevelHashTable** table;
 size_t a;
 size_t b;
};
// Define the hash function
size_t universalHash(int key, size_t a, size_t b, size_t m);
// Function to check if a number is prime
bool isPrime(int n);
// Function to find the minimum prime number greater than m
int findNextPrime(int m);
// Function to generate random values for a and b
void generateRandomValues(size_t *a, size_t *b);
// Function to initialize node
struct Node* initializeNode(int key, int value);
// Function to create a second-level hash table
struct SecondLevelHashTable* createSecondLevelHashTable(size_t size);
// Function to create a first-level hash table
struct FirstLevelHashTable* createFirstLevelHashTable(size_t size);
// Function to create an array of counts based on hash function results
size_t* countElementsByHash(int* keys, struct FirstLevelHashTable *firstLevelHashTable, size_t numKeys);
// Function to initialize second-level hash tables based on counts
void initializeSecondLevelHashTables(struct FirstLevelHashTable* firstLevelHashTable, size_t* counts);
// Function to initialize hash for second-level hash tables
void initializeHashForSecondHashTables(struct SecondLevelHashTable* secondLevelHashTable, struct FirstLevelHashTable* firstLevelHashTable, int* keys, size_t numKeys, size_t index);
// Function to check if an element exists in the hash table
bool locate(int x, struct FirstLevelHashTable* firstLevelHashTable);
void freeFirstLevelHashTable(struct FirstLevelHashTable* firstLevelHashTable);
void freeSecondLevelHashTable(struct SecondLevelHashTable* secondLevelHashTable);
// Define the hash function
size_t universalHash(int key, size_t a, size_t b, size_t m) {
 return ((a * key + b) % P_VALUE) % m;
}
// Function to generate random values for a and b
void generateRandomValues(size_t *a, size_t *b) {
 // Generate random values for a and b
 *a = (rand() % (P_VALUE - 1)) + 1; // Ensure a falls within the range [1, p - 1]
 *b = rand() % P_VALUE; // Ensure b falls within the range [0, p - 1]
}
// Function to initialize node
struct Node* initializeNode(int key, int value) {
 // Allocate memory for the new node
 struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
 if (newNode == NULL) {
 // Handle memory allocation failure
 perror("Memory allocation failed");
 return NULL;
 }
 // Assign key and value to the node
 newNode->key = key;
 newNode->value = value;
 return newNode;
}
struct SecondLevelHashTable* createSecondLevelHashTable(size_t size) {
 // Allocate memory for the hash table structure
 struct SecondLevelHashTable* secondLevelHashTable = (struct SecondLevelHashTable*)malloc(sizeof(struct SecondLevelHashTable));
 if (secondLevelHashTable == NULL) {
 freeSecondLevelHashTable(secondLevelHashTable);
 perror("Memory allocation failed");
 return NULL;
 }
 // Allocate memory for the array of pointers to doubly linked lists
 secondLevelHashTable->table = (struct Node**)malloc(size * sizeof(struct Node*));
 if (secondLevelHashTable->table == NULL) {
 freeSecondLevelHashTable(secondLevelHashTable);
 perror("Memory allocation failed");
 return NULL;
 }
 // Initialize each pointer in the array to NULL
 for (int i = 0; i < size; i++) {
 secondLevelHashTable->table[i] = NULL;
 }
 // Set the size and number of elements
 secondLevelHashTable->size = size;
 secondLevelHashTable->numElements = 0;
 return secondLevelHashTable;
}
struct FirstLevelHashTable* createFirstLevelHashTable(size_t size) {
 // Allocate memory for the hash table structure
 struct FirstLevelHashTable* firstLevelHashTable = (struct FirstLevelHashTable*)malloc(sizeof(struct FirstLevelHashTable));
 if (firstLevelHashTable == NULL) {
 freeFirstLevelHashTable(firstLevelHashTable);
 perror("Memory allocation failed");
 return NULL;
 }
 // Allocate memory for the array of pointers to second-level hash tables
 firstLevelHashTable->table = (struct SecondLevelHashTable**)malloc(size * sizeof(struct SecondLevelHashTable*));
 if (firstLevelHashTable->table == NULL) {
 freeFirstLevelHashTable(firstLevelHashTable);
 perror("Memory allocation failed");
 return NULL;
 }
 /**
 // Initialize each pointer in the array to NULL
 for (int i = 0; i < size; i++) {
 firstLevelHashTable->table[i] = createSecondLevelHashTable(1LL<<14);
 }
 **/
 firstLevelHashTable->size = size;
 firstLevelHashTable->numElements = 0;
 firstLevelHashTable->a = 0;
 firstLevelHashTable->b = 0;
 generateRandomValues(&firstLevelHashTable->a, &firstLevelHashTable->b);
 return firstLevelHashTable;
}
// Function to create an array of counts based on hash function results
size_t* countElementsByHash(int* keys, struct FirstLevelHashTable *firstLevelHashTable, size_t numKeys) {
 // Allocate memory for the array of counts
 size_t* counts = (size_t*)calloc(firstLevelHashTable->size, sizeof(size_t));
 if (counts == NULL) {
 perror("Memory allocation failed");
 return NULL;
 }
 // Iterate over each key
 for (size_t i = 0; i < numKeys; i++) {
 // Calculate the hash value for the current key
 size_t hashValue = universalHash(keys[i], firstLevelHashTable->a, firstLevelHashTable->b, firstLevelHashTable->size);
 // Increment the count at the corresponding index
 counts[hashValue]++;
 }
 return counts;
}
void initializeSecondLevelHashTables(struct FirstLevelHashTable* firstLevelHashTable, size_t* counts) {
 if (firstLevelHashTable == NULL || counts == NULL) {
 return;
 }
 // Iterate over each index in the first-level hash table
 for (size_t i = 0; i < firstLevelHashTable->size; ++i) {
 size_t size = counts[i] * counts[i] + 1; // Get the size from the counts array
 // Allocate memory for the second-level hash table
 struct SecondLevelHashTable* secondLevelHashTable = createSecondLevelHashTable(size);
 if (secondLevelHashTable == NULL) {
 freeSecondLevelHashTable(secondLevelHashTable);
 return;
 }
 // Assign the second-level hash table to the first-level hash table
 firstLevelHashTable->table[i] = secondLevelHashTable;
 }
}
void initializeHashForSecondHashTables(struct SecondLevelHashTable* secondLevelHashTable, struct FirstLevelHashTable* firstLevelHashTable, int* keys, size_t numKeys, size_t index) {
 if (secondLevelHashTable == NULL || keys == NULL) {
 return;
 }
 secondLevelHashTable->a = 0;
 secondLevelHashTable->b = 0;
 bool isCorrect = true;
 do {
 generateRandomValues(&secondLevelHashTable->a, &secondLevelHashTable->b);
 // Iterate over each key
 for (size_t i = 0; i < numKeys; i++) {
 // Calculate the hash value for the current key
 size_t firstHashValue = universalHash(keys[i], firstLevelHashTable->a,
 firstLevelHashTable->b,
 firstLevelHashTable->size);
 // Increment the count at the corresponding index
 if (firstHashValue == index) {
 size_t secondHashValue = universalHash(keys[i], secondLevelHashTable->a,
 secondLevelHashTable->b,
 secondLevelHashTable->size);
 //printf("%lld\n", secondLevelHashTable->size);
 if (secondLevelHashTable->table[secondHashValue] == NULL) {
 secondLevelHashTable->table[secondHashValue] = initializeNode(keys[i], 1);
 } else {
 isCorrect = false;
 break;
 }
 }
 }
 } while (isCorrect != true);
}
bool locate(int x, struct FirstLevelHashTable* firstLevelHashTable) {
 // Calculate the hash value for the input key
 size_t firstHashValue = universalHash(x, firstLevelHashTable->a, firstLevelHashTable->b, firstLevelHashTable->size);
 // Get the corresponding second-level hash table
 struct SecondLevelHashTable* secondLevelHashTable = firstLevelHashTable->table[firstHashValue];
 if (secondLevelHashTable == NULL) {
 return false; // No elements at this index
 }
 // Calculate the hash value for the input key in the second-level hash table
 size_t secondHashValue = universalHash(x, secondLevelHashTable->a, secondLevelHashTable->b, secondLevelHashTable->size);
 // Check if the key exists in the second-level hash table
 if (secondLevelHashTable->table[secondHashValue] != NULL && secondLevelHashTable->table[secondHashValue]->key == x) {
 return true; // Key exists
 }
 return false; // Key does not exist
}
void freeFirstLevelHashTable(struct FirstLevelHashTable* firstLevelHashTable) {
 if (firstLevelHashTable == NULL) {
 return;
 }
 for (size_t i = 0; i < firstLevelHashTable->size; ++i) {
 struct SecondLevelHashTable* secondLevelHashTable = firstLevelHashTable->table[i];
 freeSecondLevelHashTable(secondLevelHashTable);
 }
 free(firstLevelHashTable->table);
 free(firstLevelHashTable);
}
void freeSecondLevelHashTable(struct SecondLevelHashTable* secondLevelHashTable) {
 if (secondLevelHashTable == NULL) {
 return;
 }
 for (size_t i = 0; i < secondLevelHashTable->size; i++) {
 free(secondLevelHashTable->table[i]);
 }
 free(secondLevelHashTable->table);
 free(secondLevelHashTable);
}
int main() {
 // Seed the random number generator
 srand(time(NULL));
 size_t num_elements, i;
 int query;
 char buffer[BUFFER_SIZE];
 // Reading the number of elements in the set
 if (!fgets(buffer, sizeof(buffer), stdin) || sscanf(buffer, "%zu", &num_elements) != 1 || num_elements <= 0) {
 fprintf(stderr, "Error: invalid input for the number of elements.\n");
 return EXIT_FAILURE;
 }
 int* elements = (int*)malloc(num_elements * sizeof(int*));
 if (!elements) {
 fprintf(stderr, "Error: memory allocation failed.\n");
 return EXIT_FAILURE;
 }
 // Reading the elements of the set
 if (!fgets(buffer, sizeof(buffer), stdin)) {
 fprintf(stderr, "Error: invalid input for elements.\n");
 free(elements);
 return EXIT_FAILURE;
 }
 char *token = strtok(buffer, " \t\n");
 for (i = 0; i < num_elements; i++) {
 if (!token) {
 fprintf(stderr, "Error: insufficient elements in the input.\n");
 free(elements);
 return EXIT_FAILURE;
 }
 elements[i] = (int)(uintptr_t)strtoull(token, NULL, 10);
 token = strtok(NULL, " \t\n");
 }
 struct FirstLevelHashTable* firstLevelHashTable = createFirstLevelHashTable(1LL << 3);
 if (!firstLevelHashTable) {
 fprintf(stderr, "Error: failed to create first-level hash table.\n");
 free(elements);
 return EXIT_FAILURE;
 }
 size_t* counts = countElementsByHash(elements, firstLevelHashTable, num_elements);
 if (!counts) {
 fprintf(stderr, "Error: failed to count elements by hash.\n");
 free(firstLevelHashTable);
 free(elements);
 return EXIT_FAILURE;
 }
 initializeSecondLevelHashTables(firstLevelHashTable, counts);
 for (size_t j = 0; j < firstLevelHashTable->size; j++) {
 struct SecondLevelHashTable *secondLevelHashTable = firstLevelHashTable->table[j];
 if (!secondLevelHashTable) {
 fprintf(stderr, "Error: failed to initialize second-level hash table.\n");
 free(counts);
 free(firstLevelHashTable);
 free(elements);
 return EXIT_FAILURE;
 }
 initializeHashForSecondHashTables(secondLevelHashTable, firstLevelHashTable,elements,num_elements,j);
 }
 while (1) {
 if (!fgets(buffer, sizeof(buffer), stdin)) {
 fprintf(stderr, "Error reading input.\n");
 freeFirstLevelHashTable(firstLevelHashTable);
 free(elements);
 free(counts);
 return EXIT_FAILURE;
 }
 // Check if the input is '.'
 if (buffer[0] == '.') {
 break; // End of input
 }
 // Convert input to a long long integer
 if (sscanf(buffer, "%lld", &query) != 1) {
 fprintf(stderr, "Error: incorrect input format.\n");
 freeFirstLevelHashTable(firstLevelHashTable);
 free(elements);
 free(counts);
 return EXIT_FAILURE;
 }
 if (locate(query, firstLevelHashTable)) {
 printf("YES\n");
 } else {
 printf("NO\n");
 }
 }
 freeFirstLevelHashTable(firstLevelHashTable);
 free(elements);
 free(counts);
 return EXIT_SUCCESS;
}
Source Link
user282352
user282352

Optimizing Perfect Hash Table Implementation in C for Improved Performance

I wrote code that implements perfect hash table, according to its description in the book "Introduction to Algorithms by Thomas H Cormen" but the code does not pass time tests in contest. I would really appreciate any help in making this code run faster (code must be in clear C).

(Regarding the main function, we enter the number of elements in the set Then the elements themselves. Then requests, we respond to requests with "YES"|"NO" We finish reading requests when we encounter '.')

#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#include <time.h>
#include <string.h>
#define BUFFER_SIZE 1024 // Size of buffer for input
#define P_VALUE 4294967311
struct Node {
 int key;
 int value;
};
// Define the structure for the hash table
struct SecondLevelHashTable {
 size_t size;
 size_t numElements;
 struct Node** table;
 size_t a;
 size_t b;
};
// Define the structure for the hash table
struct FirstLevelHashTable {
 size_t size;
 size_t numElements;
 struct SecondLevelHashTable** table;
 size_t a;
 size_t b;
};
// Define the hash function
size_t universalHash(int key, size_t a, size_t b, size_t m);
// Function to check if a number is prime
bool isPrime(int n);
// Function to find the minimum prime number greater than m
int findNextPrime(int m);
// Function to generate random values for a and b
void generateRandomValues(size_t *a, size_t *b);
// Function to initialize node
struct Node* initializeNode(int key, int value);
// Function to create a second-level hash table
struct SecondLevelHashTable* createSecondLevelHashTable(size_t size);
// Function to create a first-level hash table
struct FirstLevelHashTable* createFirstLevelHashTable(size_t size);
// Function to create an array of counts based on hash function results
size_t* countElementsByHash(int* keys, struct FirstLevelHashTable *firstLevelHashTable, size_t numKeys);
// Function to initialize second-level hash tables based on counts
void initializeSecondLevelHashTables(struct FirstLevelHashTable* firstLevelHashTable, size_t* counts);
// Function to initialize hash for second-level hash tables
void initializeHashForSecondHashTables(struct SecondLevelHashTable* secondLevelHashTable, struct FirstLevelHashTable* firstLevelHashTable, int* keys, size_t numKeys, size_t index);
// Function to check if an element exists in the hash table
bool locate(int x, struct FirstLevelHashTable* firstLevelHashTable);
void freeFirstLevelHashTable(struct FirstLevelHashTable* firstLevelHashTable);
void freeSecondLevelHashTable(struct SecondLevelHashTable* secondLevelHashTable);
// Define the hash function
size_t universalHash(int key, size_t a, size_t b, size_t m) {
 return ((a * key + b) % P_VALUE) % m;
}
// Function to generate random values for a and b
void generateRandomValues(size_t *a, size_t *b) {
 // Generate random values for a and b
 *a = (rand() % (P_VALUE - 1)) + 1; // Ensure a falls within the range [1, p - 1]
 *b = rand() % P_VALUE; // Ensure b falls within the range [0, p - 1]
}
// Function to initialize node
struct Node* initializeNode(int key, int value) {
 // Allocate memory for the new node
 struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
 if (newNode == NULL) {
 // Handle memory allocation failure
 perror("Memory allocation failed");
 return NULL;
 }
 // Assign key and value to the node
 newNode->key = key;
 newNode->value = value;
 return newNode;
}
struct SecondLevelHashTable* createSecondLevelHashTable(size_t size) {
 // Allocate memory for the hash table structure
 struct SecondLevelHashTable* secondLevelHashTable = (struct SecondLevelHashTable*)malloc(sizeof(struct SecondLevelHashTable));
 if (secondLevelHashTable == NULL) {
 freeSecondLevelHashTable(secondLevelHashTable);
 perror("Memory allocation failed");
 return NULL;
 }
 // Allocate memory for the array of pointers to doubly linked lists
 secondLevelHashTable->table = (struct Node**)malloc(size * sizeof(struct Node*));
 if (secondLevelHashTable->table == NULL) {
 freeSecondLevelHashTable(secondLevelHashTable);
 perror("Memory allocation failed");
 return NULL;
 }
 // Initialize each pointer in the array to NULL
 for (int i = 0; i < size; i++) {
 secondLevelHashTable->table[i] = NULL;
 }
 // Set the size and number of elements
 secondLevelHashTable->size = size;
 secondLevelHashTable->numElements = 0;
 return secondLevelHashTable;
}
struct FirstLevelHashTable* createFirstLevelHashTable(size_t size) {
 // Allocate memory for the hash table structure
 struct FirstLevelHashTable* firstLevelHashTable = (struct FirstLevelHashTable*)malloc(sizeof(struct FirstLevelHashTable));
 if (firstLevelHashTable == NULL) {
 freeFirstLevelHashTable(firstLevelHashTable);
 perror("Memory allocation failed");
 return NULL;
 }
 // Allocate memory for the array of pointers to second-level hash tables
 firstLevelHashTable->table = (struct SecondLevelHashTable**)malloc(size * sizeof(struct SecondLevelHashTable*));
 if (firstLevelHashTable->table == NULL) {
 freeFirstLevelHashTable(firstLevelHashTable);
 perror("Memory allocation failed");
 return NULL;
 }
 /**
 // Initialize each pointer in the array to NULL
 for (int i = 0; i < size; i++) {
 firstLevelHashTable->table[i] = createSecondLevelHashTable(1LL<<14);
 }
 **/
 firstLevelHashTable->size = size;
 firstLevelHashTable->numElements = 0;
 firstLevelHashTable->a = 0;
 firstLevelHashTable->b = 0;
 generateRandomValues(&firstLevelHashTable->a, &firstLevelHashTable->b);
 return firstLevelHashTable;
}
// Function to create an array of counts based on hash function results
size_t* countElementsByHash(int* keys, struct FirstLevelHashTable *firstLevelHashTable, size_t numKeys) {
 // Allocate memory for the array of counts
 size_t* counts = (size_t*)calloc(firstLevelHashTable->size, sizeof(size_t));
 if (counts == NULL) {
 perror("Memory allocation failed");
 return NULL;
 }
 // Iterate over each key
 for (size_t i = 0; i < numKeys; i++) {
 // Calculate the hash value for the current key
 size_t hashValue = universalHash(keys[i], firstLevelHashTable->a, firstLevelHashTable->b, firstLevelHashTable->size);
 // Increment the count at the corresponding index
 counts[hashValue]++;
 }
 return counts;
}
void initializeSecondLevelHashTables(struct FirstLevelHashTable* firstLevelHashTable, size_t* counts) {
 if (firstLevelHashTable == NULL || counts == NULL) {
 return;
 }
 // Iterate over each index in the first-level hash table
 for (size_t i = 0; i < firstLevelHashTable->size; ++i) {
 size_t size = counts[i] * counts[i] + 1; // Get the size from the counts array
 // Allocate memory for the second-level hash table
 struct SecondLevelHashTable* secondLevelHashTable = createSecondLevelHashTable(size);
 if (secondLevelHashTable == NULL) {
 freeSecondLevelHashTable(secondLevelHashTable);
 return;
 }
 // Assign the second-level hash table to the first-level hash table
 firstLevelHashTable->table[i] = secondLevelHashTable;
 }
}
void initializeHashForSecondHashTables(struct SecondLevelHashTable* secondLevelHashTable, struct FirstLevelHashTable* firstLevelHashTable, int* keys, size_t numKeys, size_t index) {
 if (secondLevelHashTable == NULL || keys == NULL) {
 return;
 }
 secondLevelHashTable->a = 0;
 secondLevelHashTable->b = 0;
 bool isCorrect = true;
 do {
 generateRandomValues(&secondLevelHashTable->a, &secondLevelHashTable->b);
 // Iterate over each key
 for (size_t i = 0; i < numKeys; i++) {
 // Calculate the hash value for the current key
 size_t firstHashValue = universalHash(keys[i], firstLevelHashTable->a,
 firstLevelHashTable->b,
 firstLevelHashTable->size);
 // Increment the count at the corresponding index
 if (firstHashValue == index) {
 size_t secondHashValue = universalHash(keys[i], secondLevelHashTable->a,
 secondLevelHashTable->b,
 secondLevelHashTable->size);
 //printf("%lld\n", secondLevelHashTable->size);
 if (secondLevelHashTable->table[secondHashValue] == NULL) {
 secondLevelHashTable->table[secondHashValue] = initializeNode(keys[i], 1);
 } else {
 isCorrect = false;
 break;
 }
 }
 }
 } while (isCorrect != true);
}
bool locate(int x, struct FirstLevelHashTable* firstLevelHashTable) {
 // Calculate the hash value for the input key
 size_t firstHashValue = universalHash(x, firstLevelHashTable->a, firstLevelHashTable->b, firstLevelHashTable->size);
 // Get the corresponding second-level hash table
 struct SecondLevelHashTable* secondLevelHashTable = firstLevelHashTable->table[firstHashValue];
 if (secondLevelHashTable == NULL) {
 return false; // No elements at this index
 }
 // Calculate the hash value for the input key in the second-level hash table
 size_t secondHashValue = universalHash(x, secondLevelHashTable->a, secondLevelHashTable->b, secondLevelHashTable->size);
 // Check if the key exists in the second-level hash table
 if (secondLevelHashTable->table[secondHashValue] != NULL && secondLevelHashTable->table[secondHashValue]->key == x) {
 return true; // Key exists
 }
 return false; // Key does not exist
}
void freeFirstLevelHashTable(struct FirstLevelHashTable* firstLevelHashTable) {
 if (firstLevelHashTable == NULL) {
 return;
 }
 for (size_t i = 0; i < firstLevelHashTable->size; ++i) {
 struct SecondLevelHashTable* secondLevelHashTable = firstLevelHashTable->table[i];
 freeSecondLevelHashTable(secondLevelHashTable);
 }
 free(firstLevelHashTable->table);
 free(firstLevelHashTable);
}
void freeSecondLevelHashTable(struct SecondLevelHashTable* secondLevelHashTable) {
 if (secondLevelHashTable == NULL) {
 return;
 }
 for (size_t i = 0; i < secondLevelHashTable->size; i++) {
 free(secondLevelHashTable->table[i]);
 }
 free(secondLevelHashTable->table);
 free(secondLevelHashTable);
}
int main() {
 // Seed the random number generator
 srand(time(NULL));
 size_t num_elements, i;
 int query;
 char buffer[BUFFER_SIZE];
 // Reading the number of elements in the set
 if (!fgets(buffer, sizeof(buffer), stdin) || sscanf(buffer, "%zu", &num_elements) != 1 || num_elements <= 0) {
 fprintf(stderr, "Error: invalid input for the number of elements.\n");
 return EXIT_FAILURE;
 }
 int* elements = (int*)malloc(num_elements * sizeof(int*));
 if (!elements) {
 fprintf(stderr, "Error: memory allocation failed.\n");
 return EXIT_FAILURE;
 }
 // Reading the elements of the set
 if (!fgets(buffer, sizeof(buffer), stdin)) {
 fprintf(stderr, "Error: invalid input for elements.\n");
 free(elements);
 return EXIT_FAILURE;
 }
 char *token = strtok(buffer, " \t\n");
 for (i = 0; i < num_elements; i++) {
 if (!token) {
 fprintf(stderr, "Error: insufficient elements in the input.\n");
 free(elements);
 return EXIT_FAILURE;
 }
 elements[i] = (int)(uintptr_t)strtoull(token, NULL, 10);
 token = strtok(NULL, " \t\n");
 }
 struct FirstLevelHashTable* firstLevelHashTable = createFirstLevelHashTable(1LL << 3);
 if (!firstLevelHashTable) {
 fprintf(stderr, "Error: failed to create first-level hash table.\n");
 free(elements);
 return EXIT_FAILURE;
 }
 size_t* counts = countElementsByHash(elements, firstLevelHashTable, num_elements);
 if (!counts) {
 fprintf(stderr, "Error: failed to count elements by hash.\n");
 free(firstLevelHashTable);
 free(elements);
 return EXIT_FAILURE;
 }
 initializeSecondLevelHashTables(firstLevelHashTable, counts);
 for (size_t j = 0; j < firstLevelHashTable->size; j++) {
 struct SecondLevelHashTable *secondLevelHashTable = firstLevelHashTable->table[j];
 if (!secondLevelHashTable) {
 fprintf(stderr, "Error: failed to initialize second-level hash table.\n");
 free(counts);
 free(firstLevelHashTable);
 free(elements);
 return EXIT_FAILURE;
 }
 initializeHashForSecondHashTables(secondLevelHashTable, firstLevelHashTable,elements,num_elements,j);
 }
 while (1) {
 if (!fgets(buffer, sizeof(buffer), stdin)) {
 fprintf(stderr, "Error reading input.\n");
 freeFirstLevelHashTable(firstLevelHashTable);
 free(elements);
 free(counts);
 return EXIT_FAILURE;
 }
 // Check if the input is '.'
 if (buffer[0] == '.') {
 break; // End of input
 }
 // Convert input to a long long integer
 if (sscanf(buffer, "%lld", &query) != 1) {
 fprintf(stderr, "Error: incorrect input format.\n");
 freeFirstLevelHashTable(firstLevelHashTable);
 free(elements);
 free(counts);
 return EXIT_FAILURE;
 }
 if (locate(query, firstLevelHashTable)) {
 printf("YES\n");
 } else {
 printf("NO\n");
 }
 }
 freeFirstLevelHashTable(firstLevelHashTable);
 free(elements);
 free(counts);
 return EXIT_SUCCESS;
}
```
lang-c

AltStyle によって変換されたページ (->オリジナル) /