I am working on a program that will read a list of words from a file. For each word, I have to build a key which is basically the word with all of its letters sorted (i.e. dorw is the key for word). I need to build an array of all the keys sorted and an array of the primary words. Then, I need to go through array and find the duplicated keys and corresponding words. The output should look something like this:

pots stop
from form
lead deal

Right now, my program goes through the list and it rearranges the letters but it is not in alphabetical order. Please help me get on the right track.

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


char read (char *, int);
char arrayCopy(char* , int& );
void getKeys(char*, int& );
void bubbleSortKeys (char * , int );
void findDuplicates(char* ,char* , int& );

char** read(const char* fileName, int& count)
{
  ifstream countingStream(fileName);
  // first count them
  count = 0;
  while (true) 
  {
            char line[100];
            countingStream.getline(line, 100);
            if (strlen(line) == 0) 
            {
                  break;
            }
            count += 1;
  }
  countingStream.close();

  ifstream readingStream(fileName);
  char** words = new char* [count];

  for (int index = 0; index < count; ++index) 
  {
            char line[100];
            readingStream.getline(line, 100);
            words[index] = strdup(line);
            cout << line << std::endl;
  }
  readingStream.close();
  return words;
}

char** arrayCopy(char* words[], int& count)
{
      
      char** keyArray = new char* [count];
      for (int index = 0; index < count; ++index)
      {
            keyArray[index] = strdup(words[index]);
      } 

      return keyArray;
}

void getKeys(char* keys[], int& count)
{
      int length=0;
      for (int keyIndex = 0; keyIndex < count; ++keyIndex) 
      {
            length =strlen(keys[keyIndex]);
            bubbleSortKeys(keys[keyIndex], length);
            cout << keys[keyIndex] <<endl; 
      } 


}

void bubbleSortKeys (char *array , int count)
{
      char tempHold;

      for (int pass = 0; pass < count - 1; pass++)
      
             for (int compare = 0; compare < count - 1; compare++)

                   if (array[compare - 1] > array[compare])
                   {
                        tempHold = array[compare - 1];
			            array[compare - 1] = array[compare];
			            array[compare] = tempHold;
   		           }
}

void findDuplicates(char* keys[],char* words[], int& count)
{
      
      for (int keyIndex = 1; keyIndex < count; ++keyIndex) 
      {
            if (strcmp(keys[keyIndex -1],  keys[keyIndex])==0)
            {
                  cout << keys[keyIndex] << "  " << words[keyIndex]<< endl;
                  cout << keys[keyIndex-1] << "  " << words[keyIndex-1]<< endl;
            }            
      } 
}

void printArray(char* keys[],char* words[], int& count)
{
      cout <<" Keys array" << endl;
      for (int keyIndex = 0; keyIndex < count; keyIndex++) 
            cout << keys[keyIndex] << endl;
}
int main ()
{
      int wordCount;
      char** words = read("words.txt",wordCount);
      char** keys = arrayCopy(words,wordCount);
      getKeys(keys,wordCount);
      findDuplicates(keys,words,wordCount);
      printArray(keys,words,wordCount);      
      return 0;

}
Member Avatar for iamthwee

It would be easier to sort using std::strings...

for (int compare = 0; compare < count - 1; compare++)
{
    if (array[compare - 1]

While the above code is syntactically correct it will produce a runtime error since compare - 1 will be -1 when compare is zero, and -1 is out of bounds for array indexes.

for (int compare = 0; compare < count - 1; compare++)

The above code has a logic error in that you'll never be able to assess the last letter in array.
See if this makes more sense:

for (int pass = 0; pass < count - 1; pass++)
{     
   for (int compare = pass + 1; compare < count; compare++)

and replace every index written as compare - 1 with pass.

I had already implemented the change after I submitted the thread but I keep getting the following errors:

error C2440: '=' : cannot convert from 'char *' to 'char'
error C2440: '=' : cannot convert from 'char' to 'char *'

Those errors are in the BubbleSort Array code.

I am still having problems with this program. It prints the list of words with each word in alphabetical order ( i.e. word is listed as dorw). However, I still don't get the desired output of the anagrams such as

deal lead
form from

Can anybody tell me what I am missing?

#include <iostream>
#include <fstream>

using namespace std;

char** read(const char* fileName, int& count);
char** buildArray(char* words[], int& count);
void getKeys(char* keys[], int& count);
void bubbleSortKeys (char *arrayKey , int count);
void findDuplicate(char* keys[],char* words[], int& count);
void displayArray(char* keys[],char* words[], int& count);

int main ()
{
      int wordCount;

      char** words = read("words.txt",wordCount);
	  char** keys = buildArray(words, wordCount);
	  getKeys(keys, wordCount);
	  findDuplicate(keys, words, wordCount);
	  displayArray(keys, words, wordCount);

      return 0;
}
char** read(const char* fileName, int& count)
{
  ifstream countingStream(fileName);
  // first count them
  count = 0;
  while (true) 
  {
            char line[100];
            countingStream.getline(line, 100);
            if (strlen(line) == 0) 
            {
                  break;
            }
            count += 1;
  }
  countingStream.close();

  ifstream readingStream(fileName);
  char** words = new char* [count];

  for (int index = 0; index < count; ++index) 
  {
            char line[100];
            readingStream.getline(line, 100);
            words[index] = strdup(line);
            cout << words[index] << endl;
  }
  readingStream.close();
  return words;
}

char** buildArray(char* words[], int& count)
{
	char** keyArray = new char*[count];
	for(int index = 0; index < count; ++index)
	{
		keyArray[index] = strdup(words[index]);
	}
	return keyArray;
}

void getKeys(char* keys[], int& count)
{
	int length = 0;

	for(int keyIndex = 0; keyIndex < count; ++keyIndex)
	{
		length = strlen(keys[keyIndex]);
		bubbleSortKeys(keys[keyIndex], length);
	}
}
void bubbleSortKeys (char *arrayKey , int count)
{
      char wordHold;

      for (int pass = 0; pass < count - 1; pass++)
      
             for (int compare = pass + 1; compare < count; compare++)

                   if (arrayKey[pass] > arrayKey[compare])
                   {
                        wordHold = arrayKey[pass];
			            arrayKey[pass] = arrayKey[compare];
			            arrayKey[compare] = wordHold;
   		           }
}

void findDuplicate(char* keys[],char* words[], int& count)
{
      
      for (int keyIndex = 1; keyIndex < count; ++keyIndex) 
      {
            if (strcmp(keys[keyIndex -1],  keys[keyIndex])==0)
            {
                  cout << keys[keyIndex] << "  " << words[keyIndex]<< endl;
                  cout << keys[keyIndex-1] << "  " << words[keyIndex-1]<< endl;
            }            
      } 
}

void displayArray(char* keys[],char* words[], int& count)
{      
       for (int keyIndex = 0; keyIndex < count; keyIndex++) 
            cout << keys[keyIndex] << endl;
}

If you want to display the words as well, you'll have to reference the words[] array in the cout line, e.g.:

void displayArray(char* keys[],char* words[], int& count)
{      
       for (int keyIndex = 0; keyIndex < count; keyIndex++) 
            cout << keys[keyIndex] << " " << words[keyIndex] << endl;
}

You haven't done your alphabetic sorting of the keys yet either; I guess you should do that before you display them...

I thought I sorted the keys in the bubbleSortKeys function. Do I need to include another function to sort the words too?

Oh, sorry. Yes you have sorted the letters in the keys. I read the above to mean you had to sort the array of keys.

The changes to displayArray() still stand. The reason you are getting:
word1
word2
key1
key2

is that you are printing the words out as you read them from the file (hence word1, word2), and then displaying only the keys (hence key1, key2).

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.