Question
UML Diagram, Just need a UML diagram of the program below: XXXXXXXXXXXXXX This is the description before the program was completed. Problem Description Write a
UML Diagram, Just need a UML diagram of the program below:
XXXXXXXXXXXXXX
This is the description before the program was completed.
Problem Description Write a spell checker that stores a set of words, W, in a hash table and implements a function, spellCheck(s), which performs a spell check on the string s with respect to the set of words, W.
If s is in W, then the call to spellCheck(s) returns an iterable collection that contains only s, because it is assumed to be spelled correctly in this case. Otherwise, if s is not in W, then the call to spellCheck(s) returns a list of every word in W that could be a correct spelling of s.
Your program should be able to handle all the common ways that s might be a misspelling of a word in W, including
swapping adjacent characters in a word; inserting a single character in between two adjacent characters in a word; deleting a single character from a word; and replacing a character in a word with another character. The input to your program will consist of the name of a text file, and strings of characters manually entered by the user. The text file will contain the set of words, W, one word per line, and should be read in the program when the program starts. The strings of characters input by the user will be used to test the hash table and the spellCheck function. The program will keep running the tests until the user enters the string "quit".
Create classes SpellChecker and HashTable to implement the spell checker and the hash table, respectively. Create a UML class diagram that describes your class design.
XXXXXXXXXXXXX
From here on is the program that I have already completed for it.
//c++ program
#include
#include
#include
#include
#include
#include
#include
#include
//including the self created hashtable header file
#include "HashTable.h"
using namespace std;
// declaring iterator for hash_table
typedef HashTable
// delimiters
const char* DELIMITERS = " ,.-\':;?()+*/\\%$#!\"@\^&";
// declaring hashtable size
const int TABLE_SIZE = 29990;
// function to check the spelling of given word
int Spell_Check(HashTable
// declaring function prototypes
void Print_Table_Stats(HashTable
//function for lowercase conversion of words
string To_Lower_Case(string word);
int main()
{
// declare variables
string filename;
//getting user file for dictionary making
cout<<"Enter the file name";
cin>> filename;
int result = 0;
//variable for storing user inputted word
string userInput;
string currWord;
clock_t beg; // required to time the hash_table load
clock_t end; // required to time the hash_table load
char response;
// file pointer to handle file
ifstream infile;
HashTable
// open the file containing dictionary word
infile.open(filename);
// check for the file existence, if it does not exist then EXIT
if(infile.fail())
{
cout<<"**FATAL ERROR - Sorry the dictionary file inputed by you could not be found... ";
exit(1);
}
//throwing the processing caption
cerr<<"PLEASE WAIT Dictionary is loading........ ";
beg = clock(); // startING the timer
// fetching the data from inputted file and putting into hash table
while(infile >> currWord)
{
// avoiding duplicate words from entering the table
if(!hashTable.Count(currWord))
{//inserting the current new word into dictionary
hashTable.Insert(currWord);
}
}
//closing the file for safe working
infile.close();
//this function can be used for many stats related to hash table
end = clock()-beg; // ending the timer
cout<<"Your Dictionary has been loaded in "<<
(double)end / ((double)CLOCKS_PER_SEC)<<" secs!";
//showing the time in which we have created the dictonary
// creating the line separator
cout< cout.fill('-'); //filling the whole line with '-' cout< do{ // getting user input for words/sentences cout<<" Please enter a sentence/word: "; getline(cin,userInput); //storing the user input cout< // breaking the sentence into individual words for checking spelling of each char* splitInput = strtok(const_cast while(splitInput!=NULL) {//spilliting the words currWord = splitInput; //conversion of words to lower case currWord = To_Lower_Case(currWord); result += Spell_Check(hashTable,currWord); splitInput = strtok(NULL,DELIMITERS); } // displaying results if(result > 0) {//showing the number of words which are misspelled cout<<"Number of words spelled incorrectly: "< result = 0; } // ask for more data cout<<"Do you want to enter few another sentence/words? (y/quit): "; //recording the user response cin >> response; cin.ignore(numeric_limits }while(toupper(response)=='Y'); cout<<"BYE the dictionary exits!!n"; return 0; }// end of main int Spell_Check(HashTable {//declaring variables int result = 0; int suggestions = 0; //declaring string array of size 256 words string remove[256]; int numRemove=0; //if hashtable have words then if(!hashTable.Count(word)) { ++result; cout<<"** "< // checking for alteration & insertion in word for(unsigned x = 0; x < word.length(); ++x) { string alteration = word; for(char c = 'a'; c <= 'z'; ++c) { //if a alphabet is altered with another alphabet alteration[x] = c; if(hashTable.Count(alteration)) { cout< remove[numRemove++] = alteration; ++suggestions; // removing the entries so that every entry is present only once hashTable.Remove(alteration); } // checking for insertion string insertion = word.substr(0, x) + c + word.substr(x); //if insertion found if(hashTable.Count(insertion)) { cout< //removing that insertion remove[numRemove++] = insertion; ++suggestions; // remove the entry is unique not multiple times hashTable.Remove(insertion); } } } // checking for adjacent swapping (transposition) & deletion for(unsigned c = 0; c < word.length()-1;++c) { // transposition string transposition = word.substr(0,c) + word[c+1] + word[c] + word.substr(c+2); if(hashTable.Count(transposition)) { cout< remove[numRemove++] = transposition; ++suggestions; // remove the entry so it isnt displayed multiple times hashTable.Remove(transposition); } // checking for deletion string deletion = word.substr(0, c)+ word.substr(c + 1); //if deletion found then if(hashTable.Count(deletion)) { cout< //recording that deletion remove[numRemove++] = deletion; ++suggestions; // remove the entry to avoid multiple apperance hashTable.Remove(deletion); } } // placing the removed items back into the hashtable while(numRemove>=0) {//inserting item hashTable.Insert(remove[numRemove--]); } //if no suggestions are found if(suggestions< 1) { cout<<"Sorry No spelling suggestion found..."; } cout< } //returniing the spell check result return result; }// end of Spell_Check //function for conversion of word string to lower case string To_Lower_Case(string word) {//converting everyword to its lowercase for(unsigned c = 0; c < word.length(); ++c) {//using tolower functio for lower case conversion word[c] = tolower(word[c]); } //returning the lowercase word return word; }// end of To_Lower_Case //hashtable.h #ifndef TEMPLATE_HASH_TABLE #define TEMPLATE_HASH_TABLE #include #include #include #include // if user doesnt define, this is the // default hash table size const int HASH_SIZE = 100; template class HashTable { public: HashTable(int hashSze = HASH_SIZE); /* Function: Constructor initializes hash table Precondition: None Postcondition: Defines private variables */ bool IsEmpty(int key); /* Function: Determines whether hash table is empty at the given key Precondition: Hash table has been created Postcondition: The function = true if the hash table is empty and the function = false if hash table is not empty */ bool IsFull(); /* Function: Determines whether hash table is full Precondition: Hash table has been created Postcondition: The function = true if the hash table is full and the function = false if hash table is not full */ int Hash(ItemType newItem); /* Function: Computes and returns a unique hash key for a given item The returned key is the given cell where the item resides Precondition: Hash table has been created and is not full Postcondition: The hash key is returned */ void Insert(ItemType newItem); /* Function: Adds newItem to the back of the list at a given key in the hash table A unique hash key is automatically generated for each newItem Precondition: Hash table has been created and is not full Postcondition: Item is in the hash table */ void Append(int key, ItemType newItem); /* Function: Adds new item to the end of the list at a given key in the hash table Precondition: Hash table has been created and is not full Postcondition: Item is in the hash table */ bool Remove(ItemType deleteItem, int key = -1); /* Function: Removes the first instance from the table whose value is "deleteItem" Optional second parameter indicates the key where deleteItem is located Precondition: Hash table has been created and is not empty Postcondition: The function = true if deleteItem is found and the function = false if deleteItem is not found */ void Sort(int key); /* Function: Sort the items in the table at the given key Precondition: Hash table has been initialized Postcondition: The hash table is sorted */ int TableSize(); /* Function: Return the size of the hash table Precondition: Hash table has been initialized Postcondition: The size of the hash table is returned */ int TotalElems(); /* Function: Return the total number of elements contained in the hash table Precondition: Hash table has been initialized Postcondition: The size of the hash table is returned */ int BucketSize(int key); /* Function: Return the number of items contained in the hash table cell at the given key Precondition: Hash table has been initialized Postcondition: The size of the given key cell is returned */ int Count(ItemType searchItem); /* Function: Return the number of times searchItem appears in the table. Only works on items located in their correctly hashed cells Precondition: Hash table has been initialized Postcondition: The number of times searchItem appears in the table is returned */ void MakeEmpty(); /* Function: Initializes hash table to an empty state Precondition: Hash table has been created Postcondition: Hash table no longer exists */ ~HashTable(); /* Function: Removes the hash table Precondition: Hash table has been declared Postcondition: Hash table no longer exists */ // -- ITERATOR CLASS -- class Iterator; /* Function: Class declaration to the iterator Precondition: Hash table has been declared Postcondition: Hash Iterator has been declared */ Iterator begin(int key){return(!IsEmpty(key)) ? head[key]:NULL;} /* Function: Returns the beginning of the current hash cell list Precondition: Hash table has been declared Postcondition: Hash cell has been returned to the Iterator */ Iterator end(int key=0){return NULL;} /* Function: Returns the end of the current hash cell list Precondition: Hash table has been declared Postcondition: Hash cell has been returned to the Iterator */ private: struct node { ItemType currentItem; node* next; }; node** head; // array of linked list declaration - front of each hash table cell int hashSize; // the size of the hash table (how many cells it has) int totElems; // holds the total number of elements in the entire table int* bucketSize; // holds the total number of elems in each specific hash table cell }; //========================= Implementation ================================// template HashTable { hashSize = hashSze; head = new node*[hashSize]; bucketSize = new int[hashSize]; for(int x=0; x < hashSize; ++x) { head[x] = NULL; bucketSize[x] = 0; } totElems = 0; }/* End of HashTable */ template bool HashTable { if(key >=0 && key < hashSize) { return head[key] == NULL; } return true; }/* End of IsEmpty */ template bool HashTable { try { node* location = new node; delete location; return false; } catch(std::bad_alloc&) { return true; } }/* End of IsFull */ template int HashTable { long h = 19937; std::stringstream convert; // convert the parameter to a string using "stringstream" which is done // so we can hash multiple datatypes using only one function convert << newItem; std::string temp = convert.str(); for(unsigned x=0; x < temp.length(); ++x) { h = (h << 6) ^ (h >> 26) ^ temp[x]; } return abs(h % hashSize); } /* End of Hash */ template void HashTable { if(IsFull()) { //std::cout<<"nINSERT ERROR - HASH TABLE FULLn"; } else { int key = Hash(newItem); Append(key,newItem); } }/* End of Insert */ template void HashTable { if(IsFull()) { //std::cout<<"nAPPEND ERROR - HASH TABLE FULLn"; } else { node* newNode = new node; // adds new node newNode-> currentItem = newItem; newNode-> next = NULL; if(IsEmpty(key)) { head[key] = newNode; } else { node* tempPtr = head[key]; while(tempPtr-> next != NULL) { tempPtr = tempPtr-> next; } tempPtr-> next = newNode; } ++bucketSize[key]; ++totElems; } }/* End of Append */ template bool HashTable { bool isFound = false; node* tempPtr; if(key == -1) { key = Hash(deleteItem); } if(IsEmpty(key)) { //std::cout<<"nREMOVE ERROR - HASH TABLE EMPTYn"; } else if(head[key]->currentItem == deleteItem) { tempPtr = head[key]; head[key] = head[key]-> next; delete tempPtr; --totElems; --bucketSize[key]; isFound = true; } else { for(tempPtr = head[key];tempPtr->next!=NULL;tempPtr=tempPtr->next) { if(tempPtr->next->currentItem == deleteItem) { node* deleteNode = tempPtr->next; tempPtr-> next = tempPtr-> next-> next; delete deleteNode; isFound = true; --totElems; --bucketSize[key]; break; } } } return isFound; }/* End of Remove */ template void HashTable { if(IsEmpty(key)) { //std::cout<<"nSORT ERROR - HASH TABLE EMPTYn"; } else { int listSize = BucketSize(key); bool sorted = false; do{ sorted = true; int x = 0; for(node* tempPtr = head[key]; tempPtr->next!=NULL && x < listSize-1; tempPtr=tempPtr->next,++x) { if(tempPtr-> currentItem > tempPtr->next->currentItem) { ItemType temp = tempPtr-> currentItem; tempPtr-> currentItem = tempPtr->next->currentItem; tempPtr->next->currentItem = temp; sorted = false; } } --listSize; }while(!sorted); } }/* End of Sort */ template int HashTable { return hashSize; }/* End of TableSize */ template int HashTable { return totElems; }/* End of TotalElems */ template int HashTable { return(!IsEmpty(key)) ? bucketSize[key]:0; }/* End of BucketSize */ template int HashTable { int key = Hash(searchItem); int search = 0; if(IsEmpty(key)) { //std::cout<<"nCOUNT ERROR - HASH TABLE EMPTYn"; } else { for(node* tempPtr = head[key];tempPtr!=NULL;tempPtr=tempPtr->next) { if(tempPtr->currentItem == searchItem) { ++search; } } } return search; }/* End of Count */ template void HashTable { totElems = 0; for(int x=0; x < hashSize; ++x) { if(!IsEmpty(x)) { //std::cout << "Destroying nodes ...n"; while(!IsEmpty(x)) { node* temp = head[x]; //std::cout << temp-> currentItem < head[x] = head[x]-> next; delete temp; } } bucketSize[x] = 0; } }/* End of MakeEmpty */ template HashTable { MakeEmpty(); delete[] head; delete[] bucketSize; }/* End of ~HashTable */ // END OF THE HASH TABLE CLASS // ----------------------------------------------------------- // START OF THE HASH TABLE ITERATOR CLASS template class HashTable public std::iterator public HashTable { public: // Iterator constructor Iterator(node* otherIter = NULL) { itHead = otherIter; } ~Iterator() {} // The assignment and relational operators are straightforward Iterator& operator=(const Iterator& other) { itHead = other.itHead; return(*this); } bool operator==(const Iterator& other)const { return itHead == other.itHead; } bool operator!=(const Iterator& other)const { return itHead != other.itHead; } bool operator<(const Iterator& other)const { return itHead < other.itHead; } bool operator>(const Iterator& other)const { return other.itHead < itHead; } bool operator<=(const Iterator& other)const { return (!(other.itHead < itHead)); } bool operator>=(const Iterator& other)const { return (!(itHead < other.itHead)); } // Update my state such that I refer to the next element in the // HashTable. Iterator operator+(int incr) { node* temp = itHead; for(int x=0; x < incr && temp!= NULL; ++x) { temp = temp->next; } return temp; } Iterator operator+=(int incr) { for(int x=0; x < incr && itHead!= NULL; ++x) { itHead = itHead->next; } return itHead; } Iterator& operator++() // pre increment { if(itHead != NULL) { itHead = itHead->next; } return(*this); } Iterator operator++(int) // post increment { node* temp = itHead; this->operator++(); return temp; } ItemType& operator[](int incr) { // Return "junk" data // to prevent the program from crashing if(itHead == NULL || (*this + incr) == NULL) { return junk; } return(*(*this + incr)); } // Return a reference to the value in the node. I do this instead // of returning by value so a caller can update the value in the // node directly. ItemType& operator*() { // Return "junk" data // to prevent the program from crashing if(itHead == NULL) { return junk; } return itHead->currentItem; } ItemType* operator->() { return(&**this); } private: node* itHead; ItemType junk; }; #endif
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started