import java.io.BufferedInputStream;
import java.io.DataInputStream;
//import java.io.FileInputStream;
public class Cwg {
private static final int MAX = 15;
private static final int LOWER_IT = 32;
private static final int VALID_CHAR_RANGE_SIZE = 'Z' - '?' + 1;
private static final int EOW_FLAG = 0X40000000;
private static final int LIST_FORMAT_INDEX_MASK = 0X3FFE0000;
private static final int LIST_FORMAT_BIT_SHIFT = 17;
private static final int CHILD_MASK = 0X0001FFFF;
private static final int powersOfTwo[] = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384,
32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432 };
private static final int[] childListMasks = { 0X0, 0X1, 0X3, 0X7, 0XF, 0X1F, 0X3F, 0X7F, 0XFF, 0X1FF, 0X3FF, 0X7FF, 0XFFF,
0X1FFF, 0X3FFF, 0X7FFF, 0XFFFF, 0X1FFFF, 0X3FFFF, 0X7FFFF, 0XFFFFF, 0X1FFFFF, 0X3FFFFF, 0X7FFFFF, 0XFFFFFF, 0X1FFFFFF };
private static final byte[] popCountTable = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4,
4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3,
3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5,
5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3,
3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5,
5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6,
6, 7, 6, 7, 7, 8 };
// CWG format and array-size variables.
private int totalNumberOfWords;
private int nodeArraySize;
private int listFormatArraySize;
private int root_WTEOBL_ArraySize;
private int short_WTEOBL_ArraySize;
private int byte_WTEOBL_ArraySize;
// The 5 CWG arrays.
private int theNodeArray[];
private int theListFormatArray[];
private int theRoot_WTEOBL_Array[];
private short theShort_WTEOBL_Array[];
private byte theByte_WTEOBL_Array[];
// The "Cwg" class-constructor.
public Cwg() throws Exception {
int x;
DataInputStream cwgDataFile = new DataInputStream(new BufferedInputStream(getClass().getResourceAsStream("CWG_Data_For_Word-List.dat")));
//DataInputStream cwgDataFile = new DataInputStream(new BufferedInputStream(new FileInputStream("CWG_Data_For_Word-List.dat")));
totalNumberOfWords = endianIntConversion(cwgDataFile.readInt());
nodeArraySize = endianIntConversion(cwgDataFile.readInt());
listFormatArraySize = endianIntConversion(cwgDataFile.readInt());
root_WTEOBL_ArraySize = endianIntConversion(cwgDataFile.readInt());
short_WTEOBL_ArraySize = endianIntConversion(cwgDataFile.readInt());
byte_WTEOBL_ArraySize = endianIntConversion(cwgDataFile.readInt());
theNodeArray = new int[nodeArraySize];
theListFormatArray = new int[listFormatArraySize];
theRoot_WTEOBL_Array = new int[root_WTEOBL_ArraySize];
theShort_WTEOBL_Array = new short[short_WTEOBL_ArraySize];
theByte_WTEOBL_Array = new byte[byte_WTEOBL_ArraySize];
for (x = 0; x < nodeArraySize; x++) {
theNodeArray[x] = endianIntConversion(cwgDataFile.readInt());
}
for (x = 0; x < listFormatArraySize; x++) {
theListFormatArray[x] = endianIntConversion(cwgDataFile.readInt());
}
for (x = 0; x < root_WTEOBL_ArraySize; x++) {
theRoot_WTEOBL_Array[x] = endianIntConversion(cwgDataFile.readInt());
}
for (x = 0; x < short_WTEOBL_ArraySize; x++) {
theShort_WTEOBL_Array[x] = endianShortConversion(cwgDataFile.readShort());
}
for (x = 0; x < byte_WTEOBL_ArraySize; x++) {
theByte_WTEOBL_Array[x] = cwgDataFile.readByte();
}
cwgDataFile.close();
}
private int endianIntConversion(int thisInteger) {
return ((thisInteger & 0x000000ff) << 24) + ((thisInteger & 0x0000ff00) << 8) + ((thisInteger & 0x00ff0000) >>> 8) + ((thisInteger & 0xff000000) >>> 24);
}
private short endianShortConversion(short thisShort) {
return (short)(((thisShort & 0x00ff) << 8) + ((thisShort & 0xff00) >>> 8));
}
private String searchForStringRecurse(String thisString, int position, int thisIndex, String[] nodePrint, boolean[] result, int[] nodeCount) {
char thisChar = thisString.charAt(position);
int thisChildListFormat;
nodeCount[0] += 1;
nodePrint[position] = "'" + thisChar + "' @ |" + thisIndex +"|";
String addThisMessage = "";
if ( thisString.length() == (position + 1) ) {
if ( (theNodeArray[thisIndex] & EOW_FLAG) != 0 ) {
result[0] = true;
nodePrint[position] += "- found " + (char)0X2713 + "";
for ( int x = position + 1; x < MAX; x++ ) nodePrint[x] = "";
return addThisMessage;
}
else {
result[0] = false;
nodePrint[position] += "- lost EOW";
for ( int x = position + 1; x < MAX; x++ ) nodePrint[x] = "";
return (addThisMessage + "\nWord Lost\n");
}
}
else {
thisChar = thisString.charAt(position + 1);
if ( (theNodeArray[thisIndex] & CHILD_MASK) != 0 ) {
thisChildListFormat = theListFormatArray[(theNodeArray[thisIndex] & LIST_FORMAT_INDEX_MASK)>>>LIST_FORMAT_BIT_SHIFT];
if ( (thisChildListFormat & powersOfTwo[thisChar - 'A']) != 0 ) {
nodePrint[position] += "- found '" + thisChar + "' child";
return (addThisMessage + searchForStringRecurse(thisString, position + 1, (theNodeArray[thisIndex] & CHILD_MASK) + listFormatPopCount(thisChildListFormat, thisChar - 'A'), nodePrint, result, nodeCount));
}
}
result[0] = false;
nodePrint[position] += "- lost '" + thisChar + "' child";
for ( int x = position + 1; x < MAX; x++ ) nodePrint[x] = "";
return (addThisMessage + "\n'" +thisChar + "' Is a missing child in position |" + (position + 2) + "|\n\nWord Lost\n");
}
}
public String searchForString(String toSearchFor, String[] nodeCheck, boolean[] theResult, int[] theCount) {
String holder;
String upperString = toSearchFor.toUpperCase();
String traversalResult = new String("Searching for: |" + upperString + "| - ");
theCount[0] = 0;
holder = searchForStringRecurse(upperString, 0, (upperString.charAt(0) - 'A' + 1), nodeCheck, theResult, theCount);
if ( theResult[0] ) traversalResult += "Word Found " + (char)0X2713;
else traversalResult += "Word Not Found.\n";
traversalResult += holder;
return traversalResult;
}
private String hashStringRecurse(String thisString, int position, int thisIndex, String[] nodePrint, int[] currentMarker, int[] nodeCount) {
char thisChar = thisString.charAt(position);
int thisChildListFormat;
nodeCount[0] += 1;
nodePrint[position] = "'" + thisChar + "' @ |" + thisIndex +"|";
String addThisMessage = new String();
if ( (theNodeArray[thisIndex] & EOW_FLAG) != 0 ) currentMarker[0] -= 1;
nodePrint[position] += " Mark-[ " + (totalNumberOfWords - currentMarker[0]) + " ]";
if ( thisString.length() == (position + 1) ) {
if ( (theNodeArray[thisIndex] & EOW_FLAG) != 0 ) {
nodePrint[position] += " " + (char)0X2713 + "";
for ( int x = position + 1; x < MAX; x++ ) nodePrint[x] = "";
return addThisMessage;
}
else {
currentMarker[0] = totalNumberOfWords;
nodePrint[position] += " X";
for ( int x = position + 1; x < MAX; x++ ) nodePrint[x] = "";
return (addThisMessage + "\nWord Lost\n");
}
}
else {
thisChar = thisString.charAt(position + 1);
if ( (theNodeArray[thisIndex] & CHILD_MASK) != 0 ) {
thisChildListFormat = theListFormatArray[(theNodeArray[thisIndex] & LIST_FORMAT_INDEX_MASK)>>>LIST_FORMAT_BIT_SHIFT];
if ( (thisChildListFormat & powersOfTwo[thisChar - 'A']) != 0 ) {
thisIndex = theNodeArray[thisIndex] & CHILD_MASK;
if ( thisIndex < short_WTEOBL_ArraySize ) {
currentMarker[0] -= theShort_WTEOBL_Array[thisIndex];
thisIndex += listFormatPopCount(thisChildListFormat, thisChar - 'A');
currentMarker[0] += (theShort_WTEOBL_Array[thisIndex] & 0XFFFF);
}
// When reading "theByte_WTEOBL_Array", it is necessary to mask the values with "0XFF" to cast them as unsigned.
else {
currentMarker[0] -= (theByte_WTEOBL_Array[thisIndex - short_WTEOBL_ArraySize] & 0XFF);
thisIndex += listFormatPopCount(thisChildListFormat, thisChar - 'A');
currentMarker[0] += (theByte_WTEOBL_Array[thisIndex - short_WTEOBL_ArraySize] & 0XFF);
}
return (addThisMessage + hashStringRecurse(thisString, position + 1, thisIndex, nodePrint, currentMarker, nodeCount));
}
}
currentMarker[0] = totalNumberOfWords;
nodePrint[position] += " X";
for ( int x = position + 1; x < MAX; x++ ) nodePrint[x] = "";
return (addThisMessage + "\n'" +thisChar + "' Is a missing child in position |" + (position + 2) + "|\n\nWord Lost\n");
}
}
public String hashString(String toSearchFor, String[] nodeCheck, int[] hashResult, int[] theCount) {
String holder;
String upperString = toSearchFor.toUpperCase();
String traversalResult = new String("Look for: |" + upperString + "| - ");
theCount[0] = 0;
hashResult[0] = theRoot_WTEOBL_Array[upperString.charAt(0) - 'A' + 1];
holder = hashStringRecurse(upperString, 0, (upperString.charAt(0) - 'A' + 1), nodeCheck, hashResult, theCount);
hashResult[0] = totalNumberOfWords - hashResult[0];
if ( hashResult[0] != 0 ) {
traversalResult += "Word Found @ [" + hashResult[0] + "]\n";
}
else traversalResult += "Word Not Found.\n";
traversalResult += holder;
return traversalResult;
}
private String booleanAnagramRecurse(int thisIndex, char thisChar, char[] fuckWithMe, int fillThisPosition, char[] characterBank, int sizeOfBank, int[] wordCounter, int[] nodeCounter) {
String holder;
String wordAccumulator = "";
char currentChar;
boolean[] theUsedChars = new boolean[VALID_CHAR_RANGE_SIZE];
int firstChildIndex = (theNodeArray[thisIndex] & CHILD_MASK);
int theChildListFormat;
for ( int x = 0; x < VALID_CHAR_RANGE_SIZE; x++ ) theUsedChars[x] = false;
fuckWithMe[fillThisPosition] = thisChar;
nodeCounter[fillThisPosition] += 1;
if ( (theNodeArray[thisIndex] & EOW_FLAG) != 0 ) {
wordCounter[0] += 1;
wordAccumulator = new String(fuckWithMe, 0, fillThisPosition + 1);
wordAccumulator = "|" + wordCounter[0] + "| - " + wordAccumulator;
if ( sizeOfBank == 0 ) wordAccumulator += " ********->\n";
else wordAccumulator += "\n";
}
if ( (sizeOfBank != 0) && (firstChildIndex != 0) ) {
theChildListFormat = theListFormatArray[(theNodeArray[thisIndex] & LIST_FORMAT_INDEX_MASK)>>>LIST_FORMAT_BIT_SHIFT];
for ( int x = 0; x < sizeOfBank; x++ ) {
currentChar = characterBank[x];
if ( theUsedChars[currentChar - '?'] == true ) continue;
if ( currentChar == '?' ) {
removeCharFromArray(characterBank, x, sizeOfBank);
for ( int y = 'A'; y <= 'Z'; y++ ) {
if ( (theChildListFormat & powersOfTwo[y - 'A']) != 0 ) {
holder = booleanAnagramRecurse(firstChildIndex + listFormatPopCount(theChildListFormat, y - 'A'), (char)(y + LOWER_IT), fuckWithMe, fillThisPosition + 1, characterBank, sizeOfBank - 1, wordCounter, nodeCounter);
wordAccumulator += holder;
}
}
insertCharIntoArray(characterBank, x, currentChar, sizeOfBank);
theUsedChars[currentChar - '?'] = true;
}
else if ( (theChildListFormat & powersOfTwo[currentChar - 'A']) != 0 ) {
removeCharFromArray(characterBank, x, sizeOfBank);
holder = booleanAnagramRecurse(firstChildIndex + listFormatPopCount(theChildListFormat, currentChar - 'A'), currentChar, fuckWithMe, fillThisPosition + 1, characterBank, sizeOfBank - 1, wordCounter, nodeCounter);
wordAccumulator += holder;
insertCharIntoArray(characterBank, x, currentChar, sizeOfBank);
theUsedChars[currentChar - '?'] = true;
}
}
}
return wordAccumulator;
}
public String booleanAnagram(boolean toSort, String toAnagram, String[] nodeCheck, int[] numberOfWords, int[] theNodeCounts) {
String holder;
String upperAnagramString = toAnagram.toUpperCase();
String traversalResult = "";
int numberOfLetters = upperAnagramString.length();
char[] inputCharArray = upperAnagramString.toCharArray();
char[] workingCharArray = new char[MAX];
char currentChar;
boolean[] usedChars = new boolean[VALID_CHAR_RANGE_SIZE];
if ( toSort ) java.util.Arrays.sort(inputCharArray);
for ( int x = 0; x < VALID_CHAR_RANGE_SIZE; x++ ) usedChars[x] = false;
for ( int x = 0; x < numberOfLetters; x++ ) {
currentChar = inputCharArray[x];
if ( usedChars[currentChar - '?'] == true ) continue;
removeCharFromArray(inputCharArray, x, numberOfLetters);
if ( currentChar == '?' ) {
for ( int y = 'A'; y <= 'Z'; y++ ) {
holder = "-----------------------------\n";
holder += booleanAnagramRecurse(y - '@', (char)(y + LOWER_IT), workingCharArray, 0, inputCharArray, numberOfLetters - 1, numberOfWords, theNodeCounts);
traversalResult += holder;
}
}
else {
holder = "-----------------------------\n";
holder += booleanAnagramRecurse(currentChar - '@', currentChar, workingCharArray, 0, inputCharArray, numberOfLetters - 1, numberOfWords, theNodeCounts);
traversalResult += holder;
}
insertCharIntoArray(inputCharArray, x, currentChar, numberOfLetters);
usedChars[currentChar - '?'] = true;
}
for ( int x = 0; x < MAX; x++ ) {
nodeCheck[x] = "| " + theNodeCounts[x] + " |";
if ( theNodeCounts[x] != 0 )nodeCheck[x]+= " Nodes " + "" + (char)0X2713 + "";
}
traversalResult = "Anagramming this: |" + upperAnagramString + "|\nResults in |" + numberOfWords[0] + "| words.\n" + traversalResult;
return traversalResult;
}
private String hashAnagramRecurse(int thisIndex, int currentMarker, char thisChar, char[] fuckWithMe, int fillThisPosition, char[] characterBank, int sizeOfBank, int[] wordCounter, int[] nodeCounter) {
String holder;
String wordAccumulator = "";
char currentChar;
boolean[] theUsedChars = new boolean[VALID_CHAR_RANGE_SIZE];
int firstChildIndex = (theNodeArray[thisIndex] & CHILD_MASK);
int theChildListFormat;
int nextMarker;
boolean isChildShort;
for ( int x = 0; x < VALID_CHAR_RANGE_SIZE; x++ ) theUsedChars[x] = false;
fuckWithMe[fillThisPosition] = thisChar;
nodeCounter[fillThisPosition] += 1;
if ( (theNodeArray[thisIndex] & EOW_FLAG) != 0 ) {
currentMarker -= 1;
wordCounter[0] += 1;
wordAccumulator = new String(fuckWithMe, 0, fillThisPosition + 1);
wordAccumulator = "|" + wordCounter[0] + "| - " + wordAccumulator + " [ " + (totalNumberOfWords - currentMarker) + " ]";
if ( sizeOfBank == 0 ) wordAccumulator += " ********->\n";
else wordAccumulator += "\n";
}
if ( (sizeOfBank != 0) && (firstChildIndex != 0) ) {
isChildShort = ( firstChildIndex < short_WTEOBL_ArraySize ) ? true: false;
theChildListFormat = theListFormatArray[(theNodeArray[thisIndex] & LIST_FORMAT_INDEX_MASK)>>>LIST_FORMAT_BIT_SHIFT];
if ( isChildShort ) currentMarker -= theShort_WTEOBL_Array[firstChildIndex];
else currentMarker -= (theByte_WTEOBL_Array[firstChildIndex - short_WTEOBL_ArraySize] & 0XFF);
for ( int x = 0; x < sizeOfBank; x++ ) {
currentChar = characterBank[x];
if ( theUsedChars[currentChar - '?'] == true ) continue;
if ( currentChar == '?' ) {
removeCharFromArray(characterBank, x, sizeOfBank);
for ( int y = 'A'; y <= 'Z'; y++ ) {
if ( (theChildListFormat & powersOfTwo[y - 'A']) != 0 ) {
thisIndex = firstChildIndex + listFormatPopCount(theChildListFormat, y - 'A');
if ( isChildShort ) nextMarker = currentMarker + theShort_WTEOBL_Array[thisIndex];
// When reading "theByte_WTEOBL_Array", it is necessary to mask the values with "0XFF" to cast them as unsigned.
else nextMarker = currentMarker + (theByte_WTEOBL_Array[thisIndex - short_WTEOBL_ArraySize] & 0XFF);
holder = hashAnagramRecurse(thisIndex, nextMarker, (char)(y + LOWER_IT), fuckWithMe, fillThisPosition + 1, characterBank, sizeOfBank - 1, wordCounter, nodeCounter);
wordAccumulator += holder;
}
}
insertCharIntoArray(characterBank, x, currentChar, sizeOfBank);
theUsedChars[currentChar - '?'] = true;
}
else if ( (theChildListFormat & powersOfTwo[currentChar - 'A']) != 0 ) {
removeCharFromArray(characterBank, x, sizeOfBank);
thisIndex = firstChildIndex + listFormatPopCount(theChildListFormat, currentChar - 'A');
if ( isChildShort ) nextMarker = currentMarker + theShort_WTEOBL_Array[thisIndex];
// When reading "theByte_WTEOBL_Array", it is necessary to mask the values with "0XFF" to cast them as unsigned.
else nextMarker = currentMarker + (theByte_WTEOBL_Array[thisIndex - short_WTEOBL_ArraySize] & 0XFF);
holder = hashAnagramRecurse(thisIndex, nextMarker, currentChar, fuckWithMe, fillThisPosition + 1, characterBank, sizeOfBank - 1, wordCounter, nodeCounter);
wordAccumulator += holder;
insertCharIntoArray(characterBank, x, currentChar, sizeOfBank);
theUsedChars[currentChar - '?'] = true;
}
}
}
return wordAccumulator;
}
public String hashAnagram(boolean toSort, String toAnagram, String[] nodeCheck, int[] numberOfWords, int[] theNodeCounts) {
String holder;
String upperAnagramString = toAnagram.toUpperCase();
String traversalResult = "";
int numberOfLetters = upperAnagramString.length();
char[] inputCharArray = upperAnagramString.toCharArray();
char[] workingCharArray = new char[MAX];
char currentChar;
boolean[] usedChars = new boolean[VALID_CHAR_RANGE_SIZE];
if ( toSort ) java.util.Arrays.sort(inputCharArray);
for ( int x = 0; x < VALID_CHAR_RANGE_SIZE; x++ ) usedChars[x] = false;
for ( int x = 0; x < numberOfLetters; x++ ) {
currentChar = inputCharArray[x];
if ( usedChars[currentChar - '?'] == true ) continue;
removeCharFromArray(inputCharArray, x, numberOfLetters);
if ( currentChar == '?' ) {
for ( int y = 'A'; y <= 'Z'; y++ ) {
holder = "-----------------------------\n";
holder += hashAnagramRecurse(y - '@', theRoot_WTEOBL_Array[y - '@'], (char)(y + LOWER_IT), workingCharArray, 0, inputCharArray, numberOfLetters - 1, numberOfWords, theNodeCounts);
traversalResult += holder;
}
}
else {
holder = "-----------------------------\n";
holder += hashAnagramRecurse(currentChar - '@', theRoot_WTEOBL_Array[currentChar - '@'], currentChar, workingCharArray, 0, inputCharArray, numberOfLetters - 1, numberOfWords, theNodeCounts);
traversalResult += holder;
}
insertCharIntoArray(inputCharArray, x, currentChar, numberOfLetters);
usedChars[currentChar - '?'] = true;
}
for ( int x = 0; x < MAX; x++ ) {
nodeCheck[x] = "| " + theNodeCounts[x] + " |";
if ( theNodeCounts[x] != 0 )nodeCheck[x]+= " Nodes " + "" + (char)0X2713 + "";
}
traversalResult = "Anagramming this: |" + upperAnagramString + "|\nResults in |" + numberOfWords[0] + "| words.\n" + traversalResult;
return traversalResult;
}
private String booleanPatternSearchRecurse(int thisIndex, char thisChar, String thisString, char[] toyWithMe, int thisPosition, String[] nodeFills, int[] downForTheCount, int[] nodeTally) {
char currentChar;
int firstChildIndex;
int thisChildListFormat;
String wordAccumulator = "";
toyWithMe[thisPosition] = thisChar;
nodeTally[thisPosition] += 1;
nodeFills[thisPosition] = "'" + thisChar + "' @ |" + thisIndex +"|";
if ( thisString.length() == (thisPosition + 1) ) {
if ( (theNodeArray[thisIndex] & EOW_FLAG) != 0 ) {
downForTheCount[0] += 1;
nodeFills[thisPosition] += "- found " + (char)0X2713 + "";
for ( int x = thisPosition + 1; x < MAX; x++ ) nodeFills[x] = "";
wordAccumulator = new String(toyWithMe, 0, thisPosition + 1);
wordAccumulator = "|" + downForTheCount[0] + "| - " + wordAccumulator + "\n";
return wordAccumulator;
}
else {
nodeFills[thisPosition] += "- lost EOW";
for ( int x = thisPosition + 1; x < MAX; x++ ) nodeFills[x] = "";
return wordAccumulator;
}
}
firstChildIndex = (theNodeArray[thisIndex] & CHILD_MASK);
if ( firstChildIndex != 0 ) {
thisChildListFormat = theListFormatArray[(theNodeArray[thisIndex] & LIST_FORMAT_INDEX_MASK)>>>LIST_FORMAT_BIT_SHIFT];
currentChar = thisString.charAt(thisPosition + 1);
if ( currentChar == '?' ) {
for ( int x = 'A'; x <= 'Z'; x++ ) {
if ( (thisChildListFormat & powersOfTwo[x - 'A']) != 0 ){
wordAccumulator += booleanPatternSearchRecurse(firstChildIndex + listFormatPopCount(thisChildListFormat, x - 'A'), (char)(x + LOWER_IT), thisString, toyWithMe, thisPosition + 1, nodeFills, downForTheCount, nodeTally);
}
}
}
else if ( (thisChildListFormat & powersOfTwo[currentChar - 'A']) != 0 ){
wordAccumulator += booleanPatternSearchRecurse(firstChildIndex + listFormatPopCount(thisChildListFormat, currentChar - 'A'), currentChar, thisString, toyWithMe, thisPosition + 1, nodeFills, downForTheCount, nodeTally);
}
}
return wordAccumulator;
}
private String hashPatternSearchRecurse(int thisIndex, int currentMarker, char thisChar, String thisString, char[] toyWithMe, int thisPosition, String[] nodeFills, int[] downForTheCount, int[] nodeTally) {
char currentChar;
int firstChildIndex;
int thisChildListFormat;
int nextMarker;
boolean isChildShort;
String wordAccumulator = "";
toyWithMe[thisPosition] = thisChar;
nodeTally[thisPosition] += 1;
nodeFills[thisPosition] = "'" + thisChar + "' @ |" + thisIndex +"|";
if ( (theNodeArray[thisIndex] & EOW_FLAG) != 0 ) currentMarker -= 1;
nodeFills[thisPosition] += " Mark-[ " + (totalNumberOfWords - currentMarker) + " ]";
if ( thisString.length() == (thisPosition + 1) ) {
if ( (theNodeArray[thisIndex] & EOW_FLAG) != 0 ) {
downForTheCount[0] += 1;
nodeFills[thisPosition] += " " + (char)0X2713 + "";
for ( int x = thisPosition + 1; x < MAX; x++ ) nodeFills[x] = "";
wordAccumulator = new String(toyWithMe, 0, thisPosition + 1);
wordAccumulator = "|" + downForTheCount[0] + "| - " + wordAccumulator + " [ " + (totalNumberOfWords - currentMarker) + " ]\n";
return wordAccumulator;
}
else {
nodeFills[thisPosition] += " X";
for ( int x = thisPosition + 1; x < MAX; x++ ) nodeFills[x] = "";
return wordAccumulator;
}
}
firstChildIndex = (theNodeArray[thisIndex] & CHILD_MASK);
if ( firstChildIndex != 0 ) {
isChildShort = ( firstChildIndex < short_WTEOBL_ArraySize ) ? true: false;
if ( isChildShort ) currentMarker -= theShort_WTEOBL_Array[firstChildIndex];
else currentMarker -= (theByte_WTEOBL_Array[firstChildIndex - short_WTEOBL_ArraySize] & 0XFF);
thisChildListFormat = theListFormatArray[(theNodeArray[thisIndex] & LIST_FORMAT_INDEX_MASK)>>>LIST_FORMAT_BIT_SHIFT];
currentChar = thisString.charAt(thisPosition + 1);
if ( currentChar == '?' ) {
for ( int x = 'A'; x <= 'Z'; x++ ) {
if ( (thisChildListFormat & powersOfTwo[x - 'A']) != 0 ){
thisIndex = firstChildIndex + listFormatPopCount(thisChildListFormat, x - 'A');
if ( isChildShort ) nextMarker = currentMarker + theShort_WTEOBL_Array[thisIndex];
// When reading "theByte_WTEOBL_Array", it is necessary to mask the values with "0XFF" to cast them as unsigned.
else nextMarker = currentMarker + (theByte_WTEOBL_Array[thisIndex - short_WTEOBL_ArraySize] & 0XFF);
wordAccumulator += hashPatternSearchRecurse(thisIndex, nextMarker, (char)(x + LOWER_IT), thisString, toyWithMe, thisPosition + 1, nodeFills, downForTheCount, nodeTally);
}
}
}
else if ( (thisChildListFormat & powersOfTwo[currentChar - 'A']) != 0 ){
thisIndex = firstChildIndex + listFormatPopCount(thisChildListFormat, currentChar - 'A');
if ( isChildShort ) nextMarker = currentMarker + theShort_WTEOBL_Array[thisIndex];
// When reading "theByte_WTEOBL_Array", it is necessary to mask the values with "0XFF" to cast them as unsigned.
else nextMarker = currentMarker + (theByte_WTEOBL_Array[thisIndex - short_WTEOBL_ArraySize] & 0XFF);
wordAccumulator += hashPatternSearchRecurse(thisIndex, nextMarker, currentChar, thisString, toyWithMe, thisPosition + 1, nodeFills, downForTheCount, nodeTally);
}
}
return wordAccumulator;
}
public String patternSearch(boolean includeHash, String theInputString,String[] nodeFlags, int[] countEmUp, int[] nodeCountSpread) {
String holder;
String upperInputString = theInputString.toUpperCase();
String traversalResult = "";
char[] workingCharArray = new char[MAX];
char currentChar = upperInputString.charAt(0);
if ( currentChar == '?' ) {
for ( int x = 'A'; x <= 'Z'; x++ ) {
if ( !includeHash ) holder = booleanPatternSearchRecurse(x - '@', (char)(x + LOWER_IT), upperInputString, workingCharArray, 0, nodeFlags, countEmUp, nodeCountSpread);
else holder = hashPatternSearchRecurse(x - '@', theRoot_WTEOBL_Array[x - '@'], (char)(x + LOWER_IT), upperInputString, workingCharArray, 0, nodeFlags, countEmUp, nodeCountSpread);
traversalResult += holder;
}
}
else {
if ( !includeHash ) holder = booleanPatternSearchRecurse(currentChar - '@', currentChar, upperInputString, workingCharArray, 0, nodeFlags, countEmUp, nodeCountSpread);
else holder = hashPatternSearchRecurse(currentChar - '@', theRoot_WTEOBL_Array[currentChar - '@'], currentChar, upperInputString, workingCharArray, 0, nodeFlags, countEmUp, nodeCountSpread);
traversalResult += holder;
}
for ( int x = 0; x < MAX; x++ ) {
if ( nodeCountSpread[x] > 1 ) {
nodeFlags[x] = "| " + nodeCountSpread[x] + " | Nodes " + "" + (char)0X2713 + "";
}
}
traversalResult = "Pattern Searching this: |" + upperInputString + "|\nGenerates |" + countEmUp[0] + "| words.\n" + traversalResult;
return traversalResult;
}
private void removeCharFromArray(char[] thisArray, int thisPosition, int size) {
System.arraycopy(thisArray, thisPosition + 1, thisArray, thisPosition, (size - thisPosition - 1));
}
private void insertCharIntoArray(char[] thisArray, int thisPosition, char thisChar, int size) {
System.arraycopy(thisArray, thisPosition, thisArray, thisPosition + 1, (size - thisPosition - 1));
thisArray[thisPosition] = thisChar;
}
private int listFormatPopCount(int completeChildList, int LetterPosition){
int result = 0;
completeChildList &= childListMasks[LetterPosition];
switch (LetterPosition) {
case 25:
case 24:
result += popCountTable[(completeChildList & 0XFF000000)>>>24];
case 23:
case 22:
case 21:
case 20:
case 19:
case 18:
case 17:
case 16:
result += popCountTable[(completeChildList & 0XFF0000)>>>16];
case 15:
case 14:
case 13:
case 12:
case 11:
case 10:
case 9:
case 8:
result += popCountTable[(completeChildList & 0XFF00)>>>8];
case 7:
case 6:
case 5:
case 4:
case 3:
case 2:
case 1:
result += popCountTable[(completeChildList & 0XFF)];
case 0:
}
return result;
}
}