0

Below is the code. The array index represents the small characters(a-z) and index is 26 (number of characters in english alphabets). It is a dictionary of words in which the children[character ascii value-97] points to the next node. The end of word is given bool terminal=true.

All functions are recursive. In delete function, we have to traverse to the end of the word character by character. While traversing, on the second call of recursive delete, I lose all my references and NullPointerException occurs.

The line of code which is making trouble has a comment in front of it. First there is a check if word exist in dictionary or not.

import java.io.File;
import java.util.Scanner;

public class xxx {

public static void main(String[] args) {
    Trie trie = new Trie();

                if (trie.delete(word)) {
                    System.out.println("Word deleted");
                } else {
                    System.out.println("Word not present");
                }
                break;
            }
            case "S": { //Search for the word
                String word = tokens[1];
                if (trie.isPresent(word)) {
                    System.out.println("Word found");
                } else {
                    System.out.println("Word not found");
                }
}

This class just calls the recursive functions of the Node class. The trie class gets call from the main class and then shifts the data to recursive functions in Node class

class Trie {

Node root;

public Trie() {
    root = new Node();

}

boolean isPresent(String s) { // returns true if s is present, false otherwise
    current = root;
    for (int i = 0; i < s.length(); i++) {
        if (current.children[(int) s.charAt(i) - 97] == null) {
            return false;
        } else {
            current = current.children[(int) s.charAt(i) - 97];
        }

    }
    if (current.terminal == false) {
        return false;
    }

    return true;
}

boolean delete(String s) { // returns false if s is not present, true otherwise
    if (!isPresent(s)) {
        return false;
    }
    root.delete(root,s);
    return true;
}

int membership() { // returns the number of words in the data structure
    return root.membership(root, 0);
}

void listAll() { // list all members of the Trie in alphabetical orber
    root.listAll(root, "");

}

}

The children[ascii value-97] will reference a node and this link will represent alphabetic character. The outDegree will make sure that only the given string is deleted. This class has all recursive functions.

 class Node {

boolean terminal;
int outDegree;
Node[] children;

public Node() {
    terminal = false;
    outDegree = 0;
    children = new Node[26];
}



public void delete(Node x, String s) {
    if (s.length() > 1){
        if(i<s.length())
        delete(children[s.charAt(0)-97],s.substring(1)); //this is where problem occurs

    }
    else if(children[((int)s.charAt(0))-97].outDegree>0)
        terminal =false;
    else if(children[((int)s.charAt(0))-97].outDegree==0){
        children[((int)s.charAt(0))-97]=null;
        return;
    }
    if(children[s.charAt(0)-97].outDegree==0)
        children[s.charAt(0)-97]=null;
    }

}
gknicker
  • 5,509
  • 2
  • 25
  • 41
Fazeel
  • 26
  • 6
  • possible duplicate of [What is a Null Pointer Exception, and how do I fix it?](http://stackoverflow.com/questions/218384/what-is-a-null-pointer-exception-and-how-do-i-fix-it) – gknicker Mar 05 '15 at 08:02
  • I know how nullPointerExceptions occurs. My code works for first recursion and debugging shows that there is atlleast one non-null item in children[] array. – Fazeel Mar 05 '15 at 15:25

1 Answers1

0

Your problem is not in the line of code you commented. Your problem is how you initialized the array:

children = new Node[26];

This line of code allocates memory of the array. However, the value of each individual element of the array is set to NULL for object references, unicode NULL character for char primitives, false for boolean primitives, and to 0 for number primitives. If you want this to work, you must initialize the array properly.

hfontanez
  • 5,774
  • 2
  • 25
  • 37
  • The array initialization is good as insert() word, listall() words, ispresent() all these functions work perfectly. All the references are initially set to null and if I add word, then the children[ascii value of the char- 97] will reference a new node.PS. Node doesnot hold the character, it the array index representing character. – Fazeel Mar 05 '15 at 15:22
  • First is image for input :[link](http://postimg.org/image/ta1m8hyl9/) Second image shows the trie configuration for string "abcd": [link](http://postimg.org/image/iqfwfy4qv/) Third image shows first recursion: [link](http://postimg.org/image/uoi5nfilh) fourth image is where on second recursion the reference becomes null: [link](http://postimg.org/image/okwwg3a4z/) – Fazeel Mar 05 '15 at 15:42
  • Obviously initialization is not good if you are getting an NPE on that line. I suggest you run on debug and step through your code. You have this code in your `isPresent` method: `if (current.children[(int) s.charAt(i) - 97] == null) { return false;}` Which tells me you expect some elements of the array to be NULL. I don't see any code to correct this problem. – hfontanez Mar 05 '15 at 16:27
  • All elements in the array are null except for the indices that represent characters. If there is only one word in the whole trie then only one element in children array is expected to refer next element. Other reference would null. This patern continues in the following nodes as well. – Fazeel Mar 05 '15 at 17:19
  • @Fazeel, If that is the case, you are obviously accessing the wrong index. The NPE is an indicator the index you are trying to access contains a null reference. So, if initializing properly ALL elements of the array is not an option, I suggest you debug your accessing function (`current.children[(int) s.charAt(i) - 97]`). Those are your two options. – hfontanez Mar 05 '15 at 20:38
  • I figured out the error. I call the recursive delete: delete(children[s.charAt(0)-97],s.substring(1)); which is wrong. I have to call it using the reference variable and right call is : children[s.charAt(0)-97].delete(children[s.charAt(0)-97],s.substring(1)); – Fazeel Mar 06 '15 at 00:34