Automated Grading Log for CS113 -- HW9 userid: mye Name: Ye, Manny Log created: Fri Dec 13 14:15:38 EST 1996 SUBMISSIONS =========== mye Submitted hw9-types.h at Wed Dec 11 18:40:51 1996 mye Submitted hw9-types.c at Wed Dec 11 18:41:06 1996 mye Submitted hw9-table.c at Wed Dec 11 18:41:33 1996 mye Submitted hw9-main.c at Wed Dec 11 18:41:20 1996 COMPILATION =========== gccx -g -I/home/course/cs113/F96/include -Wall -I. -c hw9-table.c gccx -g -I/home/course/cs113/F96/include -Wall -I. -c hw9-main.c gccx -g -I/home/course/cs113/F96/include -Wall -I. -c hw9-types.c gccx -g -I/home/course/cs113/F96/include -Wall -o words hw9-table.o hw9-main.o hw9-types.o gccx -g -I/home/course/cs113/F96/include -Wall -I../source -I- -c ../source/hw9-types.c gccx -g -I/home/course/cs113/F96/include -Wall -I../source -I- -c ./hw9-table.c gccx -g -I/home/course/cs113/F96/include -Wall -I../source -I- -c ../source/hw9-test.c gccx -g -I/home/course/cs113/F96/include -Wall -o hw9-test hw9-test.o hw9-table.o hw9-types.o EXECUTION TESTS ========= ===== ============================================================ words -f /home/course/cs113/GradesF96/HW9/inputs/text 3 a 3 hw 2 is 3 of 1 passed 4 test 1 the 1 was Done: words -f /home/course/cs113/GradesF96/HW9/inputs/text ============================================================ words -k 2 -f /home/course/cs113/GradesF96/HW9/inputs/text Error in Arguments: Bad Command Usage: words [-m #] [-l #] [-c #] -f file-name Done: words -k 2 -f /home/course/cs113/GradesF96/HW9/inputs/text ============================================================ words -m 2 -f /home/course/cs113/GradesF96/HW9/inputs/text 3 a 3 hw 3 of 4 test Done: words -m 2 -f /home/course/cs113/GradesF96/HW9/inputs/text ============================================================ words -c 1 -f /home/course/cs113/GradesF96/HW9/inputs/text 4 test Done: words -c 1 -f /home/course/cs113/GradesF96/HW9/inputs/text ============================================================ words -c 3 -f /home/course/cs113/GradesF96/HW9/inputs/text 4 test 3 a 3 hw Done: words -c 3 -f /home/course/cs113/GradesF96/HW9/inputs/text ============================================================ words -l 2 -f /home/course/cs113/GradesF96/HW9/inputs/text 1 passed 1 the 1 was Done: words -l 2 -f /home/course/cs113/GradesF96/HW9/inputs/text ============================================================ hw9-test Inserted (A, 0). Table now has 1 elements Inserted (B, 1). Table now has 2 elements Inserted (E, 1). Table now has 3 elements Could not insert (E, 6). (E, 1) already in table. Updating instead. Could not insert (B, 1). (B, 1) already in table. Updating instead. Could not insert (A, 6). (A, 0) already in table. Updating instead. Could not insert (B, 6). (B, 1) already in table. Updating instead. Could not insert (E, 0). (E, 6) already in table. Updating instead. Here is the table: (A, 6) (B, 6) (E, 0) Largest data value: A has value 6. Removing item with key A from table. Removing item with key B from table. Could not remove item with key C from table. Here is the table: (E, 0) Largest data value: E has value 0. Done: hw9-test SOURCE FILES ====== ===== /* * File: hw9-types.h * Author: Manny Ye * Class: CS 113, Fall 96 * Assignment: HW9-Tables Using Binary Search Trees * Due Date: 11 December 1996 * Last modified: 11 December 1996 * ----------------------------------------------------- * * OVERVIEW: * ========= * This file exists solely to isolate the * definition of tableKeyT and tableDataT from * the rest of the table.h interface. This way the * client can control the type of elements * placed in the table without editing table.h. */ #ifndef _HW9types_h #define _HW9types_h #include "genlib.h" typedef int tableDataT; typedef string tableKeyT; #endif /*------------------< end of file hw9-types.h >----------------*/ /* * File: hw9-types.c * Author: Manny Ye * Class: CS 113, Fall 96 * Assignment: HW9-Tables Using Binary Search Trees * Due Date: 11 December 1996 * Last modified: 11 December 1996 * ----------------------------------------------------- * * OVERVIEW: * ========= * The implementation of the comparison for tableKeyT. * */ #include "hw9-types.h" #include "hw9-table.h" #include "strlib.h" int KeyCompare(tableKeyT key1, tableKeyT key2) { return(StringCompare(key1, key2)); } /* end of function KeyCompare */ /* -----------------< end of file hw9-types.c >----------------- */ /* * File: hw9-table.c * Author: Manny Ye * Class: CS 113, Fall 96 * Assignment: HW9--Tables Using Binary Trees * Due Date: 11 December 1996 * Last modified: 11 December 1996 * ----------------------------------------------------- * * OVERVIEW: * ========= * This is an implementation of table.h using a binary search tree. * * Elements of the table have a key, by with they are stored and retrieved, * and some additional data. Access to the table is only allowed via keys. * Duplicate keys are not permitted. * * Known Bugs: none. * ================= * * Error Handling none: * =================== */ #include "hw9-table.h" #include "hw9-types.h" /* * Types: tableCDT, BST, nodeT * --------------------------- * tableCDT is a struct consisting of * - count: an integer which maintains the number of things in the table * - tree: the binary search tree which stores the data of the table * * BST (Binary Search Tree type) is a pointer to a nodeT which is the root * of the tree. * * nodeT is a struct consisting of * - lChild: (pointer to top node of) the left subtree * - rChild: (pointer to top node of) the right subtree * - elem: the data located at this node * * picture: * * * -------------- * | count | tree | * -------------- * \ * \ * ------------------------ * | lChild | elem | rChild | * ------------------------ * / \ * / \ * ------------------------ ------------------------ * | lChild | elem | rChild | | lChild | elem | rChild | * ------------------------ ------------------------ * / \ / \ * * etc. etc. etc. etc. etc. etc. * */ typedef struct nodeT{ struct nodeT *lChild; tableElementT elem; struct nodeT *rChild; } nodeT; typedef nodeT *BST; typedef struct tableCDT{ int count; BST tree; /* equiv to nodeT *tree */ } tableCDT; /* * Prototypes of (static) local functions. These functions operate on * the underlying binary search tree rather than on the tableCDT and * are the heart of corresponding Table... functions, which are merely * wrappers. */ static bool BSTRetrieve(BST tree, tableKeyT key, tableDataT *dataPtr); static bool BSTInsert(BST *treePtr, tableKeyT key, tableDataT data); static tableElementT BSTTraverse(BST tree, VisitFuncT VisitPtr, tableElementT initElem); static void BSTFree(BST tree); static bool BSTUpdate(BST tree, tableKeyT key, tableDataT newData); static bool BSTRemove(BST *tree, tableKeyT key); static void RemoveNode(BST *treePtr); /* * Function: NewTable * Usage: table = NewTable(); * ------------------------- * A new empty table is allocated, created and returned. */ tableADT NewTable(void) { tableCDT *newTablePtr; newTablePtr = GetBlock(sizeof (tableCDT)); newTablePtr->count = 0; newTablePtr->tree = NULL; return newTablePtr; } /* Function: FreeTable, BSTFree * ---------------------------- * This function frees all memory associated with the table. Table * may not be used again unless NewTable(table) is called first. * * Function FreeTable frees the memory of tableADT, but * BSTFree is really the essential part. BSTFree frees the whole * tree (all nodes of the tree). */ void FreeTable(tableADT table) { BSTFree(table->tree); free(table); } /* end of function FreeTable */ static void BSTFree(BST tree) { if (tree != NULL) { BSTFree(tree->lChild); BSTFree(tree->rChild); free(tree); } /* end of if */ } /* end of function BSTFree */ /* * Functions: TableRetrieve, BSTRetrieve * Usage: success = TableRetrieve(table, key, &data); * success = BSTRetrieve(tree, key, &data); * ------------------------------------------------------- * Table Retrieve serves as a wrapper for BSTRetrieve, which is a recursive * functions which operates just on the tree part of the tableCDT. * */ bool TableRetrieve(tableADT table, tableKeyT key, tableDataT *dataPtr) { return BSTRetrieve(table->tree, key, dataPtr); } static bool BSTRetrieve(BST tree, tableKeyT key, tableDataT *dataPtr) { /* four cases: * base cases: * tree is empty: means key not in tree. * found the key * recursive cases * key, if present, is in left subtree * key, if present, is in right subtree */ if (tree == NULL) { /* case 1: empty tree means key not in the tree */ return FALSE; } else if (KeyCompare(key, tree->elem.key) == 0) { /* case 2: found the key */ *dataPtr = tree->elem.data; return TRUE; } else if (KeyCompare(key, tree->elem.key) < 0) { /* case 3: key to left */ return (BSTRetrieve(tree->lChild, key, dataPtr)); } else { /* recursive case 4: key to right */ return (BSTRetrieve(tree->rChild, key, dataPtr)); } /* end of cascading ifs */ } /* * Functions: TableUpdate, BSTUpdate * ---------------------------------- * TableUpdate replaces the data in the table associated with key * with newData. */ bool TableUpdate(tableADT table, tableKeyT key, tableDataT newData) { return(BSTUpdate(table->tree, key, newData)); } /* end of function TableUpdate */ static bool BSTUpdate(BST tree, tableKeyT key, tableDataT newData) { if (tree == NULL) { /* case 1: empty tree means key not in the tree */ return FALSE; } else if (KeyCompare(key, tree->elem.key) == 0) { /* case 2: found the key */ tree->elem.data = newData; return TRUE; } else if (KeyCompare(key, tree->elem.key) < 0) { /* case 3: key to left */ return (BSTUpdate(tree->lChild, key, newData)); } else { /* recursive case 4: key to right */ return (BSTUpdate(tree->rChild, key, newData)); } /* end of cascading ifs */ } /* end of function BSTUpdate */ /* * Functions: TableInsert, BSTInsert; * -------------------------------------- */ bool TableInsert(tableADT table, tableKeyT key, tableDataT data) { bool success; success = BSTInsert(&(table->tree), key, data); if (success) { /* just added one element to table so increment counter */ table->count++; } return (success); } static bool BSTInsert(BST *treePtr, tableKeyT key, tableDataT data){ /* * this just makes things a bit easier to read */ BST tree; tree = *treePtr; if (tree == NULL) { /* * *treePtr is the NULL child of some leaf. * this is where we add our new node. */ tableElementT newElem; /* newElement to be built */ /* put newElem together */ newElem.key = key; newElem.data = data; /* allocate space and change *treePtr */ tree = GetBlock(sizeof(nodeT)); /* * make sure change is permanent. without this, only our local scope will * have access to the newly allocated node. */ *treePtr = tree; /* tree was NULL, now it is not. */ tree->elem = newElem; tree->lChild = tree->rChild = NULL; return TRUE; /* successful insert */ /* note: tree not empty (we returned above in case of empty table.) */ } else if ( KeyCompare(key, tree->elem.key) == 0 ) { /* there already is a node with that key! */ return FALSE; } else if ( KeyCompare(key, tree->elem.key) < 0 ) { /* need to insert into left sub-tree */ return BSTInsert(&(tree->lChild), key, data); } else { /* need to insert into right sub-tree */ return BSTInsert(&(tree->rChild), key, data); } } /* * Functions: TableRemove, BSTRemove, RemoveNode * --------------------------------------------- * removes an element from the table. */ bool TableRemove(tableADT table, tableKeyT key) { bool success; success = BSTRemove(&(table->tree), key); if (success) { /* just added one element to table so increment counter */ table->count--; } return (success); } /* end of TableRemove */ static bool BSTRemove(BST *treePtr, tableKeyT key) { BST tree; tree = *treePtr; if (tree == NULL) { /* case 1: empty tree means key not in the tree */ return FALSE; } else if (KeyCompare(key, tree->elem.key) == 0) { /* case 2: found the key, remove node */ RemoveNode(treePtr); return TRUE; } else if (KeyCompare(key, tree->elem.key) < 0) { /* case 3: key to left */ return (BSTRemove(&(tree->lChild), key)); } else { /* recursive case 4: key to right */ return (BSTRemove(&(tree->rChild), key)); } /* end of cascading ifs */ } /* end of function BSTRemove */ static void RemoveNode(BST *treePtr) { /* * this just makes things a bit easier to read */ BST tree; tree = *treePtr; /* There is 3 cases for removing a node * case 1: node is a leaf/no children * case 2: node has only one children * case 3: node has two children */ if (tree->lChild == NULL && tree->rChild == NULL) { /* case 1: node is a leaf-remove null */ BST temp; temp = tree; tree = NULL; *treePtr = tree; free(temp); return; } else if ((tree->lChild == NULL && tree->rChild != NULL) || (tree->lChild != NULL && tree->rChild == NULL)) { /* case 2: node has one child */ BST temp; temp = tree; if (tree->lChild != NULL) { tree = tree->lChild; } else { tree = tree->rChild;} *treePtr = tree; free(temp); return; } else { /* case 3: node has two child * There is 2 sub-cases in this case * sub-case 1: the replacement node is a leaf. * replacement node will be deleted. * sub-case 2: the replacement node has a right child. * Parent of replacement node must point to the * right child of the replacement node, and then * delete replacement node. */ bool hasLeftChild; /* check if the parent has left child */ BST temp, parent; parent = tree; temp = tree->rChild; if (temp->lChild == NULL) { /* check for hasLeftChild */ hasLeftChild = FALSE; } else { hasLeftChild = TRUE; } while(temp->lChild != NULL) /* find the replacement node */ { /* and its parents */ parent = temp; temp = temp->lChild; } if (temp->rChild == NULL) { /* sub-case 1: replacement node is a leaf */ if (hasLeftChild) { /* disconnect the replacement */ parent->lChild = NULL; /* from the tree */ } else { parent->rChild = NULL; } /* end of if else */ tree->elem = temp->elem; /* change content of removing node*/ free(temp); /* free memory of replacement node */ return; } else { /* sub-case 2: replacement node has a right child */ if (hasLeftChild) { /* disconnect the */ parent->lChild = temp->rChild; /* replacement node */ } else { /* from the tree */ parent->rChild = temp->rChild; } /* end of if else */ tree->elem = temp->elem; /* change content of removing node*/ free(temp); /* free memory of replacement node */ return; } /* end of if else */ } /* end of cascading if */ } /* end of function RemoveNode */ /* * Functions: TableTraverse, BSTTraverse * --------------------------------------------- * TableTraverse traverses the entire table by calling BSTTraverse * on the BST part of the tableCDT. BSTTraverse is just an in-order * traverse of the binary tree. (*VisitPtr) is executed at each node * of the tree. */ tableElementT TableTraverse(tableADT table, VisitFuncT VisitPtr, tableElementT initElem) { return BSTTraverse(table->tree, VisitPtr, initElem); } static tableElementT BSTTraverse(BST tree, VisitFuncT VisitPtr, tableElementT initElem) { tableElementT passElem; /* element to pass to next call of Visit */ if (tree == NULL) { /* empty tree so just pass on initElem, no calls to Visit */ passElem = initElem; } else { /* non-empty tree, so do left-subtree, element, right sub-tree, * update passElement as we go */ passElem = BSTTraverse(tree->lChild, VisitPtr, initElem); passElem = (*VisitPtr)(tree->elem, passElem); passElem = BSTTraverse(tree->rChild, VisitPtr, passElem); } /* after traverse entire tree (left, here, right) return value to caller */ return passElem; } /* * Function: TableIsFull * ----------------------------------- * return TRUE if the table is full==if can not allocate another * node for the tree */ bool TableIsFull(tableADT table) { BST temp; /* allocating a piece of memory a bit bigger than a node */ temp = malloc(sizeof(nodeT) + sizeof(char)); if (temp == NULL) { /* if not successful then out of memory */ return(TRUE); } else { /* if successful then table is not full */ return(FALSE); } } /* end of function TableIsFull */ /* * Function: TableSize * ---------------------- * Returns the size of the table */ int TableSize(tableADT table) { return table->count; } /* ------------< end-of-file "table.c" >------------ */ /* * File: hw9-main.c * Author: Manny Ye * Class: CS 113, Fall 96 * Assignment: HW9-Tables Using Binary Search Trees * Due Date: 11 December 1996 * Last modified: 11 December 1996 * ----------------------------------------------------- * * OVERVIEW: * ========= * This program will read files of words and will output the words and * the number of occurences of the words depending on the command given * by the user through file arguments. * USAGE: * words [-m #] [-l #] [-c #] -f file-name * * words: name of the program. * -m: short for "more", print only words which occur more than # times. * -l: short for "lese", print only words which occur fewer than # times * -c: short for "common", print only the most frequent words. * -f: short for "file", reads words from. * * Known Bugs: * ============ * The program only takes one command at a time, except for the -l and -m * commands. These two commands can be used together. * If other combinations are made, nothing will be outputed * * Error Handling: * =============== * - if the argument is incorrect, an appropriate message will be * outputed and the program will terminate. * - if the command are given with 0, then that command is ignored. * * NOTE: * ===== * Extra Credit == "-c" command takes any number of frequencies. * */ #include #include "simpio.h" #include "hw9-table.h" #include "strlib.h" tableADT GetData(int argc, string argv[]); void ExecCommand(int argc, string argv[], tableADT table); tableElementT DoCommon(tableElementT current, tableElementT past); tableElementT PrintTable(tableElementT current, tableElementT past); tableElementT DoMore(tableElementT current, tableElementT initElem); tableElementT DoLess(tableElementT current, tableElementT initElem); tableElementT DoMoreLess(tableElementT current, tableElementT initElem); void DoMoreCommand(tableADT table, int comMore); void DoLessCommand(tableADT table, int comLess); void DoMoreLessCommand(tableADT table, int comMore, int comLess); void DoCommonCommand(tableADT table, int comCommon); int main(int argc, string argv[]) { tableADT table; /* check for missing argument */ if (argc < 2) { printf("\nMissing Arguments\n"); printf("Usage:\n"); printf("words [-m #] [-l #] [-c #] -f file-name\n"); exit(1); } /* end of if */ table = GetData(argc, argv); /* read input from file */ ExecCommand(argc, argv, table); /* execute command */ FreeTable(table); /* when done free the memory associated with the table */ return(0); } /* end of function main */ /* Function: GetData * ------------------ * This function reads in the data from the argument files, and store * it in a table, type of tableADT. If error are found in the argument * the program will terminate. * */ tableADT GetData(int argc, string argv[]) { int i = 1; /* counting var for the argument */ FILE *sourceFilePtr; tableKeyT word; tableDataT count; char tempChar; bool success; tableADT table; /* file the location of file name in the argument */ while ((i < argc) && (! StringEqual(argv[i], "-f"))) {i++;} if (i >= argc) { printf("\n Error in Arguments: missing file-name\n"); printf("Usage:\n"); printf("words [-m #] [-l #] [-c #] -f file-name\n"); exit(1); } /* end of if */ table = NewTable(); /* create an empty table */ /* read in the words in all the files, if no errors are found */ for (;i < argc; i = i+2) { if (! StringEqual(argv[i],"-f")) { printf("\n Error in Arguments: file-name\n"); printf("Usage:\n"); printf("words [-m #] [-l #] [-c #] -f file-name\n"); FreeTable(table); exit(1); } /* end if */ sourceFilePtr = fopen(argv[i+1], "r"); /* open file for reading */ if (sourceFilePtr == NULL) { printf("\n Error in Arguments: file does not exist\n"); printf("Usage:\n"); printf("words [-m #] [-l #] [-c #] -f file-name\n"); fclose(sourceFilePtr); FreeTable(table); exit(1); } /* end if */ /* read the words in the whole file into the table */ while (TRUE) { tempChar = getc(sourceFilePtr); /* first char of word */ if (tempChar == EOF) {break;} /* if end of file, done reading */ /* if the first char is a alphabet, read the rest of the word * and store it as a string. */ if ((tempChar >= 'a' && tempChar <= 'z') || (tempChar >= 'A' && tempChar <= 'Z')) { word = CharToString(tempChar); while (TRUE) { tempChar = getc(sourceFilePtr); if (! ((tempChar >= 'a' && tempChar <= 'z') || (tempChar >= 'A' && tempChar <= 'Z'))) {break;} word = Concat(word, CharToString(tempChar)); } /* end of while */ word = ConvertToLowerCase(word); /* try to find the word in the table */ success = TableRetrieve(table, word, &count); /* if the word is found then add 1 to the count. */ if (success) { TableUpdate(table, word, count + 1); } else { /* if the word is not found and there is enough memory * insert the word into the table */ if (TableIsFull(table)) { printf("Error: Table is Full, Program Terminated\n"); fclose(sourceFilePtr); FreeTable(table); exit(1); } /* end of if */ TableInsert(table, word, 1); /* if word not found insert it */ } /* end of if -- else */ } /* end of if statement */ } /* end of while loop */ fclose(sourceFilePtr); /* after finish reading close file */ } /* end of for loop */ return (table); } /* end of function GetData */ /* Function: ExecCommand * --------------------- * This function read the commands from the argument. If no errors * are found then execute them. * If the same type of command argument is given more than once, only * the last occurance is used for determining the type of report. */ void ExecCommand(int argc, string argv[], tableADT table) { int comMore = 0, comLess = 0, comCommon = 0; int i; /* counting var for the argument */ for (i = 1; i < argc; i=i+2) { if (StringEqual(argv[i], "-m")) { /* if found -m command */ comMore = StringToInteger(argv[i+1]); /* store # in command */ } else if (StringEqual(argv[i], "-l")) { /* if found -l */ comLess = StringToInteger(argv[i+1]); /* store # */ } else if (StringEqual(argv[i], "-c")) { /* if found -c */ comCommon = StringToInteger(argv[i+1]); /* store # */ } else if (StringEqual(argv[i], "-f")) { /* if found -f */ break; /* done reading commands */ } else { /* if no command match the error */ printf("\n Error in Arguments: Bad Command\n"); printf("Usage:\n"); printf("words [-m #] [-l #] [-c #] -f file-name\n"); FreeTable(table); exit(1); } /* end of nested ifs */ } /* end of for loop */ /* if no command exists, print all words with frequency */ if (comMore == 0 && comLess == 0 && comCommon == 0) { tableElementT dumb; TableTraverse(table, &PrintTable, dumb); return; } /* perform more command if exist */ if (comMore > 0 && comLess == 0 && comCommon == 0) { DoMoreCommand(table, comMore); return; } /* perform less command if exist */ if (comLess > 0 && comMore == 0 && comCommon == 0) { DoLessCommand(table, comLess); return; } /* perform more and less command if exist together */ if (comMore > 0 && comLess > 0 && comCommon == 0) { DoMoreLessCommand(table, comMore, comLess); return; } /* perform common command if exist alone*/ if (comCommon > 0 && comLess == 0 && comMore == 0) { DoCommonCommand(table, comCommon); return; } /* perform common command if exist with less command */ if (comCommon > 0 && comLess > 0 && comMore == 0) { printf("NO COMMAND PERFORMED -- not needed to implement this command\n"); return; } /* perform common command if exist with more command */ if (comCommon > 0 && comLess == 0 && comMore > 0) { printf("NO COMMAND PERFORMED -- not needed to implement this command\n"); return; } /* perform common command if exist with all command */ if (comCommon > 0 && comLess > 0 && comMore > 0) { printf("NO COMMAND PERFORMED -- not needed to implement this command\n"); return; } } /* end of function ExecCommand */ /* Function: DoCommon * ------------------- * This function is used to pass into function TableTraverse to do * the command to print out the most frequent word. * This function returns the element, that occurs most often, back * to the TableTraverse function. */ tableElementT DoCommon(tableElementT current, tableElementT past) { if (current.data > past.data) { return (current); } else { return (past); } } /* end of function DoCommon */ /* Function: PrintTable * --------------------- * This function is used to pass into function TableTraverse and * print all the elements in the table. The past element is ignored */ tableElementT PrintTable(tableElementT current, tableElementT past) { printf("%d %s\n", current.data, current.key); return(past); } /* end of function PrintTable */ /* Function: DoMore * ------------------- * This function is used to pass into function TableTraverse to print * all the elements in the table that are more than a # of occurences * which is stored in the initElem. */ tableElementT DoMore(tableElementT current, tableElementT initElem) { if (current.data > initElem.data) { printf("%d %s\n", current.data, current.key); } return (initElem); } /* end of function DoMore */ /* Function: DoLess * ------------------- * This function is used to pass into function TableTraverse to print * all the elements in the table that are less than a # of occurences * which is stored in the initElem. */ tableElementT DoLess(tableElementT current, tableElementT initElem) { if (current.data < initElem.data) { printf("%d %s\n", current.data, current.key); } return (initElem); } /* end of function DoMore */ /* Function: DoMoreLess * --------------------- * This function is used to pass into function TableTraverse to print * all the elements in the table that are less than a # and more than * a # of occurences which is stored in the initElem. * Less # is stored in initElem.data * More # is stored in initElem.key incripted as a string. */ tableElementT DoMoreLess(tableElementT current, tableElementT initElem) { if ((current.data < initElem.data) && (current.data > (StringToInteger(initElem.key)))) { printf("%d %s\n", current.data, current.key); } return(initElem); } /* end of function DoMoreLess */ /* Function: DoMoreCommand * ----------------------- * This function is a wrapper function to call TableTraverse with * the More command */ void DoMoreCommand(tableADT table, int comMore) { tableElementT initElem; initElem.data = comMore; TableTraverse(table, &DoMore, initElem); } /* end of function DoMoreCommand */ /* Function: DoLessCommand * ----------------------- * This function is a wrapper function to call TableTraverse with * the Less command */ void DoLessCommand(tableADT table, int comLess) { tableElementT initElem; initElem.data = comLess; TableTraverse(table, &DoLess, initElem); } /* end of function DoLessCommand */ /* Function: DoMoreLessCommand * ----------------------- * This function is a wrapper function to call TableTraverse with * the More and Less command together */ void DoMoreLessCommand(tableADT table, int comMore, int comLess) { tableElementT initElem; initElem.data = comLess; initElem.key = IntegerToString(comMore); TableTraverse(table, &DoMoreLess, initElem); } /* end of function DoMoreLessCommand */ /* Function: DoCommonCommand * ----------------------- * This function is a wrapper function to call TableTraverse with * the common command. The function creates a array of size of the * common command. Then it calls TableTraverse to find the most * frequent word in the table and store that word in the array. * If the common command requires 2 or more elements, then the that * most frequent word would be deleted from the table and then find * the next most frequent word and so on. */ void DoCommonCommand(tableADT table, int comCommon) { tableElementT array[comCommon]; /* array of most frequent words */ tableElementT initElem; int i; /* looping var */ initElem.data = 0; if (comCommon > TableSize(table)) { printf("Common size is greater than total number of words.\n"); printf("Common size will be change to the total number of words\n"); comCommon = TableSize(table); printf("Command change to \"-c %d\"\n", comCommon); } /* get most frequent word and store in array * delete that word from table * and find the next most frequent word */ for (i = 0; i < comCommon; i++) { array[i] = TableTraverse(table, &DoCommon, initElem); TableRemove(table, array[i].key); } /* print out the array of most frequent words */ for (i = 0; i < comCommon; i++) { printf("%d %s\n", array[i].data, array[i].key); } } /* end of function DoCommonCommand */ /*------------------< end of file hw9-main.c >----------------*/ -- END OF LOG FILE FOR mye --