Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

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 //to handle file opening and closing

#include

#include

#include // to handle strings

#include

#include

#include

//including the self created hashtable header file

#include "HashTable.h"

using namespace std;

// declaring iterator for hash_table

typedef HashTable::Iterator iterDec;

// delimiters

const char* DELIMITERS = " ,.-\':;?()+*/\\%$#!\"@\^&";

// declaring hashtable size

const int TABLE_SIZE = 29990;

// function to check the spelling of given word

int Spell_Check(HashTable& hashTable, string word);

// declaring function prototypes

void Print_Table_Stats(HashTable& 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 hashTable(TABLE_SIZE);

// 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(userInput.c_str()),DELIMITERS);

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::max(),' '); // clear the cin buffer

}while(toupper(response)=='Y');

cout<<"BYE the dictionary exits!!n";

return 0;

}// end of main

int Spell_Check(HashTable& hashTable, string word)

{//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::HashTable(int hashSze)

{

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::IsEmpty(int key)

{

if(key >=0 && key < hashSize)

{

return head[key] == NULL;

}

return true;

}/* End of IsEmpty */

template

bool HashTable::IsFull()

{

try

{

node* location = new node;

delete location;

return false;

}

catch(std::bad_alloc&)

{

return true;

}

}/* End of IsFull */

template

int HashTable::Hash(ItemType newItem)

{

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::Insert(ItemType newItem)

{

if(IsFull())

{

//std::cout<<"nINSERT ERROR - HASH TABLE FULLn";

}

else

{

int key = Hash(newItem);

Append(key,newItem);

}

}/* End of Insert */

template

void HashTable::Append(int key, ItemType newItem)

{

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::Remove(ItemType deleteItem, int key)

{

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::Sort(int key)

{

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::TableSize()

{

return hashSize;

}/* End of TableSize */

template

int HashTable::TotalElems()

{

return totElems;

}/* End of TotalElems */

template

int HashTable::BucketSize(int key)

{

return(!IsEmpty(key)) ? bucketSize[key]:0;

}/* End of BucketSize */

template

int HashTable::Count(ItemType searchItem)

{

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::MakeEmpty()

{

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::~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::Iterator :

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

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image_2

Step: 3

blur-text-image_3

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Big Data Fundamentals Concepts, Drivers & Techniques

Authors: Thomas Erl, Wajid Khattak, Paul Buhler

1st Edition

0134291204, 9780134291208

More Books

Students also viewed these Databases questions

Question

What do Dimensions represent in OLAP Cubes?

Answered: 1 week ago