Hi,

I am working on a program that reads through a file, gets the words, and finds all the anagrams in the file. For example if the input is

Pans
stop
pots
pots
Sits
it's
snap

I have no trouble reading the words from the file. I create a signature for each word as such.

Original Word Signature
Pans anps
snap anps
Sit ist
it’s ist
stop opts Pots opts Pots opts
opt opt

Now I am suppose to sort the anagrams by lines and then display as such :

Pans snap
Pots stop Pots
Sit it’s
opt

This is where I am stuck. I am having difficulty geting pass the signatures.

What I want to do is use a 2D vector or array and then sort it by the signatures. Then I could go through the sorted word list and display play all the anagrams line by line.

I need help. This is the code that I have so far.

//CLASS DECLARATION

class anagram{

	private: //I have variables here
		
	public:
		 		
		
		//Constructor
		anagram(){
		}

		//MEMBER FUNCTIONS			
		//get and returns the name of the input file
		string get_fileName(){

			cout << "Please Enter the Name of the File: ";
			getline(cin, fileName);

			return fileName;
		}//end

	
		//opens, reads, and closes the input file
		void processFile (){	

			//open file
			inFile.open(fileName.c_str(),ios::in);

			
			//CHECK if file opens
			if (inFile.bad() || inFile.fail()){
				cerr << "\tFile Does Not Exist OR the Name is spelled incorrectly --> " 
				     << fileName << endl << endl;
				exit(1);
			}			
			//CHECK if file is "empty"
			long int byteSize = 0;
			//move pointer and get length
			inFile.seekg(0, ios::end);
			//get the position of the pointer
			byteSize = inFile.tellg();
			if ( byteSize == 0) { // input file is empty; size = 0 bytes
				cerr << "\t\t\tThe file --> " << fileName << " is empty" << endl;
				exit(1);
			}
			else
			//rewind the stream
			inFile.seekg(0, ios::beg);
			

			//////////Now PROCESS the words in the file//////////////////////////////////////////////
			//initialize the word counter
			numWords = 0;
			
			while (!inFile.eof()){
			
				//get_fileName();

				//get data in lines from the file
				getline(inFile, line);
				

				//break lines into words
				istringstream instr (line);
				while (instr >> word){
					//check length of word >= 15
					//cout << word << endl;

					if (word.length() <= 15){
						word = removeJunk(word);
						//build the list of words
						
						
						//change word case and store
						//transform (word.begin(), word.end(),word.begin(), tolower);
						//mod_wordList.push_back(word);

						//sort words and store into vector
						//sort(word.begin(),word.end());
						//wordDict.push_back(word);
						//Add to dictionary
						wordList.push_back(word);
						
						numWords++;	
									
						
						//TERMINATE pogram if number of words of proper length exceeds 50
						if(numWords > 50){
							cout << "\t\tThere are more than 50 words in " << fileName << endl;
							exit (1);
						}

					}//end if
				}//end inner while			
			}//end outer while	
			
			inFile.close();//close the file

			cout << "NUM = " <<numWords << endl;

			for (int i = 0; i < wordList.size(); i++){
				cout << wordList[i] <<  endl;
			}

			cout<<endl;
		}//end procesFile

				
		//removes excess characters from words
		string removeJunk(string word){

			int numChars =0;
			int wordLength = word.length();	//stores the processed word
			string result;					//stores the porcessed word


			for (int i=0; i < wordLength; i++){
				
				if (isalpha(word[i])){
					result = result + word[i];	
					numChars++;
				}
			}	 	
			
			//ACCOUNT for a file of non alpha characters
			if (numChars == 0){
				cerr << "\t\tThe file --> " << fileName << " contains 0 words!!!" << endl;
				exit(1);
			}
			
			return result;
		}//end

Easiest way to sort two arrays at the same time is to create another array used as an index array into the two originals. For example:

string  words[20];
string  signature[20];
int     index[20] = {0,1,2,3,4 ... 18,19};

Now access signature array using the index array for the sort: signature[index[j]] You end up sorting the index array instead of the string arrays. Once sorted, access both signature and words using index and they still match.

Member Avatar for iamthwee

> This is where I am stuck. I am having difficulty geting pass the signatures.
What I want to do is use a 2D vector or array and then sort it by the signatures.

So basically you want to create a class and then have the option to sort by its various attributes. In that case you can utilize std::sort to achieve your goals. Viz...

#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

class Student
{
public:
   string name;
   double tuition;
};

//This functions sort by name
bool SortStudentByName ( const Student& left, const Student& right )
{
   //Here you can define whatever the sort criterion
   //needs to be. It can be as complicated as you wish

   if ( left.name > right.name )
   {
      return false;
   }
   else if ( left.name < right.name )
   {
      return true;
   }
   //else //i.e if both are equal

}

//This function sorts by tuitions fees
bool SortStudentByTute ( const Student& left, const Student& right )
{
   if ( left.tuition > right.tuition )
   {
      return false;
   }
   else if ( left.tuition < right.tuition )
   {
      return true;
   }
}

int main()
{
   Student myStudent [3]; //create an array of objects

   myStudent[0].name = "sarah";
   myStudent[0].tuition = 10.2;

   myStudent[1].name = "carry";
   myStudent[1].tuition = 11.2;

   myStudent[2].name = "zog";
   myStudent[2].tuition = 3;

   // call the sort like this (assuming array has size of 3):

   cout << "sorting by tutition fees\n";
   std::sort ( myStudent, myStudent + 3, SortStudentByTute );

   cout << myStudent[0].name << " " << myStudent[0].tuition << endl;
   cout << myStudent[1].name << " " << myStudent[1].tuition << endl;
   cout << myStudent[2].name << " " << myStudent[2].tuition << endl;

   //--------------------------------------------------------

   cout << "\nsorting by names\n";

   std::sort ( myStudent, myStudent + 3, SortStudentByName );

   cout << myStudent[0].name << " " << myStudent[0].tuition << endl;
   cout << myStudent[1].name << " " << myStudent[1].tuition << endl;
   cout << myStudent[2].name << " " << myStudent[2].tuition << endl;

   // Or use a vector instead of the array and sort like this:
   //std::sort(myStudentVec.begin(), myStudentVec.end(), SortStudentByName);
 
   cin.get();
}
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.