Pt 2: Howitt's Anagram Theory
Here is my code for the Anagram program so far:
public class Anagram {
String initialWord;
StringBuffer anagrams=new StringBuffer();
public Anagram(String word) {
//constructor for an anagram
this.initialWord = word;
}
public void makeAnagram (String separator) {
//to create an anagram call this method with the separator you wish to use
//in the resulting StringBuffer to separate words e.g. "<br>" for
web apps
anagrams.delete(0,anagrams.length());
makeAnagram("",this.initialWord,separator);
}
public String deleteAt(String word, int pos) {
//this method takes a string and returns the same string less the character
//at the position specified by the integer pos
if (pos > 0 && pos < word.length()-1) {
return word.substring(0,pos)+word.substring(pos+1,word.length());
} else {
if (pos==0) {
return word.substring(pos+1,word.length());
} else {
if (pos == word.length()-1) {
return word.substring(0,pos);
} else {
return word;
}
}
}
}
private void makeAnagram (String wordStart, String word, String separator) {
//this is the recursive method which actually generates the list of anagrams
//initially wordStart is the empty string but as it loops into the code it loops over
//all the possible word beginnings
String wordCopy = word;
for (int i = 0; i< word.length(); i++) {
//hide dupes: only run this word if it is the first instance of the letter in the word
if (word.indexOf(word.charAt(i)) == i) {
//remove the current character from the letters to be passed to the
//next recursion since we are adding it to the wordStart segment
wordCopy=deleteAt(word,i);
if (word.length() > 1) {
//complex case - current word is longer than 1 character so the current
//character is added to the wordStart segment
makeAnagram(wordStart + word.charAt(i),wordCopy,separator);
} else {
//trivial case - word length is 1 so only 1 permutation
if (anagrams.length() == 0) {
//our list shouldn't start with a list separator
anagrams.append(wordStart).append(word);
} else {
anagrams.append(separator).append(wordStart).append(word);
}
}
}
}
}
public int countInstances(String word, char letter) {
//this method determines how many copies of a specific character are in the string
int i=0;
while (word.indexOf(letter) >= 0) {
word=word.substring(word.indexOf(letter)+1,word.length());
i++;
}
return i;
}
public static double factorial(int x) {
// This method computes x!
if (x < 0)
return 0.0;
double fact = 1.0;
while(x > 1) {
fact = fact * x;
x = x - 1;
}
return fact;
}
public double calcAnagram () {
//This method uses my theory - Howitt's Anagram Theory to calculate the number
//of unique permutations possible for the given words.
//THEORY: UniquePermutations = factorial(word.length)
// divided by the product of the factorials of the count of instances of each
// letter in the word. e.g. aabbbc would be 6!/(2!*3!*1!) = 720/(2*6*1) = 60
String word = this.initialWord;
double factSum = 1;
for (int i = 0; i< word.length(); i++) {
if (word.indexOf(word.charAt(i)) == i) {
factSum = factSum * factorial(countInstances(word,word.charAt(i)));
}
}
return factorial(word.length())/factSum;
}
}
Here is the code to test it:
public class TestAnagram {
public static void main(String[] args) {
Anagram words = new Anagram(args[0]);
String separator;
//if a "y" is passed as a second variable, then display the anagrams else don't
//if a 3rd argument is supplied, it is used as the separator to display the anagrams
if (args.length >= 2 && args[1].indexOf("y")>=0) {
if (args.length >= 3) {
separator = ",";
} else {
separator = "<BR>";
}
words.makeAnagram(separator);
System.out.println(words.anagrams);
}
System.out.println(words.calcAnagram());
}
}