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; } }