I\'m attempting to write a program that will generate a text file with every possible permutation of the alphabet from one character up to twenty-nine characters. I\'ve chosen 2
Here is a simple untested program in C++ that creates the words by counting in Base 26:
#include <string>
#include <iostream>
int main(void)
{
//----------------------------------------------------------
// Print permuations of strings of letters up to length 5.
// Use base 26 arithmetic.
//----------------------------------------------------------
const unsigned int MAX_ITERATIONS = 26 * 26 * 26 * 26 * 26;
std::string word = "A";
for (unsigned int i = 0; i < MAX_ITERATIONS; ++i)
{
//------------------------------------------------------
// Print the word
//------------------------------------------------------
std::cout << word << std::endl;
//------------------------------------------------------
// Increment the word, using base 26 arithmetic.
// A, B, C, ..., Z.
// AA, BA, CA, ..., ZA, AB, BB, CB, DB, ..., ZZ.
// AAA, BAA, CAA, ..., ZAA, ABA, BBA, CBA, DBA, ..., ZZZ.
//------------------------------------------------------
bool carry_generated = false;
unsigned int digit = 0;
do
{
carry_generated = false;
if (word[digit] < 'Z')
{
++word[digit];
break;
}
word[digit++] = 'A';
if (word.length() == digit)
{
word += "A";
break;
}
carry_generated = true;
} while (carry_generated && (digit < 5));
}
return 0;
}
The number of words printed can be reduced by checking a word list (a.k.a. dictionary) before printing. If the word is in the word list, print it.
The biggest issue with a word length of 29 is representing the quantity. The quantity overflows the range of the standard C++ unsigned integers. A Big Int library would need to be used. The next issue is the time required to process every combination. Multiply the quantity by 1 microsecond per iteration (a kind of worse case) and reduce down to days, hours, minutes and seconds. Perhaps years may be required.
This is what I would do:
#include <iostream>
void printWords(std::string& word, int index, int last)
{
std::cout << word << "\n";
if (index != last)
{
for(char loop = 'a'; loop <= 'z'; ++loop)
{
word[index] = loop;
printWords(word, index+1, last);
}
word[index] = ' ';
}
}
int main()
{
std::string word(" "); // 29 space
printWords(word,0,word.length());
}
Here is a permutation generator written in java http://www.merriampark.com/perm.htm.
However as he mentions
//-----------------------------------------------------------
// Constructor. WARNING: Don't make n too large.
// Recall that the number of permutations is n!
// which can be very large, even when n is as small as 20 --
// 20! = 2,432,902,008,176,640,000 and
// 21! is too big to fit into a Java long, which is
// why we use BigInteger instead.
//----------------------------------------------------------
Since your n
is 29, you will be waiting a long, long time. It is too large, as EboMike is trying to tell you in his comments.
Obviously, the outer for loop is for the number of characters in your word. Then, you just create strings with that length. For length 5, you start with "AAAAA", then "AAAAB", "AAAAC".
Once you hit "Z", you go back and move the character to your left one up, i.e. "AAAAZ" becomes "AAABA", and "AAAZZ" becomes "AABAA". Once you hit "ZZZZZ", you're done with the inner loop, and the outer loop will then start with "AAAAAA".
A Java solution that should do the trick:
public void characterPermutations(int length, LinkedList<String> permutations) {
if(length > 1) {
characterPermutations(length - 1, permutations);
ListIterator<String> iterator = permutations.listIterator();
while(iterator.hasNext()) {
String permutation = iterator.next();
for(char c = 'a'; c <= 'z'; c++) {
iterator.add(c + permutation);
}
}
} else {
for(char c = 'a'; c <= 'z'; c++) {
permutations.add(c + "");
}
}
}
Even if you could store this on disk, like thirydot pointed out, you'd run out of time doing this.
Just generating (and not storing) all the 6-letter possiblilies took 24 seconds on my computer:
$ time perl letters.pl
real 0m24.837s
user 0m24.765s
sys 0m0.030s
Which is 7.7X10^-8s per word, That means it would take 8.4x10^33s or 2.6x10^26 years to do this.
You need to think more about your algorithm.