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
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.
CODE:
#include <iostream>
#include <fstream>//to handle file opening and closing
#include <cctype>
#include <cstring>
#include <string> // to handle strings
#include <iomanip>
#include <ctime>
#include <limits>
//including the self created hashtable header file
#include "HashTable.h"
using namespace std;
// declaring iterator for hash_table
typedef HashTable<string>::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<string>& hashTable, string word);
// declaring function prototypes
void Print_Table_Stats(HashTable<string>& 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<string> 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...\n";
exit(1);
}
//throwing the processing caption
cerr<<"PLEASE WAIT Dictionary is loading........\n";
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<<endl;
cout.fill('-');
//filling the whole line with '-'
cout<<left<<setw(50)<<""<<endl;
do{ // getting user input for words/sentences
cout<<" Please enter a sentence/word: ";
getline(cin,userInput);
//storing the user input
cout<<endl;
// breaking the sentence into individual words for checking spelling of each
char* splitInput = strtok(const_cast<char*>(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<<endl;
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<streamsize>::max(),'\n'); // clear the cin buffer
}while(toupper(response)=='Y');
cout<<"BYE the dictionary exits!!n";
return 0;
}// end of main
int Spell_Check(HashTable<string>& 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<<"** "<<word<<": ";
// 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<<alteration<<", ";
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<<insertion<<", ";
//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<<transposition<<", ";
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<<deletion<<", ";
//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<<endl<<endl;
}
//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 <iostream>
#include <string>
#include <sstream>
#include <cstdlib>
// if user doesnt define, this is the
// default hash table size
const int HASH_SIZE = 100;
template <class ItemType>
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<class ItemType>
HashTable<ItemType>::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<class ItemType>
bool HashTable<ItemType>::IsEmpty(int key)
{
if(key >=0 && key < hashSize)
{
return head[key] == NULL;
}
return true;
}/* End of IsEmpty */
template<class ItemType>
bool HashTable<ItemType>::IsFull()
{
try
{
node* location = new node;
delete location;
return false;
}
catch(std::bad_alloc&)
{
return true;
}
}/* End of IsFull */
template<class ItemType>
int HashTable<ItemType>::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<class ItemType>
void HashTable<ItemType>::Insert(ItemType newItem)
{
if(IsFull())
{
//std::cout<<"nINSERT ERROR - HASH TABLE FULLn";
}
else
{
int key = Hash(newItem);
Append(key,newItem);
}
}/* End of Insert */
template<class ItemType>
void HashTable<ItemType>::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<class ItemType>
bool HashTable<ItemType>::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<class ItemType>
void HashTable<ItemType>::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<class ItemType>
int HashTable<ItemType>::TableSize()
{
return hashSize;
}/* End of TableSize */
template<class ItemType>
int HashTable<ItemType>::TotalElems()
{
return totElems;
}/* End of TotalElems */
template<class ItemType>
int HashTable<ItemType>::BucketSize(int key)
{
return(!IsEmpty(key)) ? bucketSize[key]:0;
}/* End of BucketSize */
template<class ItemType>
int HashTable<ItemType>::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<class ItemType>
void HashTable<ItemType>::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 <<std::endl;
head[x] = head[x]-> next;
delete temp;
}
}
bucketSize[x] = 0;
}
}/* End of MakeEmpty */
template<class ItemType>
HashTable<ItemType>::~HashTable()
{
MakeEmpty();
delete[] head;
delete[] bucketSize;
}/* End of ~HashTable */
// END OF THE HASH TABLE CLASS
// -----------------------------------------------------------
// START OF THE HASH TABLE ITERATOR CLASS
template <class ItemType>
class HashTable<ItemType>::Iterator :
public std::iterator<std::forward_iterator_tag,ItemType>,
public HashTable<ItemType>
{
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
Write a spell checker that stores a set of words, W, in a hash table and...
Write a spell checker class 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, since it is assumed to be spelled correctly in this case. Otherwise, if s is not in W, then the call to spellCheck(s) returns...
IN JAVA: Write a spell checker class 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, since it is assumed to be spelled correctly in this case. Otherwise, if s is not in W, then the call to...
create a hash table to implement spell checker in java 1. Create a file of 100 words of varying length (max 8 characters). 2. All the words are in lower case. 3. design a hash table. 4. enter each word in the hash table. Once the hash table is created, run it as a spell checker.enter a word (interactive), find the word in the hash table. If not found enter an error message. Then prompt for next word. End the...
In this lab you will write a spell check program. The program has two input files: one is the dictionary (a list of valid words) and the other is the document to be spellchecked. The program will read in the words for the dictionary, then will read the document and check whether each word is found in the dictionary. If not, the user will be prompted to leave the word as is or type in a replacement word and add...
In C++ and not Java: Implement a spelling checker by using a hash table. Assume that the dictionary comes from two sources: an existing large dictionary and a second file containing a personal dictionary. Output all misspelled words and the line numbers on which they occur. Also, for each misspelled word, list any words in the dictionary that are obtainable by applying any of the following rules: 1. Add one character. 2. Remove one character. 3. Exchange adjacent characters The...
Overview: The goal of this assignment is to implement a simple spell checker using a hash table. You will be given the basic guidelines for your implementation, but other than that you are free to determine and implement the exact classes and methods that you might need. Your spell-checker will be reading from two input files. The first file is a dictionary containing one word per line. The program should read the dictionary and insert the words into a hash...
For this week's lab, you will use two of the classes in the Java Collection Framework: HashSet and TreeSet. You will use these classes to implement a spell checker. Set Methods For this lab, you will need to use some of the methods that are defined in the Set interface. Recall that if set is a Set, then the following methods are defined: set.size() -- Returns the number of items in the set. set.add(item) -- Adds the item to the...
For this week's lab, you will use two of the classes in the Java Collection Framework: HashSet and TreeSet. You will use these classes to implement a spell checker. Set Methods For this lab, you will need to use some of the methods that are defined in the Set interface. Recall that if set is a Set, then the following methods are defined: set.size() -- Returns the number of items in the set. set.add(item) -- Adds the item to the...
Dictionary.java DictionaryInterface.java Spell.java SpellCheck.java In this lab you will write a spell check program. The program has two input files: one is the dictionary (a list of valid words) and the other is the input file to be spell checked. The program will read in the words for the dictionary, then will read the input file and check whether each word is found in the dictionary. If not, the user will be prompted to leave the word as is, add...
C++ please! (1) Prompt the user to enter the name of the input file. The file will contain a text on a single line. Store the text in a string. Output the string. Ex: Enter file name: input1.txt File content: We'll continue our quest in space. There will be more shuttle flights and more shuttle crews and, yes, more volunteers, more civilians, more teachers in space. Nothing ends here; our hopes and our journeys continue! (2) Implement a PrintMenu() function,...