CS249-Projects/PA03-0920/StateUtilities_LogN.c
cdez 82bf795c15 Refined all the Functions and stuff
+- PA03_Main
+- StateUtilities_LogN.c
2023-09-19 22:19:01 -07:00

612 lines
22 KiB
C

#include "StateUtilities_LogN.h"
// local constants
const int NAME_BLOCK_SIZE = 16;
const int POPULATION_BLOCK_SIZE = 12;
const int GROWTH_BLOCK_SIZE = 10;
// missing constants from assignment file
const int ITEM_BLOCK_SIZE = 6;
const int MAJORITY_BLOCK_SIZE = 10;
const char EQUALS = '=';
const char PLUS = '+';
const int TITLE_LENGTH = 34;
// all functions
/*
Name: addElementFromData
Process: adds all individual data values to StateDataType array,
must check for resize before adding new element
Function input/parameters: pointer to data array type (StateArrayType *),
state name (const char *),
state population (int),
state growth (double),
state political majority (char)
Function output/parameters: updated data array (StateArrayType *)
Function output/returned: none
Device input/---: none
Device output/---: none
Dependencies: as needed, including strcpy
*/
void addElementFromData( StateArrayType *stateArr,
const char *stateName, int statePop,
double stateGrowth, char politicalMajority )
{
// check to see if the size will go over the capacity
checkForResize(stateArr);
// put in the data to the array
// stateArr->array[stateArr.size] = parameter
stateArr->array[stateArr->size].population = statePop;
stateArr->array[stateArr->size].growth = stateGrowth;
stateArr->array[stateArr->size].majority = politicalMajority;
// use strcpy(stateArr->array[stateArr.size].name, stateName)
strcpy(stateArr->array[stateArr->size].name, stateName);
// increment size (stateArr.size = stateArr.size + 1)
stateArr->size = stateArr->size + 1;
// no return, void
}
/*
Name: addElementFromElement
Process: adds data from element to StateDataType array,
uses supporting function
Function input/parameters: data array type (StateArrayType *)
source element (const StateDataType)
Function output/parameters: updated data array (StateArrayType *)
Function output/returned: none
Device input/---: none
Device output/---: none
Dependencies: addElementFromData - function uses one code statement
*/
void addElementFromElement( StateArrayType *stateArr,
const StateDataType state )
{
addElementFromData(stateArr, state.name, state.population,
state.growth, state.majority);
// no return, void
}
/*
Name: checkForResize
Process: checks if array needs to be resized,
resizes (increases capacity of) array to double capacity
and moves data from previous array into new one
Function input/parameters: pointer to state array type (StateArrayType *)
Function output/parameters: updated pointer
to state array type (StateArrayType *)
if resize has taken place,
otherwise ADT is unchanged
Function output/returned: none
Device input/---: none
Device output/---: none
Dependencies: as needed, including malloc, free, keyword sizeof
*/
void checkForResize( StateArrayType *stateArray )
{
StateDataType *biggerStateArray;
int resizeIterator;
// do a similiar check to the one that was done in PA02 for size < capacity
if(stateArray->size == stateArray->capacity)
{
// 'create' bigger array
stateArray->capacity = stateArray->capacity * 2;
// allocate the bigger array
biggerStateArray = (StateDataType *)malloc(sizeof(StateDataType) * stateArray->capacity);
// copy the new array stuff into the old space, use loop
for(resizeIterator = 0; resizeIterator < stateArray->size; resizeIterator++)
{
// use deep copy to copy the pieces of smaller array
deepCopy(&biggerStateArray[resizeIterator], stateArray->array[resizeIterator]);
}
// free the old array
free(stateArray->array);
// point the stateArray to the old array
stateArray->array = biggerStateArray;
}
// no return, void
}
/*
Name: clearStateArrayType
Process: deallocates dynamically allocated array from memory,
deallocates dynamically allocated state data type,
returns NULL
Function input/parameters: data array (StateDataType *)
Function output/parameters: none
Function output/returned: NULL
Device input/---: none
Device output/---: none
Dependencies: as needed, including free
*/
StateArrayType *clearStateArrayType( StateArrayType *stateArray )
{
// free the array from memory
free(stateArray->array);
// free the struct from memory
free(stateArray);
// return NULL once complete
return NULL;
}
/*
Name: copyArrayType
Process: copies state data array type from one array type to another
Function input/parameters: source array (const StateArrayType)
Function output/parameters: pointer to destination array (StateDataType *)
Function output/returned: none
Device input/---: none
Device output/---: none
Dependencies: as needed
*/
void copyArrayType( StateArrayType *dest, const StateArrayType src )
{
int currentSize;
// use a for loop to iterate through source array
// (start at zero, go to srcSize)
dest->size = src.size;
dest->capacity = src.capacity;
for(currentSize = 0; currentSize < src.size; currentSize++)
{
// copy each element from the array to the new array.
// uses deepCopy to do this.
deepCopy(&dest->array[currentSize], src.array[currentSize]);
}
// no return, void
}
/*
Name: createStateArrayType
Process: dynamically allocates memory for array type,
dynamically allocates memory for array,
initializes size and capacity
Function input/parameters: initial capacity (int)
Function output/parameters: none
Function output/returned: pointer to newly created array type (StateArrayType *)
Device input/---: none
Device output/---: none
Dependencies: as needed, including function malloc and keyword sizeof
*/
StateArrayType *createStateArrayType( int initialCapacity )
{
StateArrayType *stateArrayCreation;
// initialize array type
stateArrayCreation = malloc(sizeof(StateArrayType));
stateArrayCreation->size = 0;
stateArrayCreation->capacity = initialCapacity;
// initialize array
stateArrayCreation->array = malloc(sizeof(StateDataType) * initialCapacity);
// return stateArrayCreation
return stateArrayCreation;
}
/*
Name: deepCopy
Process: copies all individual values from StateDataType source
to StateDataType destination
Function input/parameters: source element (const StateDataType)
Function output/parameters: pointer to destination value (StateDataType *)
Function output/returned: none
Device input/---: none
Device output/---: none
Dependencies: as needed, including strcpy
*/
void deepCopy( StateDataType *dest, const StateDataType src )
{
// *dest.population = src.population (for each piece)
dest->population = src.population;
dest->growth = src.growth;
dest->majority = src.majority;
// strcpy for the string
// strcpy(*dest.name, src.name)
strcpy(dest->name, src.name);
// no return, void
}
/*
Name: displayData
Process: displays element data in array type as table
if array is not empty,
otherwise displays "Data not found - Display aborted",
allows for subtitle to be added to "Display Data - "
Function input/parameters: state data array type (const StateArrayType *),
subtitle (const char *)
Function output/parameters: none
Function output/returned: none
Device input/---: none
Device output/monitor: data displayed as specified
Dependencies: as needed
*/
void displayData( const StateArrayType arrayType, const char *subTitle )
{
int countStates;
// iterate through array to size, check if zero.
if(arrayType.size != 0)
{
printEndline();
printString("Display Data - ");
printString(subTitle);
printEndline();
printEndline();
// create a table
// print PIPE character
printCharacter(PIPE);
// print ITEM justified center
printStringJustified("Item", ITEM_BLOCK_SIZE, "CENTER");
// print PIPE character
printCharacter(PIPE);
// print STATE NAME justified center
printStringJustified("State Name", NAME_BLOCK_SIZE, "CENTER");
// print PIPE character
printCharacter(PIPE);
// print POPULATION justified center
printStringJustified("Population", POPULATION_BLOCK_SIZE, "CENTER");
// print PIPE character
printCharacter(PIPE);
// print GROWTH justified center
printStringJustified("Growth", GROWTH_BLOCK_SIZE, "CENTER");
// print PIPE character
printCharacter(PIPE);
// print MAJORITY justified center
printStringJustified("Majority", MAJORITY_BLOCK_SIZE, "CENTER");
// print PIPE character
printCharacter(PIPE);
// print new line
printEndline();
// printing the top border piece
// print PIPE character
printCharacter(PIPE);
// print amount of = for ITEM
printCharacters(ITEM_BLOCK_SIZE, EQUALS);
// print PLUS (needs constant) character
printCharacter(PLUS);
// print amount of = for STATE NAME
printCharacters(NAME_BLOCK_SIZE, EQUALS);
// print PLUS character
printCharacter(PLUS);
// print amount of = for POPULATION
printCharacters(POPULATION_BLOCK_SIZE, EQUALS);
// print PLUS character
printCharacter(PLUS);
// print amount of = for GROWTH
printCharacters(GROWTH_BLOCK_SIZE, EQUALS);
// print PLUS character
printCharacter(PLUS);
// print amount of = for MAJORITY
printCharacters(MAJORITY_BLOCK_SIZE, EQUALS);
// print PIPE character
printCharacter(PIPE);
// print new line
printEndline();
for(countStates = 0; countStates < arrayType.size; countStates++)
{
// use the constants to format the table
// print PIPE character
printCharacter(PIPE);
// print item justified right (size)
printIntegerJustified(countStates + 1, ITEM_BLOCK_SIZE, "RIGHT");
// print PIPE character
printCharacter(PIPE);
// print state name justified left
printStringJustified(arrayType.array[countStates].name,
NAME_BLOCK_SIZE, "LEFT");
// print PIPE character
printCharacter(PIPE);
// print population justified right
printIntegerJustified(arrayType.array[countStates].population,
POPULATION_BLOCK_SIZE, "RIGHT");
// print PIPE character
printCharacter(PIPE);
// print growth justified right, need a % sign too.
//(requires some math trickery to make work)
printDoubleJustified(arrayType.array[countStates].growth * 100.00,
PRECISION_2, GROWTH_BLOCK_SIZE - 2, "RIGHT");
printCharacter('%');
printCharacter(SPACE);
// print PIPE character
printCharacter(PIPE);
// print majority justified center,
// also requires some math trickery to make work
printCharacters((MAJORITY_BLOCK_SIZE - 1) / 2, SPACE);
printCharacter(SPACE);
printCharacter(arrayType.array[countStates].majority);
printCharacters((MAJORITY_BLOCK_SIZE - 1) / 2, SPACE);
// print PIPE character
printCharacter(PIPE);
// print endline
printEndline();
// printing for the spacer lines
// print PIPE character
printCharacter(PIPE);
// print amount of DASH for item
printCharacters(ITEM_BLOCK_SIZE, DASH);
// print PLUS character
printCharacter(PLUS);
// print amount of DASH for state name
printCharacters(NAME_BLOCK_SIZE, DASH);
// print PLUS character
printCharacter(PLUS);
// print amount of DASH for population
printCharacters(POPULATION_BLOCK_SIZE, DASH);
// print PLUS character
printCharacter(PLUS);
// print amount of DASH for growth
printCharacters(GROWTH_BLOCK_SIZE, DASH);
// print PLUS character
printCharacter(PLUS);
// print amount of DASH for majority
printCharacters(MAJORITY_BLOCK_SIZE, DASH);
// print PIPE character
printCharacter(PIPE);
// print endline
printEndline();
}
}
else
{
//print out "Data not found - Display aborted".
printString("Data not found - Display aborted");
printEndline();
}
// no return, void
}
/*
Name: reverseArray
Process: reverses values in array
Function input/parameters: pointer to state array type (StateArrayType *)
Function output/parameters: none
Function output/returned: none
Device input/---: none
Device output/---: none
Dependencies: as needed
*/
void reverseArray( StateArrayType *stateArray )
{
// reverse in place? could use swap elements to make this happen.
// use a for loop?
// no return, void
}
/*
Name: runMerge
Process: merges StateArrayType ADT subsets brought in between a low, middle,
and high index segment of the StateArrayType ADT,
must dynamically create (and release) one internal array
must use three array transfer loops
Function input/parameters: pointer to state array type (StateArrayType *),
low index, middle index, high index (int)
Function output/parameters: pointer to updated state array type
(StateArrayType *)
Function output/returned: none
Device input/---: none
Device output/---: none
Dependencies: as needed
*/
void runMerge( StateArrayType *stateArray,
int lowIndex, int middleIndex, int highIndex )
{
// no return, void
}
/*
Name: runMergeSortByName
Process: sorts StateArrayType ADT using merge sort algorithm,
calls helper function with appropriate indices
Function input/parameters: pointer to state array type (StateArrayType *)
Function output/parameters: pointer to updated state array type
(StateArrayType *)
Function output/returned: none
Device input/---: none
Device output/---: none
Dependencies: as needed
*/
void runMergeSortByName( StateArrayType *stateArray )
{
// no return, void
}
/*
Name: runMergeSortHelper
Process: recursively breaks given StateArrayType ADT segments down
to smaller segments between lowIndex and highIndex (inclusive),
then sorts data using merge operation for segments created
Function input/parameters: pointer to state array type (StateArrayType *),
low & high inclusive indices (int)
Function output/parameters: pointer to updated state array type
(StateArrayType *)
Function output/returned: none
Device input/---: none
Device output/---: none
Dependencies: as needed
*/
void runMergeSortHelper( StateArrayType *stateArray,
int lowIndex, int highIndex )
{
// no return, void
}
/*
Name: runPartition
Process: partitions StateArrayType ADT
must use the first value as the partition value;
when this function is complete the partition value is
in the correct location in the array;
main loop must iterate from left to right
Function input/parameters: pointer to state array type (StateArrayType *)
Function output/parameters: pointer to updated state array type
(StateArrayType *)
Function output/returned: partition value index within array
Device input/---: none
Device output/---: none
Dependencies: as needed
*/
int runPartition( StateArrayType *stateArray, int lowIndex, int highIndex )
{
// return zero (temporarily)
return 0;
}
/*
Name: runQuickSortByPopulation
Process: sorts StateArrayType ADT using quick sort algorithm,
calls helper with appropriate indices to implement sort
Function input/parameters: pointer to state array type (StateArrayType *)
Function output/parameters: pointer to updated state array type
(StateArrayType *)
Function output/returned: none
Device input/---: none
Device output/---: none
Dependencies: as needed
*/
void runQuickSortByPopulation( StateArrayType *stateArray )
{
// no return, void
}
/*
Name: runQuickSortHelper
Process: helper function run with parameters that partition arrays
on a given (first) element of an array segment,
then recursively sort left and right sides of given partition value
Function input/parameters: pointer to state array type (StateArrayType *)
low & high inclusive indices (int)
Function output/parameters: pointer to updated state array type
(StateArrayType *)
Function output/returned: none
Device input/---: none
Device output/---: none
Dependencies: as needed
*/
void runQuickSortHelper( StateArrayType *stateArray,
int lowIndex, int highIndex )
{
// no return, void
}
/*
Name: setEmptyElementData
Process: sets state data type to empty or default values,
name to empty string, population and growth to zero,
and majority to 'x'
Function input/parameters: none
Function output/parameters: state data value (StateDataType *)
Function output/returned: none
Device input/---: none
Device output/---: none
Dependencies: none
*/
void setEmptyElementData( StateDataType *element )
{
// set the element's name to ""
element->name[0] = NULL_CHAR;
// set the element's population and growth to 0
element->population = 0;
element->growth = 0.0;
// set the element's majority to 'x'
element->majority = 'x';
// no return, void
}
/*
Name: showTitle
Process: displays program title with thick underline,
"Data Management with Log N Sorting"
Function input/parameters: none
Function output/parameters: none
Function output/returned: none
Device input/---: none
Device output/monitor: displays title as specified
Dependencies: as needed
*/
void showTitle()
{
// use console io utilities to display the string
printString("Data Management with Log N Sorting");
// print endline
printEndline();
// use console io utilities to display 34 '='
printCharacters(TITLE_LENGTH, EQUALS);
// print an endline
printEndline();
// no return, void
}
/*
Name: swapElements
Process: swaps state data elements within an array
Function input/parameters: given array (StateDataType *),
left and right indices to be swapped (int)
Function output/parameters: updated array with swapped values (StateDataType *)
Function output/returned: none
Device input/---: none
Device output/---: none
Dependencies: as needed
*/
void swapElements( StateDataType *array, int leftIndex, int rightIndex )
{
// create StateDataType temp to store swapped element
StateDataType storeElement;
// use deepCopy to copy out swapped element
deepCopy(&storeElement, array[leftIndex]);
// use deepCopy to move the other element,
deepCopy(&array[leftIndex], array[rightIndex]);
// use deepCopy to copy the temp element to the other element
deepCopy(&array[rightIndex], storeElement);
// updated the array
// no return, void
}
/*
Name: uploadStateData
Process: uploads data from given file to state data array,
ignores first (title) line in .csv file,
then captures comma-delimited state name, population, growth,
and political majority data on each row,
returns true if upload successful, false otherwise
Function input/parameters: file name (const char *)
Function output/parameters: updated array with uploaded values (StateDataType *)
Function output/returned: Boolean result of upload operation
Device input/HD: data uploaded from text file as specified
Device output/---: none
Dependencies: as needed
*/
bool uploadStateData( StateArrayType *arrayType, const char *fileName )
{
// setup a temporary state and other variables
StateDataType stateUpload;
char currentString[STD_STR_LEN];
// int populationUpload;
// double growthUpload;
// char majorityUpload;
// open file
//setEmptyElementData(&stateUpload);
if(openInputFile(fileName))
{
// read in the four strings/starting line
// (use readStringToLineEndFromFile)
readStringToLineEndFromFile(currentString);
readStringToDelimiterFromFile(COMMA, stateUpload.name);
while(!checkForEndOfInputFile())
{
// repeat these steps: (use readStringToDelimiterFromFile)
// read in the state name, store
// read in the population, store (cast from string to int)
stateUpload.population = readIntegerFromFile();
readCharacterFromFile();
// read in the growth, store (cast from string to double)
stateUpload.growth = readDoubleFromFile();
// read in the majority, store
readCharacterFromFile();
stateUpload.majority = readCharacterFromFile();
// use the addElementFromElement function to add the data to array
addElementFromElement(arrayType, stateUpload);
// do until end of the file is reached.
readStringToDelimiterFromFile(COMMA, stateUpload.name);
}
// return true when completely finished, close file before completion
closeInputFile();
return true;
}
// return false
return false;
}