search(String target) method in a BinarySearchTree - java

I'm coding a dictionary system. This system should be run like this;
User enters a word that s/he wants to learn the definition.
The words and the definitions are storing in a linked list
while searching I should use a binary search tree
bst is comparing the words
search(String target) method should return the word+definition
Problems:
I've printed the linked list in a binary search tree but the method search() is couldn't return the word+definition? Where did I do a mistake?
public class BinarySearchTree {
private String data;
private BinarySearchTree left;
private BinarySearchTree right;
public BinarySearchTree() {
// I've deleted the getters/setters
public void addNode(String data) {
if (this.data == null) {
this.data = data;
} else {
if (this.data.compareTo(data)> 0) {
if (this.left != null) {
this.left.addNode(data);
} else {
this.left = new BinarySearchTree(data);
}
} else {
if (this.right != null) {
this.right.addNode(data);
} else {
this.right = new BinarySearchTree(data);
}
}
}
}
public boolean search(BinarySearchTree t,String key) {
if (t.data.equals(key)) return true;
if (t.left != null && search(t.left,key)) return true;
if (t.right != null && search(t.right,key)) return true;
return false;
}
}
public class Vocab {
public static void main(String args[])
{
LinkedList<String> ll
= new LinkedList<>();
Word word = new Word("Engineer", "Mühendis");
Word word2 = new Word("School", " Okul");
Word word3 = new Word("Pencil", "Kalem");
Word word4 = new Word("Window", "Pencere");
ll.add(word.toString());
ll.add(word2.toString());
ll.add(word3.toString());
ll.add(word4.toString());
for (int i = 0; i < ll.size(); i++) {
System.out.println(ll.get(i));
}
BinarySearchTree bst = new BinarySearchTree();
// Using the for each loop
for (String str : ll) {
bst.addNode(str);
}
System.out.println("search: " );
//here I want to return search() method and get the word+definition
}
}

Related

Question in implementing Trie data structure

I have a question about nested class in terms of Trie implementation
I want to know what is the difference define TrieNode class inside of Trie class and outside of Trie class
In case of I implement TrieNode class outside of Trie class, when I try to use Insert method, it keeps sayig NullPointException at (Trie.java:14),
So anyone could explain about what are the difference between two way and further to what is the solution if i want to resolve Nullpointexception error when I implement TrieNode class outside of Trie class.
here is my code
public class Trie {
private final TrieNode root;
public Trie () {
root = new TrieNode();
}
public void insert (String word) {
TrieNode current = root;
for (int i = 0; i < word.length(); i++) {
char ch = word.charAt(i);
TrieNode node = current.children.get(ch);
if (node == null) {
node = new TrieNode();
current.children.put(ch, node);
}
current = node;
}
//mark the current nodes endOfWord as true
current.isEnd = true;
}
public boolean search (String word) {
TrieNode current = root;
for (int i = 0; i < word.length(); i++) {
char ch = word.charAt(i);
if (current.children.get(ch) == null) {
return false;
}
current = current.children.get(ch);
}
return current.isEnd;
}
public void delete (String word) {
delete(root, word, 0);
}
private boolean delete (TrieNode node, String word, int index) {
if (index == word.length()) {
if (!node.isEnd) {
return false;
}
node.isEnd = false;
return node.children.size() == 0;
}
if (node == null) {
return false;
}
node = node.children.get(word.charAt(index));
boolean shouldBeDeleted = delete(node, word, index + 1);
if (shouldBeDeleted) {
node.children.remove(word.charAt(index));
return node.children.size() == 0;
}
return false;
}
public static void main(String[] args) {
Trie trie = new Trie();
trie.insert("abcd");
// System.out.println(trie.search("abcd"));
}
}
TrieNode class separated to Trie class
public class TrieNode {
boolean isEnd;
Map<Character, TrieNode> children;
public void TrieNode () {
this.isEnd = false;
this.children = new HashMap<>();
}
}

How do I reference a method to add to a binaryTree?

I am tasked with building a BinaryTree that represents Morse Code. It branches left with each dot and right with each dash.
I can not figure out, however, why my method to add a Node does not seem to want to work with a BinaryTree object. IntelliJ says that it "can not resolve method".
I am certain that the BinaryTree is not the issue, because I was given detailed instructions on how to write the class by my instructor. Rather, I suspect that I am perhaps referencing the wrong thing here. I have already verified that the parameters being entered isn't the issue.
public static MorseCodeTree<Character> readMorseCodeTree()
{
MorseCodeTree<Character> morse = new MorseCodeTree<Character>();
Node<Character> newNode = new Node<Character>(null);
morse.addNode(newNode, letter, position);
private Node<Character> addNode(Node<Character> currentNode, char data, String morseCode)
{
if (currentNode == null)
{
currentNode = new Node(null);
}
if (morseCode.charAt(0) == '*')
{
currentNode = addNode(currentNode.left, data, morseCode.substring(1));
}
else if (morseCode.charAt(0) == '-')
{
currentNode = addNode(currentNode.right, data, morseCode.substring(1));
}
else
{
currentNode.data = data;
}
return currentNode;
}
BinaryTree class:
import java.io.Serializable;
import java.util.Scanner;
public class BinaryTree implements Serializable{
//implement Node class
protected static class Node<E> implements Serializable
{
protected E data;
protected Node<E> left;
protected Node<E> right;
public Node (E data)
{
this.data = data;
this.left = null;
this.right = null;
}
public String toString()
{
return data.toString();
}
}
protected Node root;
public BinaryTree()
{
root = null;
}
protected BinaryTree(Node<E> root)
{
this.root = root;
}
public BinaryTree(E data, BinaryTree<E> leftTree, BinaryTree<E> rightTree)
{
root = new Node<E>(data);
if (leftTree != null)
{
root.left = leftTree.root;
}
else
{
root.left = null;
}
if (rightTree != null)
{
root.right = rightTree.root;
}
else
{
root.right = null;
}
}
public BinaryTree<E> getLeftSubtree()
{
if (root != null && root.left != null)
{
return new BinaryTree<E>(root.left);
}
else
{
return null;
}
}
public BinaryTree<E> getRightSubtree()
{
if (root != null && root.right != null)
{
return new BinaryTree<E>(root.right);
}
else
{
return null;
}
}
public boolean isLeaf()
{
return (root.left == null && root.right == null);
}
public String toString()
{
StringBuilder sb = new StringBuilder();
preOrderTraverse(root, 1, sb);
return sb.toString();
}
private void preOrderTraverse(Node<E> node, int depth, StringBuilder sb)
{
for (int i = 1; i < depth; i++)
{
sb.append(" ");
}
if (node == null)
{
sb.append("null\n");
}
else
{
sb.append(node.toString() + "\n");
preOrderTraverse(node.left, depth + 1, sb);
preOrderTraverse(node.right, depth + 1, sb);
}
}
public static BinaryTree<String> readBinaryTree(Scanner scan)
{
String data = scan.next();
if (data.equals("null"))
{
return null;
}
else
{
BinaryTree<String> leftTree = readBinaryTree(scan);
BinaryTree<String> rightTree = readBinaryTree(scan);
return new BinaryTree<String>(data, leftTree, rightTree);
}
}
}
You're declaring the addNode(...) method within readMorseCodeTree(), so it's not in the scope of the class. The latter method should look like this:
public static BinaryTree<Character> readMorseCodeTree()
{
BinaryTree morse = new MorseCodeTree();
Node<Character> newNode = new Node<Character>(null);
morse.addNode(newNode, letter, position);
}

Remove method in a binary tree

I'm trying to create a method to remove nodes from a Binary Tree but I am having a problem, it seems to be ok but I have another method for printing all of them and after "deleting" a specific node I use the print method but it prints all of them including the one I've already deleted.
public class BinaryTree
{
Node root;
Node n;
private class Node
{
public Node f; //father
public Node right;
public Node left;
public int key; // key
public String Student;
public int Mark;
public Node(int key)
{
right = null;
left = null;
f = null;
Student = null;
Mark = 0;
}
}
public void remove()
{
System.out.println("");
System.out.println("Which student do you want to delete? Write down his ID.");
int id = Genio.getInteger();
n = new Node(id);
Node temporal = root;
if(root == null)
{
System.out.println("This tree is empty");
}
else
{
while(temporal != null)
{
n.f = temporal;
if(n.key == temporal.key)
{
if(n.f.right == null && n.f.left == null)
{
n = null;
temporal = null;
}
}
else if(n.key >= temporal.key)
{
temporal = temporal.right;
}
else
{
temporal = temporal.left;
}
}
}
}
}

I'm getting a Out Of Memory Error: Java heap space Exception

I am currently trying to take in a text file and read each word in the file into a binary tree the specific error i get is:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
the text file i am reading into the project was given to me by the professor for the assignment so i know this should not be running into any memory problems i have never felt with this type of exception before and don't know where to start please help. here is my code:
public class Tester {
public static void main(String[] args) throws FileNotFoundException {
Tester run = new Tester();
run.it();
}
public void it() throws FileNotFoundException {
BTree theTree = new BTree();
String str = this.readInFile();
String [] firstWords = this.breakIntoWords(str);
String [] finalWords = this.removeNullValues(firstWords);
for(int i = 0; i < finalWords.length; i++) {
theTree.add(finalWords[i]);
}
theTree.print();
}
public String readInFile() throws FileNotFoundException {
String myFile = "";
int numWords = 0;
Scanner myScan = new Scanner(new File("Dracula.txt"));
while(myScan.hasNext() == true) {
myFile += myScan.nextLine() + " ";
}
return myFile;
}
public String [] breakIntoWords(String myFile) {
String[] words = new String[myFile.length()];
String nextWord = "";
int position = 0;
int i = 0;
while(myFile.length() > position) {
char next = myFile.charAt(position);
next = Character.toLowerCase(next);
// First trim beginning
while (((next < 'a') || (next > 'z')) && !Character.isDigit(next)) {
position++;
next = myFile.charAt(position);
next = Character.toLowerCase(next);
}
// Now pull only letters or numbers until we hit a space
while(!Character.isWhitespace(next)) {
if (Character.isLetterOrDigit(next)) {
nextWord += myFile.charAt(position);
}
position++;
next = myFile.charAt(position);
}
words [i] = nextWord;
i++;
}
return words;
}
public String[] removeNullValues(String[] myWords) {
String[] justMyWords = new String[myWords.length];
for (int i = 0; i < myWords.length; i++) {
if (myWords[i] != null) {
justMyWords[i] = myWords[i];
}
}
return justMyWords;
}
}
Here's my B-tree class:
public class BTree {
private BTNode root;
private int nodeCount;
public boolean add(String word) {
BTNode myNode = new BTNode(word);
if(root == null) {
root = myNode;
nodeCount++;
return true;
}
if(findNode(word)) {
int tmp = myNode.getNumInstance();
tmp++;
myNode.setNumInstance(tmp);
return false;
}
BTNode temp = root;
while(temp != null) {
if(word.compareTo(temp.getMyWord()) < 0) {
if(temp.getRightChild() == null) {
temp.setLeftChild(myNode);
nodeCount++;
return true;
} else {
temp = temp.getRightChild();
}
} else {
if(temp.getLeftChild() == null) {
temp.setLeftChild(myNode);
nodeCount++;
return true;
} else {
temp = temp.getLeftChild();
}
}
}
return false;
}
public boolean findNode(String word) {
return mySearch(root, word);
}
private boolean mySearch(BTNode root, String word) {
if (root == null) {
return false;
}
if ((root.getMyWord().compareTo(word) < 0)) {
return true;
} else {
if (word.compareTo(root.getMyWord()) > 0) {
return mySearch(root.getLeftChild(), word);
} else {
return mySearch(root.getRightChild(), word);
}
}
}
public void print() {
printTree(root);
}
private void printTree(BTNode root) {
if (root == null) {
System.out.print(".");
return;
}
printTree(root.getLeftChild());
System.out.print(root.getMyWord());
printTree(root.getRightChild());
}
public int wordCount() {
return nodeCount;
}
}
And my B-tree node class:
public class BTNode {
private BTNode rightChild;
private BTNode leftChild;
private String myWord;
private int numWords;
private int numInstance;
private boolean uniqueWord;
private boolean isRoot;
private boolean isDeepest;
public BTNode(String myWord){
this.numInstance = 1;
this.myWord = myWord;
this.rightChild = null;
this.leftChild = null;
}
public String getMyWord() {
return myWord;
}
public void setMyWord(String myWord) {
this.myWord = myWord;
}
public BTNode getRightChild() {
return rightChild;
}
public void setRightChild(BTNode rightChild) {
this.rightChild = rightChild;
}
public BTNode getLeftChild() {
return leftChild;
}
public void setLeftChild(BTNode leftChild) {
this.leftChild = leftChild;
}
public int getnumWords() {
return numWords;
}
public void setnumWords(int numWords) {
this.numWords = numWords;
}
public boolean isUniqueWord() {
return uniqueWord;
}
public void setUniqueWord(boolean uniqueWord) {
this.uniqueWord = uniqueWord;
}
public boolean isRoot() {
return isRoot;
}
public void setRoot(boolean isRoot) {
this.isRoot = isRoot;
}
public boolean isDeepest() {
return isDeepest;
}
public void setDeepest(boolean isDeepest) {
this.isDeepest = isDeepest;
}
public int getNumInstance() {
return numInstance;
}
public void setNumInstance(int numInstance) {
this.numInstance = numInstance;
}
}
This little file should not be the reason for the OutOfMemory error.
Performance
That is no error, but if you want to read a whole file in the memory
don't read line per line and concatenate the strings. This slows down your programm.
You can use:
String myFile = new String(Files.readAllBytes(Paths.get("Dracula.txt")));
myFile = myFile.replaceAll("\r\n", " ");
return myFile;
That is also not superfast, but faster.
Now the Errors
word array is too large
public String[] breakIntoWords(String myFile) {
String[] words = new String[myFile.length()];
You define words as an array of lengh lenght of file . That is much too large if you
the name is mnemonic and means that you need an array of length count of words in file
nextWord is never resetted (Cause of OutOfMemory)
// Now pull only letters or numbers until we hit a space
while (!Character.isWhitespace(next)) {
if (Character.isLetterOrDigit(next)) {
nextWord += myFile.charAt(position);
}
position++;
next = myFile.charAt(position);
}
words[i] = nextWord;
i++;
because next word is never set to "" after assigning it to words[i]. So that next word grow
up word by word and your array contents looks like as:
words[0] = "Word1"
words[1] = "Word1Word2"
words[2] = "Word1Word2Word3"
As you can imagine, that will result in an very large amount of used space.
When you are building the tree, you are inserting nodes in the wrong side when you should insert the element to the right.
You should replace this code at BTree class:
while(temp != null) {
if(word.compareTo(temp.getMyWord()) < 0) {
if(temp.getRightChild() == null) {
temp.setRightChild(myNode); // <-- You were using setLeftChild()
nodeCount++;
return true;
} else {
temp = temp.getRightChild();
}
....
}
You are probably creating a huge tree with all the elements to the left side and getting the OutOfMemoryError
Add VM arguments :
-Xms<size> set initial Java heap size
-Xmx<size> set maximum Java heap size
-Xss<size> set java thread stack size
or run it using : java -Xmx256m yourclass.java
It depends on various factors.
Amount of java heap you are running with (default values differ for 32 bit and 64 bit JDK)
Size of the file you feed to the java program
You are trying to load entire contents of the file(i.e. stream object) into Java Memory. In such case, your file size limited(i.e small) Then above code will work in your limited memory but if the file size is increased(i.e. Contents of the file is increased). Then you will face issue.
You have to follow better approach to solve this problem by reading the file contents in chuck. Otherwise you will face same issue.
If you increase JVM arguments also won't work for larger files.
I feel your professor also testing the implementation of your project.

Error at Linked list (java)

I created my own linked list, but when I tried to run it there is an error:
Exception in thread "main" java.lang.NullPointerException
at List.add(List.java:8) //if(t.val ==null)
at main.main(main.java:38) //linput.add(inputLine.split(" ")[i]);
Here is my List class:
class List{
String val;
List next=null;
private List t;
public void add(String word){
if(t.val ==null)
t.val=word;
else while(!t.next.val.equals(null))
{
t=t.next;
if(t.next.val.equals(null))
{
t.next.val=word;
break;
}
}
}
public int get(String word)
{
int i=0;
if(t.val.equals(word))
i=0;
else while(!t.next.val.equals(word))
{
t=t.next;
i++;
if(t.next.val.equals(word))
{
i++;
}
}
return i;
}
public String indexOf(int i)
{
int counter=0;
while(counter<i)
{
t=t.next;
counter++;
}
return t.val;
}
}
And here is my main function :
static public void main(String[] args)
{
List linput = new List();
String inputLine = "Hey look at me.";
for(int i = 0 ; i < inputLine.split(" ").length ; i++)
{
linput.add(inputLine.split(" ")[i]);
}
System.out.println(linput.indexOf(0)+" "+linput.indexOf(1)+" "+linput.indexOf(2));
}
I initialized t but next time there is an error like this:
private List t =new List();
Exception in thread "main" java.lang.StackOverflowError
at List.<init>(List.java:5)
at List.<init>(List.java:5)
at List.<init>(List.java:5)
Sorry. I can't give my full code, because the rest of my code is working well (reading from txt etc....).
The error seems to be related to the variable 't' (i.e., private List t).
Did you initialize this variable ? The if (t.val == null) seems to be cribbing this as t is null (uninitialized) at this point
You should have allocated object (using new) for this variable.
Can you share the full code for the constructor of List ?
Assuming you want to implement a simple forward list, rather than use the Java LinkedList class, you need to:
Change your implementation of the list to reference nodes in the list
handle traversal of the linked nodes in your word list
Here is an example:
WordList class
package com.example.words;
class WordList {
private WordNode head = null;
private int listSize = 0;
public void add(String word) {
// TODO add check for duplicate word
if (head == null) {
head = new WordNode();
head.setValue(word);
listSize++;
} else {
WordNode current = head;
while (current.getNext() != null) {
current = current.getNext();
}
WordNode newNode = new WordNode();
newNode.setValue(word);
current.setNext(newNode);
listSize++;
}
}
public int getWordIndex(String word) {
WordNode current = head;
int index = 0;
boolean found = false;
while (!found && current != null) {
found = current.getValue().equalsIgnoreCase(word);
if (!found) {
index++;
current = current.getNext();
}
}
if (found) {
return index;
} else {
return -1;
}
}
public String indexOf(int i) {
int index = 0;
WordNode current = head;
if (i <= listSize) {
while (index < i) {
current = current.getNext();
index++;
}
return current.getValue();
} else {
return null;
}
}
public int size() {
return listSize;
}
}
WordNode Class
package com.example.words;
public class WordNode {
private String value;
private WordNode next = null;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public WordNode getNext() {
return next;
}
public void setNext(WordNode link) {
next = link;
}
}
Test Driver
package com.example.words;
public class Test {
public static void main(String[] args) {
//TODO handle punctuation
WordList myList = new WordList();
String inputLine = "Hey look at me.";
String[] pieces = inputLine.split(" ");
for (int i=0; i < pieces.length; i++) {
myList.add(pieces[i]);
}
for (int i=0; i < pieces.length; i++) {
String value = myList.indexOf(i);
if (value.equalsIgnoreCase(pieces[i])) {
System.out.println("Following node is wrong:");
}
System.out.println ("node " + i + ". = " + value);
}
}
}
You tried to create t as a member variable of its own class like this:
class List {
[...]
private List t = new List();
[...]
}
This won't work because the constructor of List would be called indefinitely.
Try lazy instantiation of t instead. Replace all access of t with a getter:
private List getT() {
if (this.t == null) {
this.t = new List();
}
return t;
}

Categories

Resources