Hi, I'm trying to figure out how classes work. I currently am working on getting a class to read a string and then place it into an array, as well as have the class then output the entire array. I wrote the following code to make sure i could get it working without a class, but now I don't know how to continue.

int main(void)
{
	int hold = 0;
	string table[MAX_ARRAY_SIZE];

	string word;


	cout<<"This code will take in 15 words and store them based on a hash function."<<endl;
	
	for(int c ount = 0; count < MAX_ARRAY_SIZE; count++)
	{
		table[count] = "?";
	}
	
	for(int count = 0; count < 15; count++)
		{
			getline(cin, word);
			
			hold= ((word[0] + word[word.size()-1])% MAX_ARRAY_SIZE);

			table[hold] = word; 
		}
	
	cout<<endl;

	for(int count = 0; count < MAX_ARRAY_SIZE; count++)
	{
		cout<<table[count]<<endl;
	}
}

I would make table a vector instead of array of strings so that it can hold as many strings or as few as you want. vector<string> table; . IMHO that hash line is probably much less efficient than just adding the new string to the next available slot in the array. For example if you input two strings that are the same length then that hash function will produce the same array index and the second string will overwrite the first.

Alright, I can work on getting the hash function to push everything forward to insert the word with the same hash size. I still need to get it working with a hash, which is the main thing I don't understand.

Make table a private member of your class. Use a "setter" method that takes in the value, applies the hash function and puts it in the proper cell of the array.
ADs point is valid and important as not all inputs to your hash function will hash uniquely, causing collisions (how can you store 2+ elements at the same index of the array?). Using a vector allows you to hold multiple entries at the same position. That way it expands as necessary and once you need to retrieve something just step through all the members at that particular location.

I currently have this as my code, I have everything taken care of except collisions. Suggestions? Also, I'm required to keep it as a locked array, not using a vector.

Main:

using namespace std;

int main(void)
{
	hash_class hash;

	string word;
	
	cout<<"This code will take in 15 words and store them based on a hash function."<<endl;
	
	hash.initilize();

	for(int count = 0; count < 15; count++)
		{
			getline(cin, word);
			hash.add(count, word);
		}	
	
	cout<<endl;

	for(int count = 0; count < MAX_ARRAY_SIZE; count++)
		{
			hash.display(count);
		}
}

Header File:

using namespace std;
const int MAX_ARRAY_SIZE = 23;

class hash_class
{
private:
	string table[MAX_ARRAY_SIZE];
	
public:


void display(int count)
	{
		cout<<table[count]<<endl;
	}

void initilize()
	{
		for(int count = 0; count < MAX_ARRAY_SIZE; count++)
			{
				table[count] = "?";
			}
	}

void add(int count, string word)
	{
		int hold = 0;
	
		hold= ((word[0] + word[word.size()-1])% 23);

		table[hold] = word; 
	}
};

Looks like you did it pretty well. I can think of two options, the first would be to report the collision to the user and not file the word.

The second would be, if you have a string holding your word, nothing is stopping you from appending a colliding word onto the end of the word occupying that position and using a space or comma or any other symbol as the delimiter. You would then need to account for this when you are outputting the strings at a given index. I don't know whether this is a good practice or not, but would work for purposes of your assignment.

Alright, I'll have to try it out thanks! I think I only have one last problem and that's with my main. At the bottom where it says "getline(cin, word_search);
cout<<endl;"

The program is completely jumping over this. Is this because of an endline taking up the space? If it is, how do I clear out the input stream to make it actually read this line?

#include <iostream>
#include <string>
#include "HashClass.h"
using namespace std;

int main(void)
{
	hash_class hash;

	string word;
	string word_search;
	int decision = 1;
	
	cout<<"This code will take in 15 words and store them based on a hash function."<<endl;
	
	hash.initilize();

	for(int count = 0; count < 15; count++)
		{
			getline(cin, word);
			hash.add(count, word);
		}	
	
	cout<<endl;

	for(int count = 0; count < MAX_ARRAY_SIZE; count++)
		{
			hash.display(count);
		}

	cout<<endl;

	while(decision == 1)
	{
		cout<<"Would you now like to search the array for a specific word? 1) Yes 0) No"<<endl;
		cout<<"Decision: ";
		cin>>decision;
		if(decision == 1)
		{
			cout<<"Please enter a word to search for now: ";
			
			getline(cin, word_search);
			cout<<endl;
			//hash.search(word_search);
		}
	}
	
return 0;
}

When entering integers the '\n' (Return key) is left in the keyboard buffer. You need to clear that and all other characters out before calling getline(). See this thread for instructions how to do that.

Alright! Got it all working! Thanks!!

Alright, I guess I don't have it all working lol.

It now runs through it if there's no conflicts. But if there is a conflict now it freezes. What I'm trying to get it to do is search ahead from the hash point, and then if it doesn't find and empty spot from there to the end, it starts at the beginning and runs until it reaches the hash point.

void add(int count, string word)
	{
		int hold = 0;
		bool set = false;
	
		hold= ((word[0] + word[word.size()-1])% MAX_ARRAY_SIZE);

		if(table[hold] != "?")
		{
			while(set == false)
			{
				for(int run = hold; run < MAX_ARRAY_SIZE; run++)
				{
					if(table[run] == "?")
					{
						table[run] = word; 
						set = true;
					}
				}
				
				for(int secondpass = 0; secondpass < hold; secondpass++)
				{
					if(table[secondpass] == "?")
					{
						table[secondpass] = word; 
						set = true;
					}
				}
			}
		}

Part of the problem is that if your program makes it through the two while loops without finding a "?" then set is still equal to false so the while loop runs again and again. You may not even want the while loop.

Also, you may want to put in a break statement (to get out of the for loop) after each of the set = true; statements, since you don't want it to run through the second loop if you've found "?" in the first. In the case of the first for loop, you'll need an additional if statement to break from the while loop/skip the second for also.

Actually all set this time. Have it working and turned in. Thanks for the help!!

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.