Hi, I'm trying to find a solution to my code and I have general idea what the problem is but I don't know how to solve it please help me.

What the code does:
What my code does is it should read a dictionary file called dict.txt and store each of the words into an array. Then I run my functions to search for the words in the array.

Problem:
The problem I'm facing is that I supposedly read all the files into the array but when I run a search for the words, not all of them are there. But for some reason it won't read words like zucchini.

I know that it has something to do with the number of words in the dict.txt file and the size of my array. If I set the array size to be the same as the exact amount of words then my program will run without fail. However, I am forced to keep my array at 250,000 as it is a requirement for my task. The dict.txt file has about 233606 words therefore my array is roughly 17000 cells too large.

I have tried multiple input methods even a dict.!eof() but I'm not getting any results.

I have attached my dict.txt file along with the post incase someone wants to run some tests.

Here is my code:

#include <cstdlib>
#include <iostream>
#include <fstream>

using namespace std;

//Variables
string line, word, wordlist[250000];
int linenumber = 0, c = 0;
string temp;

//Function prototypes
void printMenu();
int binSearch (string a[], int n, string target);
bool pattern(string s1, string s2);
bool alpha (string s);
bool alpha2 (string s);

//Main code
int main()
{
	ifstream dict;
    dict.open("dict.txt");
    if (dict.fail())
    {
        cout << "No dictionary file" << endl;
        system("pause");
        return 0;
    }

    //Read dictionary into array to make multiple searches faster:

    while(!dict.fail())	//Makes sure empty lines aren't inserted into the array.
    {
    	while (dict >> wordlist[c])
    		c++;
    }

    //Loop to display menu, get user choice and perform required action:

	while (temp != "3")
	{
		printMenu();
		cin >> temp;
		int cmd = atoi(temp.c_str());

		if(cmd == 1)	//Word search using binSearch method.
		{
			cout << "Enter word " << flush;
			cin >> word;
			if(alpha(word))	//Checks if word is a valid input for option1.
			{
				for (unsigned int i = 0; i < word.length(); i++)	//Loop that converts word to lower-case.
				{
					if (isalpha(word.at(i)) == false)	//Checks if there are any letters in word that are not in the alphabet.
					{
						word.erase(i, 1);
						i--;
					}
					else
						word.at(i) = tolower(word.at(i));	//Converts word to lower-case before search.
				}
				if (binSearch(wordlist, 250000, word)== -1)
				{
					cout << word << " is not in dictionary"  << endl;	//binSearch = -1 (hence not found)
				}
				else
				{
					cout << word << " is in dictionary" << endl;	//binSearch = mid (hence found)
				}
			}
			else
				cout << "Word must be alphabetic" << endl;
		}

		else if (cmd == 2)
		{
			cout << "Enter word pattern with ? for missing letters " << flush;
			cin >> word;
			if(alpha2(word))	//Checks if word is a valid input for option2.
			{
				for (unsigned int i = 0; i < word.length(); i++)	//Loop that converts word to lower-case.
				{
					if ((isalpha(word.at(i)) == false) && (word.at(i) != '?'))	//Checks if there are any letters in word that are not in the alphabet.
					{
						word.erase(i, 1);
						i--;
					}
					else
						word.at(i) = tolower(word.at(i));	//Converts word to lower-case before search.
				}

				for (int k = 0; k < 250000; k++)	//Checks array for words.
				{
					if (pattern(word, wordlist[k]))	//Check if words match.
						cout << wordlist[k] << endl;	//Print words that match
				}
			}
			else
			{
				cout << "Word must be alphabetic" << endl;
			}
		}

		else if (cmd == 3)
		{
			goto Pause;	//Goes to pauce if cmd is equal to 3.
		}

		else
		{
			cout << "Invalid Choice" << endl;
		}
	}
	Pause:
    system("pause");
    return 0;
}

void printMenu()
{
   cout << "\tCrossword Helper " << endl << endl;
   cout << " 1 : Check if word is in dictionary " << endl;
   cout << " 2 : Find words in dictionary which match pattern " << endl;
   cout << " 3 : Quit " << endl;
}

int binSearch(string a[], int n, string target)	//Binary search function.
{
	int first = 0;
	int last = n-1;
	while (first <= last)
	{
		int mid = (first + last) / 2;
		if (a[mid] == target)
			return mid;	//Search returns true, word exists in dictionary.
		else if (a[mid] > target)
			last = mid - 1;
		else
			first = mid + 1;
	}
	return -1;	//Search returns false, word doesn't exist in dictionary.
}

bool pattern(string s1, string s2)	//Checks if pattern in s1 matches s2.
{
	if (s2.length() != s1.length()) return false;	//Checks if length matches, return false if it doesn't.
	for (unsigned int i=0; i < s1.length() ; i++)
	{
		if (s1.at(i) != '?')	//Loop checks if word has any ? in word, if not proceeds to next check.
		{
			if (s1.at(i) != s2.at(i))	//Checks if letters in word match if not return false.  Else check next letter.
			{
				return false;
		    }
		}
	}
	return true;
}

bool alpha (string s)	//Checks if string is a valid input for option1.
{
	for (unsigned int i = 0; i < s.length(); i++)
	{
		if(isalpha(s.at(i)))	//Makes sure all letters in word are alphabetic.
			return true;
	}
	return false;
}

bool alpha2 (string s)	//Checks if string is a valid input for option2.
{
	if((s.at(0)== '?') || isalpha(s.at(0)))  //If letter first letter is alpha or ?.
		return true;	//If true then word is valid input.
	else
		return false;
}

Recommended Answers

All 5 Replies

I know that it has something to do with the number of words in the dict.txt file and the size of my array. If I set the array size to be the same as the exact amount of words then my program will run without fail. However, I am forced to keep my array at 250,000 as it is a requirement for my task. The dict.txt file has about 233606 words therefore my array is roughly 17000 cells too large.

What exactly are your forced to do? If you are forced to have an array CAPACITY of 250,000, that's fine. Technically that's the "size" of the array, but define the size as 233,606 and just ignore all the elements after that. Don't use them and definitely don't pass them uninitialized to a function that expects all of the elements to be ordered and to represent real data.

I have tried multiple input methods even a dict.!eof() but I'm not getting any results.

It has nothing to do with the input method. It has to do with the search method.

int binSearch(string a[], int n, string target)	//Binary search function.
{
	int first = 0;
	int last = n-1;
	while (first <= last)
	{
		int mid = (first + last) / 2;
		if (a[mid] == target)
			return mid;	//Search returns true, word exists in dictionary.
		else if (a[mid] > target)
			last = mid - 1;
		else
			first = mid + 1;
	}
	return -1;	//Search returns false, word doesn't exist in dictionary.
}

n here should be the number of data elements that actually have meaning (i.e. contain actual words), not the array capacity. You have 233,606 words, so that's what you should pass the function. You're making >, <, and == comparisons on elements. Do these have any meaning for element 240,000?

Or I suppose you could initialize elements 233,606 and beyond to "zzzzzzzzz", a "word" that doesn't exist and would be at the end of the alphabet, so any real word would be "less than" that and you thus get the correct range even if you pass the function 250,000.

Yeah, your right I just got too caught up with the whole input method because my lecturer kept saying I was using !eof incorrectly and wasn't reading the inputs correctly...

I found my solution and here it is:

int binSearch(string a[], int n, string target)
{
	int first = 0;
	int last = n-1;
	while (first <= last)
	{
		int mid = (first + last) / 2;
		if (a[mid] == target)
			return mid;
		else if (target.compare(a[mid]) < 0)  <-- .compare fixed it
			last = mid - 1;
		else
			first = mid + 1;
	}
	return -1;
}

I missed the > versus "compare" problem too. Glad you solved it.

[EDIT # 2]
Actually, strike that. What's wrong with using > here? It's just like using compare, right?
[/EDIT]

I missed the > versus "compare" problem too. Glad you solved it.

[EDIT # 2]
Actually, strike that. What's wrong with using > here? It's just like using compare, right?
[/EDIT]

Apparenty .compare compares everything from string length as well as the alphabet of each letter..

The way it was explained to me is that if you don't use compare then A and AB are equal. When in reality AB should be smaller because it comes after in the alphabet if this makes any sense. So it only checks the first letter of the string to see if its larger or smaller.

Apparenty .compare compares everything from string length as well as the alphabet of each letter..

The way it was explained to me is that if you don't use compare then A and AB are equal. When in reality AB should be smaller because it comes after in the alphabet if this makes any sense. So it only checks the first letter of the string to see if its larger or smaller.

Lines 12 and 15 both display for me in the program below.

#include <string>
#include <iostream>
using namespace std;


int main()
{
   string string1 = "AB";
   string string2 = "A";
   
   if (string1.compare (string2) > 0)
       cout << "compare : A is before AB\n";
       
   if (string1 > string2)
       cout << "> : A is before AB\n";
          
   cin.get ();
   return 0;
}

http://www.cppreference.com/wiki/string/string_operators

From the above link (string operators page):

Two strings are equal if:

1. Their size is the same, and
2. Each member in location i in one string is equal to the the member in location i in the other string.

http://www.cppreference.com/wiki/string/compare

From the above link (compare page)

The compare() function either compares str to the current string in a variety of ways, returning

Return Value Case

less than zero 	      this < str
zero 	              this == str
greater than zero     this > str

It looks like using "compare" and using > are equivalent here.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.