public RuleGuesser(String[] dictionary, double[] freqCoefficients, Levenshtein matcher) {
		this.dictionary = dictionary;
		this.freqCoefficients = freqCoefficients;
		this.matcher = matcher;
		
		dictionarySet = new HashSet<String>();
		for (String word: dictionary) {
			dictionarySet.add(word);
		}
		
		alphaTranslationTable = new int[256];
		// Initialize the translation table for k-gram indexing, using fixed alphabet.
		// The apostrophe, #26, is an all-purpose code for nonalphabetic characters.
		for (int i = 0; i < 256; ++i) {
			alphaTranslationTable[i] = 26;
		}
		// Now assign characters in the alphabet.
		for (int i = 0; i < alphabet.length(); ++i) {
			int ascii = (int) alphabet.charAt(i);
			alphaTranslationTable[ascii] = i;
			if (i < 26) {
				// Upper-case equivalent for alphabetic characters.
				int upper = ascii - 32;
				alphaTranslationTable[upper] = i;
			}
		}
		
		// Now we create a list of lists of hashsets, containing integers.
		bigramIndex = new ArrayList<ArrayList<HashSet<Integer>>>();
		for (int i = 0; i < 28; ++i) {
			ArrayList<HashSet<Integer>> aListOfSets = new ArrayList<HashSet<Integer>>();
			for (int j = 0; j < 28; ++j) {
				HashSet<Integer> wordsContainingBigramIJ = new HashSet<Integer>();
				aListOfSets.add(wordsContainingBigramIJ);
			}
			bigramIndex.add(aListOfSets);
		}
		
		dictBigramCount = new int[dictionary.length];
		for (int i = 0; i < dictionary.length; ++i) {
			String word = "$" + dictionary[i] + "$";
			HashSet<String> bigrams = new HashSet<String>();
			for (int j = 1; j < word.length(); ++ j) {
				String bigram = word.substring(j - 1, j + 1);
				bigrams.add(bigram);
				int gram1 = bigramcode(word.charAt(j - 1));
				int gram2 = bigramcode(word.charAt(j));
				ArrayList<HashSet<Integer>> listOfSets = bigramIndex.get(gram1);
				HashSet<Integer> setOfWords = listOfSets.get(gram2);
				setOfWords.add(i);
			}
			dictBigramCount[i] = bigrams.size();
		}	
	}