/*--- wordlist.c -------------------------- Listing 3-4 -------
* Lists all words in a text file by storing them in a hash
* table. Must be linked to the linked-list primitives of
* Chapter 2 and to ElfHash() of Listing 3-3.
*-------------------------------------------------------------*/
/* uncomment the following line to print all words
* with their associated hash value.
*/
// #define LIST_HASH 1
/* #define LIST_HASH 1 */
/* uncomment the following line to print the unique words
* and a count of their frequency.
*/
#define LIST_WORDS 1
/* #define LIST_WORDS 1 */
/* comment out the following line if you do not want an
* an analysis of the hashing function and hash table load.
*/
// #define LIST_TABLE_STATS 1
/* uncomment the following line if you want a listing
* of all words > 10 letters. Such words are often typing
* or scanning errors in the text or odd constructs.
*/
#define LIST_LONG_WORDS 1
#include
#include
#include
#include
#include "llgen.h" /* Header for generic linked lists */
#include "llapp.h" /* Header for appl.'s linked lists */
extern unsigned long ElfHash ( char *);
extern unsigned int HashPJW ( char * );
/*--- the hash table portion ---*/
//#define TABLE_SIZE 1999 /* Number of slots; a prime number */
#define TABLE_SIZE 7 /* Number of slots; a prime number */
Link *Table; /* Our table is an array of Links */
#if 0
int CreateTable ( Link **t )
{
*t = calloc ( TABLE_SIZE, sizeof ( Link ));
return ( *t == NULL ? 0 : 1 );
}
#endif
/*--------------------------------------------------------------
* We use calloc() to allocate the table. However, on some
* compilers the bit pattern used by calloc() for initialization
* is not the same as NULL (which is what we want). So we check
* for this condition and, if it occurs, intialize the table by
* hand to NULLs.
*-------------------------------------------------------------*/
int CreateTable ( Link **t )
{
int i;
*t = (Link *) calloc ( TABLE_SIZE, sizeof ( Link ));
if ( *t == NULL )
return ( 0 );
if ( **t != NULL ) /* is the calloc'd memory == NULL? */
{
for ( i = 0; i < TABLE_SIZE; i++, t++ )
**t = NULL;
}
return ( 1 );
}
/* === main line === */
int main ( int argc, char *argv[] )
{
char word[64]; /* the raw word from the file */
char buffer[128];
char *phoneNum;
char *name;
char *age;
char *pw; /* pointer to the word */
int c, i, j;
int chains, /* counts how many chains */
chain_table[33]; /* table of chain lengths */
/* for our report. */
int add_status; /* return value from table add*/
unsigned hash_key;
struct List *L1, /* list for hash table entries*/
*long_wd; /* list of long words */
struct NodeData1 nd; /* the node we add each time */
struct Node n; /* used for scratch purposes */
FILE *fin; /* the input file */
if ( argc < 2 )
{
fprintf ( stderr, "Error! Usage: wordlist filename\n" );
exit ( EXIT_FAILURE );
}
if ( argc > 2 )
fprintf
( stderr, "Warning: Usage: wordlist filename\n" );
fin = fopen ( argv[1], "rt" );
if ( fin == NULL )
{
fprintf ( stderr, "Could not find/open %s\n", argv[1] );
exit ( EXIT_FAILURE );
}
/*--- create the table ---*/
if ( ! CreateTable ( &Table ))
{
fprintf ( stderr, "Error! Could not create table\n" );
exit ( EXIT_FAILURE );
}
/*--- set up linked-list data structures ---*/
L1 = CreateLList ( CreateData1, /* in llapp.c */
DeleteData1, /* " */
DuplicatedNode1, /* " */
NodeDataCmp1 ); /* " */
long_wd = CreateLList ( CreateData2, /* in llapp.c */
DeleteData2, /* " */
DuplicatedNode2, /* " */
NodeDataCmp2 ); /* " */
if ( L1 == NULL || long_wd == NULL )
{
fprintf ( stderr, "Error creating linked list\n" );
exit ( EXIT_FAILURE );
}
/*--- begin processing file ---*/
while (!feof(fin))
{
if (fgets(buffer, 127, fin) == NULL)
break;
buffer[strlen(buffer) - 1] = '\0';
phoneNum = strtok(buffer, ",");
name = strtok(NULL, ",");
age = strtok(NULL, ",");
/*--- get the hash value ---*/
hash_key = (unsigned int) ElfHash ( phoneNum );
hash_key %= TABLE_SIZE;
#ifdef LIST_HASH
printf ( "%15s %3d\n", phoneNum, hash_key );
#endif
/*--- insert into table ---*/
L1->LHead = Table[hash_key];
nd.phoneNum = phoneNum;
nd.name = name;
nd.age = age;
add_status = AddNodeAscend ( L1, &nd );
if ( add_status == 0 )
printf ( "Warning! Error while allocating node.\n" );
Table[hash_key] = L1->LHead;
}
/*--- now dump the table ---*/
for ( j = 0; j < 33; j++ ){
chain_table[j] = 0;
}
for ( i = 0; i < TABLE_SIZE; i++ )
{
Link pcurr; /* Node we're examining */
pcurr = Table[i]; /* set to start of list */
if ( pcurr == NULL ) /* skip empty slots */
continue;
else
{
int chain_len;
for ( chain_len = 0; ; pcurr = pcurr->next )
{
memcpy ( &n, pcurr, sizeof ( struct Node ));
#ifdef LIST_WORDS
/* Print each word and the count of occurrences */
printf ( "%-20s %-20s %-5s\n",
( (pND1) n.pdata)->phoneNum,
( (pND1) n.pdata)->name,
( (pND1) n.pdata)->age );
#endif
chain_len += 1;
if ( pcurr->next == NULL )
break;
}
if ( chain_len > 32 )
chain_len = 32;
chain_table[chain_len] += 1;
}
}
#ifdef LIST_TABLE_STATS
chains = 0;
for ( i = 32; i > 0; i-- )
{
if ( chain_table[i] == 0 )
continue;
else
{
printf ( "%3d chains of length %2d\n",
chain_table[i], i );
chains += chain_table[i];
}
}
if ( chains != 0 )
{
printf ( "\n%d Nodes in %u chains\n\n",
L1->LCount, chains );
printf ( "Size of hash table = %u\n",
(unsigned) TABLE_SIZE );
printf ( "Average chain length = %f\n",
L1->LCount / (double)chains );
printf ( "Slot Occupancy = %f \n",
( (double)chains ) / TABLE_SIZE );
printf ( "Load Factor = %f \n",
( (double)L1->LCount ) / TABLE_SIZE );
}
else
printf ( "Error! No chains found.\n" );
#endif
while(1)
{
Link pcurr;
printf("please input you want to search...\n");
scanf("%s" ,phoneNum);
hash_key = (unsigned int) ElfHash ( phoneNum );
hash_key %= TABLE_SIZE;
pcurr = Table[hash_key];
if (pcurr == NULL)
{
printf("Did not find\n");
printf("=====================\n");
continue;
}
else
{
for ( ; ; pcurr = pcurr->next )
{
memcpy ( &n, pcurr, sizeof ( struct Node ));
// if (*(((pND1)n.pdata)->phoneNum) == *phoneNum)
if (strcmp(((pND1)n.pdata)->phoneNum, phoneNum) == 0)
{
printf("this is you want...\n");
printf ( "%-20s %-20s %-5s\n",
( (pND1) n.pdata)->phoneNum,
( (pND1) n.pdata)->name,
( (pND1) n.pdata)->age );
printf("=====================\n");
break;
}
if ( pcurr->next == NULL )
{
printf("Did not find\n");
printf("=====================\n");
break;
}
}
}
}
system("pause");
return ( EXIT_SUCCESS );
}