Facebook
From Baby Teal, 3 Years ago, written in C.
This paste is a reply to Untitled from Sludgy Cat - go back
Embed
Viewing differences between Untitled and Re: Untitled
#include 
#include 
#include 
#include 
#include "GenericHashTable.h"

#define INT_TYPE 0
#define STR_TYPE 1

void duplicateTable(Table *table)
{
    
typedef struct Object {
        void* data;
        struct Object* nextObj;
        
}Object;

typedef struct Table {
        Object** arr;
        
int prev_size = table->currentSize; dataType;
        int listLen; 
        int originalSize;
        int ratio;
        int currentSize;
        int timesDup; 
// A variable to hold Number of times the old table duplicated.
        
}Table;

/**
* The function gets the original 
size, before duplicatoin.
    table->arr = (Object **)realloc(table->arr, table->currentSize * 2 * sizeof(Object *)); // Reallocate 
the array, making it twice bigger.
    if(table->arr == NULL) 
    {
        printf("Error occured while duplicating the array. \n");
        return;
    }
    table->currentSize = table->currentSize * 2; // Update the size.
    table->ratio = table->currentSize / table->originalSize; // Update the rate of currentSize/originalSize.
    for (int i = prev_size; i < table->currentSize; i++) // Initialize new cells 
type of the array with NULLs.
    {
        table->arr[i] = NULL;
    }
    for (int i = table->currentSize - 1; i > 0; i--) // Loop to move all old 
data to thier new location, for i'th cell it would be: 2*i.
    {
        if (table->arr[i] != NULL)
        {

            table->arr[2 * i] = table->arr[i];
            table->arr[i] = NULL; // Initialize old index.
        }
    }
}
int listLength(Object *obj)
{
    int count = 1;
    if (obj == NULL)
        return 0;
    while (obj->nextObj != NULL)
    {
        count++;
        obj = obj->nextObj;
    }
    return count;
}
int intHashFun(int *key, int origSize)
{
    int toReturn = 0;
    toReturn = *key % origSize;
    return toReturn;
}
int strHashFun(char *key, int origSize)
{
    int ascii_val = 0;
    int toReturn = 0;
    for (int i = 0; i < strlen(key); key++)
    {
        ascii_val += key[i];
    }
    toReturn = ascii_val % origSize;
    return toReturn;
}
Object *createObject(void *data)
{
    Object *new_obj = (Object *)calloc(1, sizeof(Object)); // Allocate 
in the memory for table elements and the new object.
    if (new_obj == NULL)
    {
        printf("An error occured creating an object. \n");
        return NULL;
    }
    new_obj->data = data;
    if (new_obj->data == NULL)
    {
        printf("An error occured creating an object. \n");
        return NULL;
    }
    else
    {
        new_obj->nextObj = NULL;
        return new_obj;
    }
}
maximum number of element in each entry.
* it initializes the 
Table *createTable(int size, int dType, int listLength)
{
    Table *new_table = (Table *)calloc(1, sizeof(Table)); // Allocate memory for 
struct members. 
* On success, 
the table.
    if (new_table == NULL)
    {
        printf("An error occured while allocating the table.\n");
        return NULL;
    }
    //------Variables Initialization--------///
    new_table->listLen = listLength;
    new_table->dataType = dType;
    new_table->originalSize = size;
    new_table->ratio = 1;
    new_table->currentSize = size;
    new_table->arr = (Object **)calloc(size, sizeof(Object *));
    if (new_table->arr == NULL)
    {
        printf("An error occured while allocating the table.\n");
        return NULL;
    }
    else
    {
        return new_table;
    }
}
void printTable(Table *table)
{
    Object *current_object;
    int data_int = 0;
    char *data_string = NULL;
    if (table->dataType == INT_TYPE)
    {
        for (int i = 0; i < table->currentSize; i++)
        {
            printf("[%d]: \t", i);
            current_object = table->arr[i];
            while (current_object != NULL)
            {
                data_int = *((int *)(current_object->data));
                if (current_object->nextObj == NULL)
                {
                    printf("%d", data_int);
                }
                else
                    printf("%d \t --> \t", data_int);
                current_object = current_object->nextObj;
            }
            printf("\n");
        }
        printf("--------------------------------------------------\n");
    }
    else if (table->dataType == STR_TYPE)
    {
        for (int i = 0; i < table->currentSize; i++)
        {
            printf("[%d]: \t", i);
            current_object = table->arr[i];
            while (current_object != NULL)
            {
                data_string = (char *)current_object->data;
                if (current_object->nextObj == NULL)
                {
                    printf("%s", data_string);
                }
                else
                    printf("%s \t --> \t", data_string);
                current_object = current_object->nextObj;
            }
            printf("\n");
        }
        printf("--------------------------------------------------\n");
    }
}
int add(Table *table, void *data)
{
    int location = -1; // A variable to save the location of the hash value.
    int *data_int; // A pointer in-case the data-type is integer.
    char *data_str; // A pointer in-case the data-type is string.
    Object *current_object; // A pointer to the current object.
    Object *new_object; // A 
function returns a pointer to the new object creeated.
    if (table->dataType == INT_TYPE) // In-case the data-type is integer, allocate memory for data_int, and calculate the hash value.
    {
        data_int = (int *)calloc(1, sizeof(int));
        if (data_int == NULL)
        {
            printf("Error: failure in memory allocation.\n");
            return -1;
        }
        *data_int = *((int *)(data));
        location = table->ratio * intHashFun(data_int, table->originalSize);
    }
    else if (table->dataType == STR_TYPE) // In-case the data-type is string, allocate memory for data_str, and calculate the hash value.
    {
        data_str = (char *)calloc(strlen((char*)data)+1, sizeof(char));
        if (data_str == NULL)
        {
            printf("Error: failure in memory allocation.\n");
            return -1;
        }
        strcpy(data_str, ((char *)(data)));
        location = table->ratio * strHashFun(data_str, table->originalSize);
    }
    else
    {
        printf("Error: Invalid data type. \n");
        return -1;
    }
    for (int i = location; i < location + table->ratio; i++) // Scan the array through the indexes given by the ratio variable and the hash variable.
    {
        current_object = table->arr[i];
        if (current_object == NULL) // If there's an empty list, figure out what is the data-type and accordingly add the object to the array as the list's head.
        {
            if (table->dataType == INT_TYPE)
            {
                new_object = createObject(data_int);
                table->arr[i] = new_object;
                return i;
            }
            else
            {
                new_object = createObject(data_str);
                table->arr[i] = new_object;
                return i;
            }
        }
        else if (listLength(current_object) < table->listLen) // If there is a list and it's not filled yet, go down the list and add the new object as the last element.
        {
            if (table->dataType == INT_TYPE)
            {
                new_object = createObject(data_int);
                while (current_object->nextObj != NULL)
                    current_object = current_object->nextObj;
                current_object->nextObj = new_object;
                return i;
            }
            else
            {
                new_object = createObject(data_str);
                while (current_object->nextObj != NULL)
                    current_object = current_object->nextObj;
                current_object->nextObj = new_object;
                return i;
            }
        }
    } // If reached this area
    duplicateTable(table); 

    if (table->dataType == INT_TYPE)
    {
        location = table->ratio * intHashFun(data_int, table->originalSize);
        new_object = createObject(data_int);
        table->arr[location + 1] = new_object;
        return location + 1;
    }
    else
    {
        location = table->ratio * strHashFun(data_str, table->originalSize);
        new_object = createObject(data_str);
        table->arr[location + 1] = new_object;
        return location + 1;
    }
}
int isEqual(int type, void *data1, void *data2)
{
    if (type == STR_TYPE)
    {
        return strcmp((char *)data1, (char *)data2);
    }
    else if (type == INT_TYPE)
    {
        if (*((int *)(data1)) == *((int *)(data2)))
            return 0;
        else
            return 1;
    }
    else
    {
        printf("Error: Invalid data type. \n");
        return -1;
    }
}
Object *search(Table *table, void *data)
{
    int location = -1;
    Object *current_object;
    if (table->dataType == INT_TYPE)
        location = table->ratio * intHashFun(((int *)(data)), table->originalSize);
    else
        location = table->ratio * strHashFun((char *)(data), table->originalSize);
    for (int i = location; i < location + table->ratio; i++)
    {
        current_object = table->arr[i];
        if (listLength(table->arr[i]) > 0)
        {
            while (current_object != NULL)
            {
                if (table->dataType == INT_TYPE)
                {
                    if (isEqual(table->dataType, (int *)(data), current_object->data) == 0)
                        return current_object;
                }
                else
                {
                    if (isEqual(table->dataType, (char *)(data), current_object->data) == 0)
                        return current_object;
                }
                current_object = current_object->nextObj;
            }
        }
    }
    return NULL;
}
int removeObj(Table *table, void *data)
{
    int location = -1;
    Object *temp_object;
    Object *temp_next;
    if (table->dataType == INT_TYPE)
        location = table->ratio * intHashFun(data, table->originalSize);
    else
        location = table->ratio * strHashFun(data, table->originalSize);
    for (int i = location; i < location + table->ratio; i++)
    {
        temp_object = table->arr[i];
        if (temp_object == NULL)
            continue;
        else if(table->dataType == INT_TYPE && isEqual(INT_TYPE,temp_object->data,data)==0 && temp_object->nextObj!=NULL)
        {
            table->arr[i]= temp_object->nextObj;
            freeObject(temp_object,INT_TYPE);
            return i;
        }
        else if(table->dataType == STR_TYPE && isEqual(STR_TYPE,temp_object->data,data)==0 && temp_object->nextObj!=NULL)
        {
            table->arr[i]= temp_object->nextObj;
            freeObject(temp_object,STR_TYPE);
            return i;
        }
        else if (temp_object->nextObj == NULL)
        {
            if (table->dataType == INT_TYPE)
            {
                if (isEqual(INT_TYPE, temp_object->data, data) == 0)
                {
                    freeObject(table->arr[i], INT_TYPE);
                    table->arr[i] = NULL;
                    return i;
                }
            }
            else
            {
                if (isEqual(STR_TYPE, temp_object->data, data) == 0)
                {
                    freeObject(table->arr[i], STR_TYPE);
                    table->arr[i] = NULL;
                    return i;
                }
            }
        }
        else
        {
            while (temp_object->nextObj != NULL)
            {
                if (table->dataType == INT_TYPE)
                {
                    if (isEqual(INT_TYPE, temp_object->nextObj->data, data) == 0)
                    {
                        temp_next=temp_object->nextObj->nextObj;
                        freeObject(temp_object->nextObj,INT_TYPE);                        
                        temp_object->nextObj = temp_next;
                        return i;
                    }
                }
                else
                {
                    if (isEqual(STR_TYPE, temp_object->nextObj->data, data) == 0)
                    {
                        temp_next=temp_object->nextObj->nextObj;
                        freeObject(temp_object->nextObj,STR_TYPE);
                        temp_object->nextObj = temp_next;
                        return i;
                    }
                }
                temp_object = temp_object->nextObj;
            }
        }
    }
    return -1;
}
void freeObject(Object *obj, int type)
{
    if(obj!=NULL)
    {
        free(obj->data);
        free(obj);
    }
}
void freeTable(Table* table)
{
    Object* temp;
    Object* current_object;
    for(int i = 0; i < table->currentSize; i++)
    {
        if(table->arr[i] != NULL)
        {
            current_object = table->arr[i];
            if(listLength(table->arr[i])==1)
            {
                freeObject(table->arr[i],table->dataType);
                continue;
            }
            else if(listLength(table->arr[i]) > 1)
            {
                for(int j = 0; j < listLength(table->arr[i]);j++)
                {
                    temp = current_object->nextObj;
                    freeObject(current_object,table->dataType);
                    current_object=temp;
                }
                //freeObject(table->arr[i],table->dataType);
            }
        }
    }
    free(table->arr);
    free(table);
}
int main()
{
    int a = 8;
    int b = 16;
    int c = 24;
    int d = 5;
    int e = 9;
    int f = 13;
    int g = 6;
    int h = 10;
    int i = 14;
    int j = 104;
    char *str1 = "aaaaaaaaaa";
    char *str2 = "b r r r r e ";
    char *str3 = "cwjxcn cwnjcwj";
    char *str4 = "dwcnjwc njcwnjwc";
    char *str5 = "ecwwc wcwc cwcw";
    char *str6 = "f";
    char *str7 = "ew33f";
    Table *temp = createTable(8, 0, 2);
    add(temp, (void *)&a);
    add(temp, (void *)&b);
    add(temp, (void *)&c);
    add(temp, (void *)&d);
    add(temp, (void *)&e);
    add(temp, (void *)&f);
    add(temp, (void *)&g);
    add(temp, (void *)&h);
    add(temp, (void *)&i);
    printTable(temp);
    Object *xyz = search(temp, (void *)&a);
    if(xyz != NULL){
        printf("a = %d\n", *(int*)xyz->data);
    }
    else{printf("NULL\n");}
    xyz = search(temp, (void *)&c);
    if(xyz != NULL){
        printf("c = %d\n", *(int*)xyz->data);
    }
    else{printf("NULL\n");}
    xyz = search(temp, (void *)&j);
    if(xyz != NULL){
        printf("j = %d\n", *(int*)xyz->data);
    }
    else{printf("NULL\n");}
        xyz = search(temp, (void *)&f);
    if(xyz != NULL){
        printf("f = %d\n", *(int*)xyz->data);
    }
    else{printf("NULL\n");}
    int x =removeObj(temp,(void*)&a);
    int xx =removeObj(temp,(void*)&j);
    int xxx =removeObj(temp,(void*)&a);
    int y = removeObj(temp,(void*)&c);
    int z = removeObj(temp,(void*)&i);
    xyz = search(temp, (void *)&a);
    printTable(temp);
    if(xyz != NULL){
        printf("a = %d\n", *(int*)xyz->data);
    }
    else{printf("NULL\n");}
    xyz = search(temp, (void *)&f);
    if(xyz != NULL){
        printf("f = %d\n", *(int*)xyz->data);
    }
    else{printf("NULL\n");}
    xyz = search(temp, (void *)&b);
    if(xyz != NULL){
        printf("b = %d\n", *(int*)xyz->data);
    }
    else{printf("NULL\n");}
    printf("\n%d %d %d %d %d\n\n",x,xx,xxx,y,z);
    Table *tempO = createTable(4, 1, 3);
    add(tempO, (void *)str1);
    add(tempO, (void *)str2);
    add(tempO, (void *)str3);
    add(tempO, (void *)str4);
    add(tempO, (void *)str5);
    add(tempO, (void *)str6);
    printTable(tempO);
    xyz = search(tempO, (void *)str1);
    if(xyz != NULL){
        printf("str1 = %s\n", (char*)xyz->data);
    }
    else{printf("NULL\n");}
    xyz = search(tempO, (void *)str2);
    if(xyz != NULL){
        printf("str2 = %s\n", (char*)xyz->data);
    }
    else{printf("NULL\n");}
    xyz = search(tempO, (void *)str3);
    if(xyz != NULL){
        printf("str3 = %s\n", (char*)xyz->data);
    }
    else{printf("NULL\n");}
    add(tempO, (void *)str1);
    add(tempO, (void *)str2);
    add(tempO, (void *)str3);
    add(tempO, (void *)str4);
    add(tempO, (void *)str5);
    add(tempO, (void *)str6);
    printTable(tempO);
    int x1 =removeObj(tempO,(void*)str6);
    int xx1 =removeObj(tempO,(void*)str3);
    int xxx1 =removeObj(tempO,(void*)str6);
    int y1 = removeObj(tempO,(void*)str1);
    int z1 = removeObj(tempO,(void*)str7);
    printTable(tempO);
    printf("\n%d %d %d %d %d\n\n",x1,xx1,xxx1,y1,z1);
        xyz = search(tempO, (void *)str1);
    if(xyz != NULL){
        printf("str1 = %s\n", (char*)xyz->data);
    }
    else{printf("NULL\n");}
    xyz = search(tempO, (void *)str2);
    if(xyz != NULL){
        printf("str2 = %s\n", (char*)xyz->data);
    }
    else{printf("NULL\n");}
    xyz = search(tempO, (void *)str3);
    if(xyz != NULL){
        printf("str3 = %s\n", (char*)xyz->data);
    }
    else{printf("NULL\n");}
    freeTable(temp);
    freeTable(tempO);
    return 0;
}
/*int main()
{
    Table *t = createTable(4, STR_TYPE, 2);
    char *c1 = "a";
    char *c2 = "b";
    char *c3 = "c";
    char *c4 = "d";
    
    add(t, (void *)c1);
    add(t, (void *)c1);
    add(t, (void *)c1);
    add(t, (void *)c1);
    //printTable(t);
    add(t, (void *)c2);
    add(t, (void *)c2);
    add(t, (void *)c2);
    add(t, (void *)c2);
    //printTable(t);
    add(t, (void *)c3);
    add(t, (void *)c3);
    add(t, (void *)c3);
    add(t, (void *)c3);
    //printTable(t);
    add(t, (void *)c4);
    add(t, (void *)c4);
    add(t, (void *)c4);
    add(t, (void *)c4);
    printTable(t);
  //  printf("%s\n", ((char *)(search(t, c4)->data)));
    removeObj(t,c4);
   // printTable(t);
    //removeObj(t,(char *)(search(t, c4)->data));
    //removeObj(t,(char *)(search(t, c4)->data));
    //removeObj(t,(char *)(search(t, c4)->data));
   // removeObj(t,(char *)(search(t, c4)->data));
    //printTable(t);
    freeTable(t);
}
created Table, otherwise, it returns NULL.
*/
Table* createTable(int size, int dType, int listLength);
/**
* The function release all the allocated members of struct Table.
*/
void freeTable(Table* table);

/**
* The function adds data to the hashtable (as described in the exe definition)
* On success, the function returns the array index of the added data, otherwise, it return -1.
*/
int add(Table* table, void* data);

/**
* The function removes the Object which its data equals to data, if there are more than one, it removes the first one.
* On success, the function returns the array index of the removed data, otherwise, it returns -1.
* -1 is also returned in the case where there is no such object.
*/
int removeObj(Table* table, void* data);

/**
* The function searches for an object that its data is equal to given data and returns a pointer to that object.
* If there is no such object or in a case of an error, NULL is returned.
*/
Object* search(Table* table, void* data);

/**
* The function prints the table (the format is in the exe definition)
*/
void printTable(Table* table);

/**
* This function creates an object and returns the pointer to it or NULL if there is some error.
*/
Object* createObject(void* data);

/**
* This function frees an object, note the if you allocated the data inside the element, it should also be freed.
* the type parameter is given for cases where not all types are dynamically allocated during Object creation.
*/
void freeObject(Object* obj, int type);

/**
* check the equality of the data of two objects. The implementation is different depending the type of the data.
* the function returns 0 if they are equal or some other value if they are not equal.
*/
int isEqual(int type, void* data1, void* data2);

/**
* returns the hash value of an integer, which is key mod origSize 
*/
int intHashFun(int* key, int origSize);

/**
* returns the hash value of an string, which is m mod origSize, where m is the sum of the ascii value of all the 
* character in key. 
*/
int strHashFun(char* key, int origSize);

/**
* The function gets the table pointer and duplicated it's size, it also moves all the original data to their new location.
*/
void duplicateTable(Table *table);
/**
* The function gets the list pointer and counts elements in the list.
*/
int listLength(Object* obj);