is there a way to avoid using this function twice?

60 Views Asked by At
void inputData(){
        printf("Enter contact name  : "); gets(temp.name);
        fflush(stdin);
        printf("Enter contact email : "); gets(temp.email);
        fflush(stdin);
        printf("Enter contact phone number : "); gets(temp.phoneNum);
        fflush(stdin);
        int index = hash(temp.phoneNum, sizeof(table1.listContact)/sizeof(table1.listContact[0]));
        if (checkDuplicate(index)){
            puts("Number is used");
            return;
        }
        if(strcmp(table1.listContact[index].phoneNum, "foo")){
            index = linearRehash(index, sizeof(table1.listContact)/sizeof(table1.listContact[0]));
            if (index == -1){
                puts("Memory Full);
                return;
            } 
            if (checkDuplicate(index)){
                puts("Number is used");
                return;
            } 
        }
        strcpy(table1.listContact[index].name, temp.name);
        strcpy(table1.listContact[index].email, temp.email);
        strcpy(table1.listContact[index].phoneNum, temp.phoneNum);
} 

I'm using hash tables to create a contact list, and to prevent entering the same phone number i think i need to check the data (using checkDuplicate()) in the index twice (once after the first hash, second after the rehashing), is there a way so i only need to check it once?

int checkDuplicate(int index){
    if (!strcmp(table1.listContact[index].phoneNum, temp.phoneNum)){
            return 1;
        }
        return 0;
}
int linearRehash(int hash, int m){
    int i = 0;
    while (strcmp(table1.listContact[hash].phoneNum, "foo")){
        hash = (hash+1)%m;
        if (checkDuplicate(hash)){
            return hash;
        }//If duplicate found, return index with the same data
        if (i == m){
            return -1;
        }//If no space in hashtable return -1
        i++;
    }
    return hash;
}
1

There are 1 best solutions below

0
David Alexander On

I think it's the checkDuplicate inside the linearRehash function that you want to avoid doubling up on, right?

First of all, I think linearRehash could be modified into something like linearHash, which would do the initial hashing and the rehashing. Then all the duplicate checking could be done inside linearHash.

You'd still need a way for linearHash to return three different types of values: "memory full" (currently -1), "duplicate found" (currently just returns the index) and "available space found" (also currently just returns the index). Of course there are ways that you can do this (e.g. passing data through pointer parameters), but that seems unnecessarily complicated.

Instead I would suggest changing your "empty space" representation from "foo" to either a NULL pointer (if phoneNum is a pointer) or an empty string (if phoneNum is a fixed length char array). Then you can check if you're looking at an empty slot without doing a strcmp (either phoneNum == NULL or phoneNum[0] == '\0'). Then just have linearHash return the index of the slot found (either a duplicate or an empty slot, or -1 if memory full), and then have inputData check the returned index to see if it points to an empty slot (in which case insert the details into the slot) or a non-empty slot (in which case print "Number is used").

Of course, you're still doing that extra "empty slot" check on the returned value, but it doesn't matter so much.