Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package predictive;
- import java.io.File;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.util.HashSet;
- import java.util.Scanner;
- import java.util.Set;
- /**
- * TreeDictionary is a Tree with 8 branches each representing a number from a signature of a word.
- * as you progress through the tree the node will store complete words for which the subsignature created by the path of branches is a match for.
- * @author Henry
- *
- */
- public class TreeDictionary implements Dictionary {
- private Set<String> nodeList;
- private String nodeSig;
- private TreeDictionary[] children;
- public static void main(String[] args) throws IOException {
- TreeDictionary dict = new TreeDictionary("C:\\Users\\henry\\Desktop\\Programs\\WS3\\src\\words");
- System.out.println(dict.findSigNode("4663"));
- }
- /**
- * TreeDictionary(String path) is the constructor which should be called upon to create your Tree dictionary
- * it will initizalise the starting node which has every valid word attached to it and then create the first 8 branches of the tree
- * using a different constructor.
- * @param path, a file path to a dictionary of words.
- */
- public TreeDictionary(String path) {
- this.nodeList = new HashSet<String>(); // our starting node is initialized as empty set
- try{
- File words = new File(path);
- Scanner scan = new Scanner(words);
- while(scan.hasNextLine()) { // loops whenever there is a next line
- String line = scan.nextLine().toLowerCase(); // initialise a String of the next line in lower case
- if(isValidWord(line)) {
- nodeList.add(line); // adds every valid word to the set
- }
- }
- scan.close();
- } catch (FileNotFoundException exception) { // exception when the dictionary cannot be found
- System.out.println("File Not Found");
- }
- this.nodeSig = ""; // first node signature is empty
- String empty = ""; // creates empty string to be the first nodes signature
- TreeDictionary[] childs = {new TreeDictionary(empty, "2", nodeList), // uses our next constructor to make the array of children for the first node.
- new TreeDictionary(empty, "3", nodeList),
- new TreeDictionary(empty, "4", nodeList),
- new TreeDictionary(empty, "5", nodeList),
- new TreeDictionary(empty, "6", nodeList),
- new TreeDictionary(empty, "7", nodeList),
- new TreeDictionary(empty, "8", nodeList),
- new TreeDictionary(empty, "9", nodeList)};
- this.children = childs; // sets this array to be the children of our starting node
- }
- /**
- * TreeDictionary(String prevNodeSig, String childSig, Set<String> prevNodeList) is a constructor which is called by our initial constructor
- * in which we narrow down our Set of words for each child without having to rescan the file.
- * @param prevNodeSig The signature of the previous node
- * @param childSig The number of child we are on from 2-9
- * @param prevNodeList The list of words from the parent node which we narrow down depending on the new part of our signature
- */
- public TreeDictionary(String prevNodeSig, String childSig, Set<String> prevNodeList) {
- this.nodeSig = prevNodeSig + childSig; // sets the node of the signature to be the previous plus the number of the child we are on.
- Set<String> newNodeList = new HashSet<>(); // initializes this nodes Set of words as empty
- for(String s : prevNodeList) {
- if(wordToSignature(s).startsWith(this.nodeSig)) // for each word in the previous list we add to the new list if our new subsignature matches it.
- newNodeList.add(s);
- }
- this.nodeList = newNodeList; // sets this new list as the nodes nodeList
- if(newNodeList.size() > 0) { // if this list is non empty we create its children recursively using this constructor.
- TreeDictionary[] childs = {new TreeDictionary(this.nodeSig, "2", this.nodeList),
- new TreeDictionary(this.nodeSig, "3", this.nodeList),
- new TreeDictionary(this.nodeSig, "4", this.nodeList),
- new TreeDictionary(this.nodeSig, "5", this.nodeList),
- new TreeDictionary(this.nodeSig, "6", this.nodeList),
- new TreeDictionary(this.nodeSig, "7", this.nodeList),
- new TreeDictionary(this.nodeSig, "8", this.nodeList),
- new TreeDictionary(this.nodeSig, "9", this.nodeList),
- };
- this.children=childs; // sets the child array to be this nodes children
- }
- }
- /**
- * getter for nodeList
- * @return this.nodeList
- */
- public Set<String> getNodeList() {
- return nodeList;
- }
- /**
- * getter for nodeSig
- * @return this.nodeSig
- */
- public String getNodeSig() {
- return nodeSig;
- }
- /**
- * getter for child i, we use 2-9 to simplify this class and will minus 2 to make it match the childs position in the array
- * @param i, name of child from 2-9
- * @return child i
- * @throws IOException if i is out of bounds
- */
- public TreeDictionary getChildI(int i) throws IOException{
- return children[i-2]; // matches the child's signature number from 2-9 to its position in the array 0-7
- }
- /**
- * signatureToWords will get a Set of Strings which match our signatures by using helper method findSigNode and getting the nodeList of the found node. Then it will return these words in a set with each word
- * trimmed to be the same length of the input signature.
- * @param signature, a numeric String signature you wish to find
- * @return a Set<String> of a set of substrings or strings of all words which have matching subsignatures or a matching signatures to the input signature.
- * @throws IOException if no matches are found
- */
- public Set<String> signatureToWords(String signature) {
- if(signature.length()>0) { // stops the inital node from returning every word in our TreeDictionary
- try {
- Set<String> words = new HashSet<>(); // initialize empty set
- for(String s : findSigNode(signature).getNodeList()) { // for each String in our nodeList
- if (s.length() == signature.length())
- words.add(s); // we add the whole String if it is of the correct length
- else
- words.add(s.substring(0, signature.length())); // else we add a substring of the word if of matching length to signature if it the String is longer than our input signature.
- }
- return words; // returns this Set of words
- } catch (IOException e) {
- System.out.println("no words found"); // catches exception if no matching words are found
- }
- }
- return null;
- }
- /**
- * findSigNode will recursively search through a TreeDictionary and return the node at which the input signature matches the signature of a node.
- * @param signature, signature you wish to find
- * @return a TreeDictionary, typically a sub TreeDictionary
- * @throws IOException
- */
- public TreeDictionary findSigNode(String signature) throws IOException {
- if (signature.length()==1) { // if the input signature is only of length 1 we return that child.
- return this.getChildI(Character.getNumericValue(signature.charAt(0)));
- }
- else{
- try {
- int startSig = Character.getNumericValue(signature.charAt(0)); // converts the first number in our signature to an int
- TreeDictionary child = this.getChildI(startSig); // gets that child node and assigns to a TreeDictionary
- if(child.getNodeSig() == signature) { // if this child's node has nodeSig of our input signature return the child
- return child;
- }
- else {
- return findSigNodeHelper(child, signature.substring(1), signature); // else search the child of the next character in the signature using helper method
- }
- } catch(IOException ex) {
- System.out.println("not found"); // if this signature cannot be found
- }
- }
- return null;
- }
- /**
- *
- * @param dict the node of the TreeDictionary you wish to search
- * @param trimmedSignature the last used signature missing the first element
- * @param signature the original signature you wish to search for
- * @return the node of TreeDictionary with a nodeSig matching the input signature
- * @throws IOException if no match is found
- */
- public static TreeDictionary findSigNodeHelper(TreeDictionary dict, String trimmedSignature, String signature) throws IOException {
- try {
- int startSig = Character.getNumericValue(trimmedSignature.charAt(0)); // converts the first number in our signature to an int
- TreeDictionary child = dict.getChildI(startSig); // gets that child node and assigns to a TreeDictionary
- if(child.getNodeSig().contentEquals(signature)) {// if this child's node has nodeSig of our input signature return the child
- return child;
- }
- else {
- return findSigNodeHelper(child, trimmedSignature.substring(1), signature); // else recursively search the child of the next character in the signature using this helper method
- }
- } catch(IOException ex) {
- System.out.println("not found"); // if this signature cannot be found
- }
- return null;
- }
- /**
- * boolean method returning if input word contains characters not in the alphabet
- * @param word, a word to be checked.
- * @return true if no invalid characters are found, false if they are
- */
- static boolean isValidWord(String word) {
- word = word.toLowerCase();
- for ( int i=0; i < word.length(); i++) {
- if(word.charAt(i) < 'a' || word.charAt(i) > 'z')
- return false;
- }
- return true;
- }
- /**
- * wordToSignature() takes in a word and returns a String of numbers corresponding to where each
- * letter of the word is on an old mobile keyboard, we call this its signature. (https://i.stack.imgur.com/hHq4v.jpg)
- * This method makes use of the helper method letterToNumber to convert each letter individually.
- * @param word A String of a word you wish to convert
- * @return A String of the numeric signature of the word
- */
- public static String wordToSignature(String word) {
- StringBuffer signature = new StringBuffer();
- String lowerCaseWord = word.toLowerCase(); // converts to lower case
- for (int i=0; i < lowerCaseWord.length(); i++) {
- signature.append(letterToNumber(lowerCaseWord.charAt(i))); // we append the signature String for each character in the word
- }
- return signature.toString(); // converts back to string once fully appended
- }
- /**
- * This helper method assigns each letter to its corresponding number on the phones keypad.
- * @param letter, the character you wish to convert, non letter characters will become spaces.
- * @return The corresponding signature of the character or space if there is none.
- */
- public static String letterToNumber(char letter) {
- if (letter == 'a' || letter == 'b' || letter == 'c')
- return "2";
- if (letter == 'd' || letter == 'e' || letter == 'f')
- return "3";
- if (letter == 'g' || letter == 'h' || letter == 'i')
- return "4";
- if (letter == 'j' || letter == 'k' || letter == 'l')
- return "5";
- if (letter == 'm' || letter == 'n' || letter == 'o')
- return "6";
- if (letter == 'p' || letter == 'q' || letter == 'r' || letter == 's')
- return "7";
- if (letter == 't' || letter == 'u' || letter == 'v')
- return "8";
- if (letter == 'w' || letter == 'x' || letter == 'y' || letter == 'z')
- return "9";
- else
- return " ";
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement