Anagram Solver/ Word jumbler

Pages: 12
Aug 15, 2011 at 4:15pm
Hi,
I am working on a Word Jumble, which will hopefully be turned into an anagram solver. I just have two questions. If i have the user input a string such as "apple" how do i have it split it into 5 different letters and jumble them into a different order. Secondly is how do i jumble the letters? I have read the page on the Next Permutation command, but it didnt make any sense to me. Can anyone explain how to use it or give me a different method.
Thanks
Joel
Aug 15, 2011 at 5:49pm
Strings are character arrays. You get nth char with mystring[n]. Same works when mystring is an std::string.

To shuffle, use the method here: http://en.wikipedia.org/wiki/Fisher–Yates_shuffle or a function (implemented the same way) random_shuffle from <algorithm> header.
Aug 15, 2011 at 6:57pm
could you please provide a simple example of it? also could you please help with the sort command too? Im using the h.file <algorithm> but i use sort and it says that sort is not defined in this scope.

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include <algorithm>

int main()
{ 
	int list[] = {2,5,1,3,4};
	
	
	sort (list);
	
	std::cout << list;
	return 0;
}
Aug 15, 2011 at 7:21pm
sort (like random_shuffle and most other functions in <algorithm> ) takes two arguments. One is an iterator (pointer) to the first element of your container (array) and the other is an iterator (pointer) to one element past the last element of your container (array). So the arguments you'd put them in your example are sort( list, list+5 );.
Aug 15, 2011 at 7:34pm
I still have the error, that sort is not declared in this scope, when i try to compile it...
Aug 15, 2011 at 7:38pm
I have changed my code to this

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include <algorithm>

int main()
{ 
	int list[] = {2,5,1,3,4};
	
	
	std::sort (list, list+5);
	
	std::cout << list;
	return 0;
}

(i added the std:: infront of sort)

and now i dont get an error, but my output is this

0xbfc83b0c
Aug 15, 2011 at 7:59pm
Now your printing the address of the memory where your array begins. To print the elements, you need a for loop.
Aug 15, 2011 at 8:13pm
what would i need the parameters to be for the for loop?
Aug 15, 2011 at 9:09pm
Okay I wrote out some of this to get an idea how to explain the method.
You need to have a swap function and a function for the scrambling:

1
2
void swap (char &a, char &b);
std::string str_scramble (const std::string &old_str);


Basically, get two random numbers from 0 to str.length().
Then swap their positions in an array or std::string.
Repeat as many times as you want (which means you'll need a counter as well to stop the loop, as well as constantly generate new random numbers).
Print scrambled word or store it for later use.

The loop should just run for a number of times. I suggest a multiple of the length of the word. Maybe 200 loops for each letter.
Last edited on Aug 15, 2011 at 9:25pm
Aug 16, 2011 at 5:05am
so i should have it swap random letters in my string so many times, that all the possibilities will be there?
Aug 16, 2011 at 6:33am
The for loop would be for( int i = 0; i < 5; i++ ) cout << list[i];

As for the algorithm, swapping random values is the point, though if you did as my link suggested, you'd only need N swaps. There is pseudocode, so you shouldn't have any problems writing it..
Aug 16, 2011 at 7:01am
Thankyou :)

The code i have so far is this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <ctime>

int main()
{ 
 srand ( time(NULL) );

 int x = rand() % 4+1;
 int y = rand() % 4+1;
 std::string myString = "sony";
 std::cout << "myString is " << myString.length() << " characters long\n";

 swap (myString[0], myString[3]);
 std::cout << myString << endl;
}


Im working on an online compiler, because im not using my own comp, but i plan on making x & y the 2 places that i swap in the word, and i plan on replacing the word with something that the user inputs. I also plan on making a for loop that will print out the new jumbled word (and eventually have it read a file and check to see if any of the new jumbles are a word to make it an anagram solver) :)

Ill let you know how it goes!
Joel
Aug 17, 2011 at 8:08pm
Hey,
everything is going well, except i ran into a little problem with an if statement:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>
#include <algorithm>
#include <string>
#include <ctime>

int main()
{ 
 srand ( time(NULL) );
 
	std::string myString;	
	std::cin >> myString;	// input your word
	int length = myString.length(); //used to find permutations line16
	int fact = 1; // number of permutations
	int arrayNum = 0; // used to know what array slot to use line24
	
	 while (length > 1) //finds the number of permutations possible
{
 fact = fact*length;
 length--;
 std::cout << fact << "\n";
}

	std::string array[fact];
	array[arrayNum] = myString;
	arrayNum ++; // so the next input will be a different slot
	
	while (arrayNum < fact)
	{
	std::swap (myString[rand() % myString.length()], myString[rand() % myString.length()]);
		if (myString != array[1] && myString != array[2] && myString != array[3] && myString != array[4] && myString != array[5])
		{
		array[arrayNum] = myString;
		arrayNum++;
		}
		else 
		continue;
	}
	
	int elements = sizeof(array) / sizeof(array[0]); 	// outputs array
	for (int i = 0; i < elements; ++i)					
	std::cout << array[i] << " ";						
		

}


line 30 is supposed to make it so that it wont be able to put the same string into a new slot, however when i run i still get repeats... any advice?
Aug 18, 2011 at 7:26am
On line 30 you're forgetting that arrays start from 0. Also, you should be using a for loop for this. You don't know whether you'll have 6 elements in array.

Also, std::string array[fact]; is not legal in C++. Using a variable for the size of a static array was fine in C. Some C++ compilers allow it, some don't. You should be using std::string* array = new std::string[fact];. Don't forget to delete it later.
Aug 18, 2011 at 8:10pm
I understand what i have done wrong with the if function, thanks. Could you please explain how
std::string* array = new std::string[fact];
works? What is the astrix for after the first string? Is it saying make a new string "array" that equals a new string that is an array?
Thankyou
Joel
Aug 18, 2011 at 8:38pm
Two things. With the
std::string* array = new std::string[fact];
it isnt adding anything new to the array. also is there a way to check the entire array for 1 thing, instead of searching each individual element?
Aug 19, 2011 at 6:04am
That * means a pointer. If you haven't learned them yet, I guess it's fine if you go back to the variable length array..
As for searching, instead of the usual for loop, you could http://www.cplusplus.com/reference/algorithm/find/
Aug 20, 2011 at 8:15am
Hey,
I have a couple of chapters to read before i get to pointers in the C++ book i have. I got my code to work up to 4 letters, but i think that the code just takes to long when i get to 5 or more...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <iostream>
#include <algorithm>
#include <string>
#include <ctime>

int main()
{ 
 srand ( time(NULL) );
 
	std::string myString;	
	std::cin >> myString;	// input your word
	int length = myString.length(); //used to find permutations line16
	int fact = 1; // number of permutations
	int arrayNum = 0; // used to know what array slot to use line24
	int checkRepeat;
	int counter;
	
	 while (length > 1) //finds the number of permutations possible
{
 fact = fact*length;
 length--;
 std::cout << fact << "\n";
}

	std::string array[fact];
	array[arrayNum] = myString;
	arrayNum ++; // so the next input will be a different slot
	
	while (arrayNum < fact)
	{
		checkRepeat = 0;
	std::swap (myString[rand() % myString.length()], myString[rand() % myString.length()]);
	
		for (counter = 0; counter < fact; counter++)
		{
			if (myString == array[counter])// counter increases so it checks until counter = fact
			{
			checkRepeat++; // used to know if there is a repeat
			}
		}
		
	if (checkRepeat < 1) // if checkRepeat is less than 1 then no repeats
		{
		array[arrayNum] = myString;
		arrayNum++;
		}
	}
	
	
	int elements = sizeof(array) / sizeof(array[0]); 	// outputs array
	for (int i = 0; i < elements; ++i)					
	std::cout << array[i] << " ";	
	
	return 0;					
		

}


its kind of a spaghetti code at the moment, but i tried to put in comments so you could understand. when i learn more about pointers, ill try using the find fuction you showed me. :)
Aug 20, 2011 at 8:41am
This is a bad idea. You aren't searching for permutations, you're just shuffling and expecting to find them all. This could take forever. There are better methods to find all permutations of a set.
See http://en.wikipedia.org/wiki/Permutation#Systematic_generation_of_all_permutations
If you don't want to write this yourself, even though it shouldn't be hard, use http://www.cplusplus.com/reference/algorithm/next_permutation/
Aug 20, 2011 at 3:38pm
The random shuffling method isn't really a good idea. I wrote an anagram solver once that worked pretty fast.

Essentially you read the acceptable words into an array, and the shuffled words into another array.

Then what you do is check if the length of the shuffled word is the same as one word from the list.

If so, then check if all the character are present, you do this by reading the shuffled word character into a vector, and for each match you delete said character from the vector.

Then at the end you check if the vector is empty.

When I tested it out it worked.

:)
Pages: 12