/************************************************************************ **** Nicholas Erho **** OWNAGE.CA ****** C++ **** December 14, 2004 **** ************************************************************************ * Anagram Finder * ************************************************************************ * This program is designed to load a word list file compare every word * * in the word list file with every other word and determine the * * anagrams of the word and outout them to a file. * * NOTE: For long word lists such as 81000 words this program can take * * a considerable amount of time to complete. * ************************************************************************ * If you make any improvements which I am sure their are lots; I would * * love to see what you have done. So email me @ nicholaserho@ownage.ca * ************************************************************************/ #include // General input and output. #include // This is going to be used to capitalize chars with the 'toupper' function. #include // Casing to stings. #include // Used to get access to the filestream. using namespace std; // This function determines if string 1 and string 2 conatain the exact same characters elements, where order does not matter. bool isanagram(string str1, string str2){ register string tempstr1 = str1; // Fuction works on temp strings of 1 and 2 so that origional strings are left untouched. register string tempstr2 = str2; if (tempstr1 == tempstr2){ // False because exactly the same word which violates the definition of an anagram. return false; } int strlen1 = str1.length(); int strlen2 = str2.length(); if (strlen1 != strlen2){ //False because of wrong string length and therefor can not contain the exact same elements. return false; } else{ for (int i = 0; i <= strlen1-1; i++){ // runs though every char in the string1 array. int j = 0; bool kill_loop = false; do{ if (j > (strlen2-1)){ // False because missing common character. return false; } if ((toupper(tempstr1[i]) == toupper(tempstr2[j])) && ((tempstr1[i] != '*') || (tempstr2[i] != '*'))){ tempstr1[i] = '*'; // insure that duplicate letters are not repeated tempstr2[j] = '*'; kill_loop = true; // Exits the infinte loop if a match is found. } j++; }while(!kill_loop); } return true; // If all of the above is not false, then the strings must be anagrams. } } int main(void){ const int listsize = 81000; // Size of word list. int number = 0; // number of anagram collections writen to the file. string wordlist[listsize]; // An array holding the entire list of words. NOTE: This is a BIG array and the stack may have to be increased. ifstream infile("wordlist.txt", ios::in); // Opens the wordlist text file for read. if (!infile){ // Error if file could not be opened. cerr << "This file could not be opened for read access." << endl; exit(1); // Kill program cause there is no point going on. } for (int i = 0; i <= listsize; i++){ // Run though the entire word list, this could probably be done better with dynamic means. if (!(infile >> wordlist[i])){ wordlist[i] = ""; // Since 81000 is just a bit bigger than the word list it fills in the empty words with blanks. See above comment. } } infile.close(); // Since all the words are stored in the array, no need for this file to be open. ofstream outfile("anagramfile.txt", ios::out); // Open the output file. if (!outfile){ // Again if the file could not be opened display error message. cerr << "This file could not be opened for write access." << endl; exit(2); // Kill program cause if the file is not open there is no point going on. } // Display a header in the text file. outfile << "************************************************************************\n" "**** Nicholas Erho **** OWNAGE.CA ****** C++ **** December 14, 2004 ****\n" "************************************************************************\n" "* Anagram Finder *\n" "************************************************************************\n" "* This file contains a list of anagrams generated from a wordlist file *\n" "* using the Anagram Finder program. *\n" "************************************************************************" << endl; cout << "Percent done... " << endl; for (register int j = 0; j <= listsize; j++){ if ((j % 4050) == 0){ // Used 4050 just because that is exactly 5% of 81000 any number could be used. cout << (float(j)/listsize)*100 << "%... " << endl; // Prints the precent completed. } int anagramnumber = 0; // Number of anagrams in each anagram collection. for (register int k = 0; k <= listsize; k++){ // Runs though the word list looking for anagrams of the given word in wordlist[j]. if (isanagram(wordlist[j], wordlist[k])){ // If new anagram found. anagramnumber++; if (anagramnumber == 1){ // if first anagram found. outfile << number++ << ". " << wordlist[j] << " " << wordlist[k]; } else{ // If not first anagram found. outfile << " " << wordlist[k]; } wordlist[k] = ""; // Deletes the word from the word list so no duplicate anagrams are printed. } } if (anagramnumber > 0){ outfile << endl; } wordlist[j] = ""; // Deletes the intial word from the word list so again no duplicate anagrams are printed. } outfile.close(); // Closes the file output file. return 0; // Kills the program. }