COMPLETED PA10 and CS249!
+- HashUtility.c
This commit is contained in:
parent
6911280eb5
commit
a62aa61957
1 changed files with 191 additions and 27 deletions
|
|
@ -4,6 +4,10 @@
|
|||
#include "StateDataUtility.h"
|
||||
|
||||
// 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
|
||||
typedef struct HashStruct
|
||||
|
|
@ -34,8 +38,13 @@ Dependencies: setDataNodeFromData, addItemFromStruct
|
|||
bool addItemFromData( ProbingHashType *hashTable, const char *stateName,
|
||||
double avgTemp, double lowTemp, double highTemp )
|
||||
{
|
||||
// return false (temp)
|
||||
return false;
|
||||
StateDataType createState;
|
||||
// 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,8 +64,58 @@ Dependencies: getHashIndex, privateToPower, printf, stateDataToString,
|
|||
*/
|
||||
bool addItemFromStruct( ProbingHashType *hashTable, StateDataType newItem )
|
||||
{
|
||||
// return false (temp)
|
||||
return false;
|
||||
// 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(¤tNode, 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;
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -128,8 +187,19 @@ Dependencies: findItemIndex, setEmptyDataNode
|
|||
StateDataType findItem( const ProbingHashType *hashTable,
|
||||
StateDataType searchItem )
|
||||
{
|
||||
// return NULL (temp)
|
||||
return;
|
||||
int indexFound;
|
||||
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 )
|
||||
{
|
||||
// return zero (temp)
|
||||
return 0;
|
||||
// initialize function/variables
|
||||
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 )
|
||||
{
|
||||
// return zero (temp)
|
||||
return 0;
|
||||
int hashIndex = 0, hashDiff = 0, hashIterator;
|
||||
// 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,
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -247,41 +408,44 @@ Dependencies: sprintf, printf
|
|||
*/
|
||||
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
|
||||
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
|
||||
if(hashTable.array[statusIterator].inUse)
|
||||
{
|
||||
// print 'D'
|
||||
printf("D");
|
||||
// increment the item count actual
|
||||
itemCount = itemCount + 1;
|
||||
contigCount = contigCount + 1;
|
||||
// check to see if the contigCount is bigger than old maxContig
|
||||
if (contigCount > maxContig)
|
||||
// increment the minimum number of contiguous elements
|
||||
minContig = minContig + 1;
|
||||
// check to see if the min exceeds max
|
||||
if(minContig > maxContig)
|
||||
{
|
||||
maxContig = contigCount;
|
||||
// assign the max to min since it exceeded
|
||||
maxContig = minContig;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// check to see if the contigCount is less than old minContig
|
||||
if(contigCount < minContig)
|
||||
{
|
||||
minContig = contigCount;
|
||||
}
|
||||
contigCount = 1;
|
||||
// reset the minimum value to zero.
|
||||
minContig = 0;
|
||||
// print '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(" Items in Hash Table: %d\n", itemCount);
|
||||
printf(" Minimum contiguous bins: %d\n", itemCount);
|
||||
printf(" Maximum contiguous bins: %d\n", itemCount);
|
||||
printf(" Number of empty bins: %d\n", itemCount);
|
||||
printf(" Minimum contiguous bins: %d\n", minContig);
|
||||
printf(" Maximum contiguous bins: %d\n", maxContig);
|
||||
printf(" Number of empty bins: %d\n", unusedCount);
|
||||
// no return, void.
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue