COMPLETED PA10 and CS249!

+- HashUtility.c
This commit is contained in:
Charles Descamps 2023-11-15 15:12:03 -07:00
parent 6911280eb5
commit a62aa61957

View file

@ -4,6 +4,10 @@
#include "StateDataUtility.h" #include "StateDataUtility.h"
// constants // constants
const int MINIMUM_HASH_LETTER_COUNT = 7;
const int ITEM_NOT_FOUND = -1;
const bool USED_NODE = true;
const bool UNUSED_NODE = false;
/* Data Structures /* Data Structures
typedef struct HashStruct typedef struct HashStruct
@ -34,8 +38,13 @@ Dependencies: setDataNodeFromData, addItemFromStruct
bool addItemFromData( ProbingHashType *hashTable, const char *stateName, bool addItemFromData( ProbingHashType *hashTable, const char *stateName,
double avgTemp, double lowTemp, double highTemp ) double avgTemp, double lowTemp, double highTemp )
{ {
// return false (temp) StateDataType createState;
return false; // sets a node from the data using the function
setDataNodeFromData(&createState, stateName, avgTemp,
lowTemp, highTemp, UNUSED_NODE);
// uses add item from struct to add the data and do the calling.
// return addItemFromStruct
return addItemFromStruct(hashTable, createState);
} }
/* /*
@ -55,9 +64,59 @@ Dependencies: getHashIndex, privateToPower, printf, stateDataToString,
*/ */
bool addItemFromStruct( ProbingHashType *hashTable, StateDataType newItem ) bool addItemFromStruct( ProbingHashType *hashTable, StateDataType newItem )
{ {
// return false (temp) // initialize function/variables
char stateString[MAX_STR_LEN];
// create offset variable
int hashOffset = 0;
// get hash value, assign to hashIndex variable
int hashIndex = getHashIndex(*hashTable, newItem);
// set a temp node with index
StateDataType currentNode;
int workingIndex = hashIndex;
setDataNodeFromStruct(&currentNode, newItem);
// loop until location found
// iterate no more than HT size AND element is in use
printf("\nIndices Probed: %d", workingIndex);
while(workingIndex <= hashTable->tableSize &&
hashTable->array[workingIndex].inUse)
{
// increment the offset variable
hashOffset = hashOffset + 1;
// check for linear probe type
if(hashTable->probeStrategy == LINEAR_PROBING)
{
// set working variable to the hash index plus the offset
workingIndex = hashIndex + hashOffset;
printf(", %d", workingIndex % hashTable->tableSize);
}
// otherwise, assume quadratic probe type
else
{
// set working variable to the hash index plus the offset squared
workingIndex = hashIndex + privateToPower(hashOffset, 2);
printf(", %d", workingIndex % hashTable->tableSize);
}
// mod by table size to keep index in bounds
workingIndex = workingIndex % hashTable->tableSize;
// set temp node to the new index
}
printf("\n");
stateDataToString(stateString, currentNode);
printf("%s, %d -> %d\n", stateString, hashIndex, workingIndex);
// end index loop
// check for failed correct index
if(hashOffset == hashTable->tableSize)
{
// return false
return false; return false;
} }
// complete the data - set the temp value's inUse to true
currentNode.inUse = USED_NODE;
// assign to array (use setDataNodeFromStruct)
setDataNodeFromStruct(&hashTable->array[workingIndex], currentNode);
// return true
return true;
}
/* /*
Name: clearHashTable Name: clearHashTable
@ -128,8 +187,19 @@ Dependencies: findItemIndex, setEmptyDataNode
StateDataType findItem( const ProbingHashType *hashTable, StateDataType findItem( const ProbingHashType *hashTable,
StateDataType searchItem ) StateDataType searchItem )
{ {
// return NULL (temp) int indexFound;
return; StateDataType foundItem;
// set the return item to empty as default
setEmptyDataNode(&foundItem);
// use findItemIndex to search for the item
indexFound = findItemIndex(hashTable, searchItem);
if (indexFound != ITEM_NOT_FOUND)
{
// return the hashTable at index data.
return hashTable->array[indexFound];
}
// return foundItem with blank data
return foundItem;
} }
/* /*
@ -149,8 +219,60 @@ Dependencies: getHashIndex, printf, privateCompareStrings, privateToPower,
*/ */
int findItemIndex( const ProbingHashType *hashTable, StateDataType searchItem ) int findItemIndex( const ProbingHashType *hashTable, StateDataType searchItem )
{ {
// return zero (temp) // initialize function/variables
return 0; int findIterator;
// set hash index to getHashIndex
int hashIndex = getHashIndex(*hashTable, searchItem);
// declare added value, set to zero
int addedVal = 0;
// declare working index
int workingIndex = hashIndex;
// set the value into a temp
// test the value, set compare to int var
int strCompare = privateCompareStrings(hashTable->array[workingIndex].name,
searchItem.name);
// print indices probed, with hash index
printf("\nIndices Probed: %d", workingIndex);
// loop up to table size with added value AND value not found
// value not found => test for equality of name
for(findIterator = 0; findIterator < hashTable->tableSize && strCompare != 0;
findIterator++)
{
// increment the added value
addedVal = addedVal + 1;
// check for linear probing type
if(hashTable->probeStrategy == LINEAR_PROBING)
{
// get a working index from the hash index plus the added value
workingIndex = hashIndex + addedVal;
}
// otherwise, assume quadratic
else
{
// get a working index from the hash index
// plus the added value squared
workingIndex = hashIndex + privateToPower(addedVal, 2);
}
// process the working index to set it within array indices
workingIndex = workingIndex % hashTable->tableSize;
// print index probed, with comma delimiter
printf(", %d", workingIndex);
// set the value into a temp
// test the value, set compare to int var
strCompare = privateCompareStrings(hashTable->array[workingIndex].name,
searchItem.name);
}
// end of loop
// print an endline
printf("\n");
// check for item not found (added value is up at hash table size)
if(addedVal == hashTable->tableSize)
{
// return item not found
return ITEM_NOT_FOUND;
}
// return working index
return workingIndex;
} }
/* /*
@ -169,8 +291,33 @@ Dependencies: privateGetStringLength
*/ */
int getHashIndex( const ProbingHashType hashTable, const StateDataType state ) int getHashIndex( const ProbingHashType hashTable, const StateDataType state )
{ {
// return zero (temp) int hashIndex = 0, hashDiff = 0, hashIterator;
return 0; // check to see if the state name length is less than MIN HASH LETTER COUNT
// if it is, take a difference of the minimum letter count, then loop
if(privateGetStringLength(state.name) < MINIMUM_HASH_LETTER_COUNT)
{
// set the hash difference
hashDiff = MINIMUM_HASH_LETTER_COUNT - privateGetStringLength(state.name);
}
// otherwise, for loop through the name of the state
for(hashIterator = 0; hashIterator < privateGetStringLength(state.name);
hashIterator++)
{
// loop through the state's characters, add them up.
hashIndex = hashIndex + (int)state.name[hashIterator];
}
// if the state does not meet the minimum, then loop through the difference.
for(hashIterator = 0; hashIterator < hashDiff; hashIterator++)
{
// since the requirement wasn't met, and if the difference is greater than
// zero, then this loop will fill in the gap.
hashIndex = hashIndex + (int)state.name[hashIterator];
}
// since the hash index is now a number, must mod by table size in order to
// get an index value that is range fitted.
hashIndex = hashIndex % hashTable.tableSize;
// return hashIndex
return hashIndex;
} }
/* /*
@ -226,7 +373,21 @@ Dependencies: findItemIndex, setDataNodeFromStruct
bool removeState( StateDataType *removedState, bool removeState( StateDataType *removedState,
const StateDataType toBeRemoved, const ProbingHashType hashTable ) const StateDataType toBeRemoved, const ProbingHashType hashTable )
{ {
// return false (temp) int removeIndex;
// get the index of the item
removeIndex = findItemIndex(&hashTable, toBeRemoved);
// check to see if the item was not found
// if the item was found, then 'remove' it by setting to unused.
if(removeIndex != ITEM_NOT_FOUND)
{
// set the removed state to where the item is in array
setDataNodeFromStruct(removedState, hashTable.array[removeIndex]);
// set the state to unused in the array to let overwriting possible
hashTable.array[removeIndex].inUse = UNUSED_NODE;
// return true since operation success
return true;
}
// return false since item not found
return false; return false;
} }
@ -247,41 +408,44 @@ Dependencies: sprintf, printf
*/ */
void showHashTableStatus( const ProbingHashType hashTable) void showHashTableStatus( const ProbingHashType hashTable)
{ {
int itemCount = 0, statusIterator, contigCount, maxContig, minContig; int itemCount = 0, statusIterator, maxContig = 0, minContig = 0;
int unusedCount = 0;
// display the hash table status, then iterate through either used/unused // display the hash table status, then iterate through either used/unused
printf("\nHash Table Status: "); printf("\nHash Table Status: ");
for(statusIterator = 0; statusIterator < hashTable.tableSize; statusIterator++) for(statusIterator = 0; statusIterator < hashTable.tableSize;
statusIterator++)
{ {
contigCount = 1;
// check to see if inUse // check to see if inUse
if(hashTable.array[statusIterator].inUse) if(hashTable.array[statusIterator].inUse)
{ {
// print 'D' // print 'D'
printf("D"); printf("D");
// increment the item count actual
itemCount = itemCount + 1; itemCount = itemCount + 1;
contigCount = contigCount + 1; // increment the minimum number of contiguous elements
// check to see if the contigCount is bigger than old maxContig minContig = minContig + 1;
if (contigCount > maxContig) // check to see if the min exceeds max
if(minContig > maxContig)
{ {
maxContig = contigCount; // assign the max to min since it exceeded
maxContig = minContig;
} }
} }
else else
{ {
// check to see if the contigCount is less than old minContig // reset the minimum value to zero.
if(contigCount < minContig) minContig = 0;
{
minContig = contigCount;
}
contigCount = 1;
// print 'U' // print 'U'
printf("U"); printf("U");
// keep count of the actual unused values.
unusedCount = unusedCount + 1;
} }
} }
// print out the table of important values.
printf("\nD => Data, U => Unused\n\n"); printf("\nD => Data, U => Unused\n\n");
printf(" Items in Hash Table: %d\n", itemCount); printf(" Items in Hash Table: %d\n", itemCount);
printf(" Minimum contiguous bins: %d\n", itemCount); printf(" Minimum contiguous bins: %d\n", minContig);
printf(" Maximum contiguous bins: %d\n", itemCount); printf(" Maximum contiguous bins: %d\n", maxContig);
printf(" Number of empty bins: %d\n", itemCount); printf(" Number of empty bins: %d\n", unusedCount);
// no return, void. // no return, void.
} }