0
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;
}
  • 2
    [Don't ever use gets()](https://stackoverflow.com/q/1694036/1679849) – r3mainer Jun 06 '22 at 07:27
  • 1
    And [don't use `fflush(stdin)`](https://stackoverflow.com/q/2979209/10871073). – Adrian Mole Jun 06 '22 at 07:43
  • I have no idea what `linearRehash()` is supposed to do (or why you don't just delete it). Also note that it's extremely common for 2 or more people to use the same phone number (working at the same company/business, family sharing a smartphone with their kids, people using "house phone" and not mobile phone). – Brendan Jun 06 '22 at 08:14

1 Answers1

0

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.

David Alexander
  • 659
  • 1
  • 4