Cannot find symbol in Java recursion - java

I'm trying to help a friend implement a Trie structure in Java although my programming is not that great, let along my Java. I found an implementation here and tried to run it on IDEA IntelliJ.
The error I receive is,
Error:(87, 41) java: cannot find symbol
symbol: method getWords()
location: variable children of type com.company.TrieNode[]
I'm not sure where to start troubleshooting this error. I have a feeling it might have to do with the loop? I want to get the code running before I analyze it but this error is a hurdle.
I've already tried File > Invalidate Caches/Restart within IntelliJ but it comes up with the same error. I think this might be a Java problem.
The following is what I have (credits to the aforementioned link),
Main.java
package com.company;
public class Main {
public static void main(String[] args) {
Trie myTrie = new Trie();
myTrie.addWord("Khalid");
}
}
Trie.java
package com.company;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Khalid on 5 December.
*/
public class Trie
{
private TrieNode root;
/**
* Constructor
*/
public Trie()
{
root = new TrieNode();
}
/**
* Adds a word to the Trie
* #param word
*/
public void addWord(String word)
{
root.addWord(word.toLowerCase());
}
/**
* Get the words in the Trie with the given
* prefix
* #param prefix
* #return a List containing String objects containing the words in
* the Trie with the given prefix.
*/
public List getWords(String prefix)
{
//Find the node which represents the last letter of the prefix
TrieNode lastNode = root;
for (int i=0; i<prefix.length(); i++)
{
lastNode = lastNode.getNode(prefix.charAt(i));
//If no node matches, then no words exist, return empty list
if (lastNode == null) return new ArrayList();
}
//Return the words which eminate from the last node
return lastNode.getWords();
}
}
TrieNode.java
package com.company;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Khalid on 5 December.
*/
public class TrieNode {
private TrieNode parent;
private TrieNode[] children;
private boolean isLeaf; //Quick way to check if any children exist
private boolean isWord; //Does this node represent the last character of a word
private char character; //The character this node represents
/**
* Constructor for top level root node.
*/
public TrieNode() {
children = new TrieNode[26];
isLeaf = true;
isWord = false;
}
/**
* Constructor for child node.
*/
public TrieNode(char character) {
this();
this.character = character;
}
/**
* Adds a word to this node. This method is called recursively and
* adds child nodes for each successive letter in the word, therefore
* recursive calls will be made with partial words.
*
* #param word the word to add
*/
protected void addWord(String word) {
isLeaf = false;
int charPos = word.charAt(0) - 'a';
if (children[charPos] == null) {
children[charPos] = new TrieNode(word.charAt(0));
children[charPos].parent = this;
}
if (word.length() > 1) {
children[charPos].addWord(word.substring(1));
} else {
children[charPos].isWord = true;
}
}
/**
* Returns the child TrieNode representing the given char,
* or null if no node exists.
*
* #param c
* #return
*/
protected TrieNode getNode(char c) {
return children[c - 'a'];
}
/**
* Returns a List of String objects which are lower in the
* hierarchy that this node.
*
* #return
*/
protected List getWords() {
//Create a list to return
List list = new ArrayList();
//If this node represents a word, add it
if (isWord) {
list.add(toString());
}
//If any children
if (!isLeaf) {
//Add any words belonging to any children
for (int i = 0; i < children.length; i++) {
if (children[i] != null)
list.addAll(children.getWords());
}
}
return list;
}
/**
* Gets the String that this node represents.
* For example, if this node represents the character t, whose parent
* represents the charater a, whose parent represents the character
* c, then the String would be "cat".
*
* #return
*/
public String toString() {
if (parent == null) {
return "";
} else {
return parent.toString() + new String(new char[]{character});
}
}
}

Your code is trying to call getWords() on children, which is an array of TrieNode. Presumably the intent is to collect the result of each child node. Since you're already in a loop, you just need to update the code to reference the current item:
list.addAll(children[i].getWords());

Related

Evaluates the given postfix expression with stack

I am working to write code to Evaluate the given postfix expression. I have wrote a code, but one of the junit test doesn´t go through. How should i write that "expr contains too few operands". In the evalute I use a stack.
TODO: help to correct the "evaluate(String expr) throws ExpressionException ()" method so all the test in the testclass goes through.
EDIT: The test that i need help withy is the only in the JUNIT test class.
Interface stack:
/**
* A interface of stack
*/
public interface Stack <T> {
/**
* Adds the element to the top of the stack.
*/
void push (T elem);
/**
* Removes and returns the top element in stack,
* that is the element that was last added.
* Throws an EmptyStackException if stack is empty.
*/
T pop();
/**
* Returns the top element in the stack without removing it.
* Throws an EmptyStackException if stack is empty.
*/
T top();
/**
* Returns the number of elements in stack.
* #return the number of elements.
*/
int size();
/**
* Returns true if the stack is empty.
* #return true.
*/
boolean isEmpty();
}
Linkedlist implements stack:
import java.util.EmptyStackException;
import java.util.NoSuchElementException;
/**
* A singly linked list.
*
*/
public class LinkedList<T> implements Stack <T> {
private ListElement<T> first; // First element in list.
private ListElement<T> last; // Last element in list.
private int size; // Number of elements in list.
/**
* A list element.
*/
private static class ListElement<T>{
public T data;
public ListElement<T> next;
public ListElement(T data) {
this.data = data;
this.next = null;
}
}
/**
* Creates an empty list.
*/
public LinkedList() {
this.first = null;
this.last = null;
this.size = 0;
}
/**
* Inserts the given element at the beginning of this list.
*
* #param element An element to insert into the list.
*/
public void addFirst(T element) {
ListElement<T> firstElement = new ListElement<>(element);
if (this.size == 0){
this.first = firstElement;
this.last = firstElement;
}
else{
firstElement.next = this.first;
this.first = firstElement;
}
this.size ++;
}
/**
* Inserts the given element at the end of this list.
*
* #param element An element to insert into the list.
*/
public void addLast(T element) {
ListElement<T> lastElement = new ListElement<>(element);
if(this.size ==0){
this.first = lastElement;
}
else{
this.last.next = lastElement;
}
this.last = lastElement;
this.size ++;
}
/**
* #return The head of the list.
* #throws NoSuchElementException if the list is empty.
*/
public T getFirst() {
if (this.first != null){
return this.first.data;
}
else{
throw new NoSuchElementException();
}
}
/**
* #return The tail of the list.
* #throws NoSuchElementException if the list is empty.
*/
public T getLast() {
if(this.last != null){
return this.last.data;
}
else{
throw new NoSuchElementException();
}
}
/**
* Returns an element from a specified index.
*
* #param index A list index.
* #return The element at the specified index.
* #throws IndexOutOfBoundsException if the index is out of bounds.
*/
public T get(int index) {
if(index < 0|| index >= this.size){
throw new IndexOutOfBoundsException();
}
else{
ListElement<T>element = this.first;
for(int i = 0; i < index; i++){
element = element.next;
}
return element.data;
}
}
/**
* Removes the first element from the list.
*
* #return The removed element.
* #throws NoSuchElementException if the list is empty.
*/
public T removeFirst() {
if(this.first != null || this.size != 0){
ListElement<T> list = this.first;
this.first = first.next;
size --;
return list.data;
}
else{
throw new NoSuchElementException();
}
}
/**
* Removes all of the elements from the list.
*/
public void clear() {
this.first = null;
this.last = null;
this.size =0;
}
/**
* Adds the element to the top of the stock.
* #param elem
*/
#Override
public void push(T elem) {
ListElement <T> list = new ListElement<>(elem);
if( first == null){
first = list;
last = first;
} else{
list.next = first;
first = list;
}
size ++;
}
/**
* Removes and returns the top element in stack,
* that is the element that was last added.
* Throws an EmptyStackException if stack is empty.
* #return the top element in the stack.
*/
#Override
public T pop(){
if(isEmpty()){
throw new EmptyStackException();
}else{
ListElement <T> list = first;
first = first.next;
size --;
return list.data;
}
}
/**
* returns the top element in the stack without removing it.
* Throws an EmptyStackException if stack is empty.
* #return the top element.
*/
#Override
public T top() {
if(isEmpty()){
throw new EmptyStackException();
}else{
return first.data;
}
}
/**
* Returns the number of elements in the stock
* #return The number of elements in the stock.
*/
public int size() {
return this.size;
}
/**
* Note that by definition, the list is empty if both first and last
* are null, regardless of what value the size field holds (it should
* be 0, otherwise something is wrong).
*
* #return <code>true</code> if this list contains no elements.
*/
public boolean isEmpty() {
return first == null && last == null;
}
/**
* Creates a string representation of this list. The string
* representation consists of a list of the elements enclosed in
* square brackets ("[]"). Adjacent elements are separated by the
* characters ", " (comma and space). Elements are converted to
* strings by the method toString() inherited from Object.
*
* Examples:
* "[1, 4, 2, 3, 44]"
* "[]"
*
* #return A string representing the list.
*/
public String toString() {
ListElement<T> listOfElements = this.first;
String returnString = "[";
while(listOfElements != null) {
returnString += listOfElements.data;
if(listOfElements.next != null){
returnString += ", ";
}
listOfElements = listOfElements.next;
}
returnString += "]";
return returnString;
}
}
Postfix class:
import java.util.Scanner;
import java.util.Stack;
/**
* The Postfix class implements an evaluator for integer postfix expressions.
*
* Postfix notation is a simple way to define and write arithmetic expressions
* without the need for parentheses or priority rules. For example, the postfix
* expression "1 2 - 3 4 + *" corresponds to the ordinary infix expression
* "(1 - 2) * (3 + 4)". The expressions may contain decimal 32-bit integer
* operands and the four operators +, -, *, and /. Operators and operands must
* be separated by whitespace.
*
*/
public class Postfix {
public static class ExpressionException extends Exception {
public ExpressionException(String message) {
super(message);
}
}
/**
* Evaluates the given postfix expression.
*
* #param expr Arithmetic expression in postfix notation
* #return The value of the evaluated expression
* #throws ExpressionException if the expression is wrong
*/
public static int evaluate(String expr) throws ExpressionException {
expr = expr.trim();
String[] tokens = expr.split("\\s+");
if(expr.matches("(\\+)|(\\-)|(\\*)|(\\/)")){
throw new ExpressionException("");
}
LinkedList<Integer> stack = new LinkedList<>();
for(String token: tokens) {
if(isInteger(token)) {
int number = Integer.parseInt(token);
stack.push(number);
}
else if(isOperator(token)) {
String operator = token;
int b = stack.pop();
int a = stack.pop();
if(token.equals("+")){
stack.push(a+b);
} else if (token.equals("-")){
stack.push(a-b);
}
else if(token.equals("/")){
if( b == 0){
throw new ExpressionException("");
}
stack.push(a/b);
} else if(token.equals("*")){
stack.push(a*b);
}
}
else {
throw new ExpressionException("");
}
}
if(stack.size() != 1){
throw new ExpressionException("");
}
int result = stack.pop();
if(stack.isEmpty()) {
throw new ExpressionException("");
}
return result;
}
/**
* Returns true if s is an operator.
*
* A word of caution on using the String.matches method: it returns true
* if and only if the whole given string matches the regex. Therefore
* using the regex "[0-9]" is equivalent to "^[0-9]$".
*
* An operator is one of '+', '-', '*', '/'.
*/
private static boolean isOperator(String s) {
return s.matches("[-+*/]");
}
/**
* Returns true if s is an integer.
*
* A word of caution on using the String.matches method: it returns true
* if and only if the whole given string matches the regex. Therefore
* using the regex "[0-9]" is equivalent to "^[0-9]$".
*
* We accept two types of integers:
*
* - the first type consists of an optional '-'
* followed by a non-zero digit
* followed by zero or more digits,
*
* - the second type consists of an optional '-'
* followed by a single '0'.
*/
private static boolean isInteger(String s) {
return s.matches("(((\\-)*?[1-9](\\d+)*)|(\\-)*?0)");
}
}
Junit class
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.CoreMatchers.*;
import java.util.Arrays;
/**
* Test class for Postfix
*
*/
public class PostfixTest {
#Rule public Timeout globalTimeout = Timeout.seconds(5);
#Test
public void evaluateExceptionWhenExprContainsTooFewOperands() {
String[] expressions = {"1 +", " 1 2 + +"};
assertExpressionExceptionOnAll(expressions);
}
}
Your pop() method will throw an exception when the stack is empty (which you can catch) and your isEmpty() method will return true when the stack is empty. You can also use the size() method to check the number of items on the stack. As an example, you can use code like this to check if there are enough values to run your operand:
// ...
else if(isOperator(token)) {
String operator = token;
if (stack.size() < 2) {
throw new ExpressionException("There are not enough values on the stack to perform the operation");
}
int b = stack.pop();
int a = stack.pop();
// ...

Fibonacci Heap Extract Min Implementation Not Working

I am implementing Fibonacci Heap to improve on my Dijkstra's shortest path algorithm. My insert method works fine, and the next one I needed to do is extract-min. I am following CLRS. Please note some attributes mentioned in the book aren't in my implementation yet, as they are not needed for the functions so far, but I will add them later.
private static class FibonacciHeap {
/**
* Implementation of the node used in
* fibonacci heap. The nodes are stored
* as a circular doubly-linked list, making
* delete and insert operations easy, as
* well as being able to iterate through
* without being forced to keep track of the
* head
*/
private class Node {
/**
* The vertex this node is storing
*/
Vertex val;
/**
* Key used to know the order of vertices
*/
int key;
/**
* The left and right sibling in the list
*/
Node left, right;
/**
* Pointer to one of the child's
*/
Node child;
/**
* The amount of children this node has
*/
int degree;
/**
* Constructs a node with a value and key
*
* #param val the value of this node
* #param key the key of this node
*/
public Node(Vertex val, int key) {
this.val = val;
this.key = key;
}
/**
* Inserts a new node into this node's list.
* Inserts it to the left of this node, while
* maintaining the fact that it's circular
*
* #param newNode The new node to be inserted
*/
public void insert(Node newNode) {
newNode.left = left;
left.right = newNode;
newNode.right = this;
left = newNode;
if(newNode.key < min.key) {
min = newNode;
}
size++;
}
/**
* Removes this node from it's list
*/
public void remove() {
right.left = left;
left.right = right;
}
/**
* Inserts a new child into this nodes
* child list
*
* #param child The new node to be added as a child
*/
public void link(Node child) {
child.remove();
if(this.child == null) {
this.child = child;
} else {
this.child.insert(child);
}
degree ++;
}
/**
* Used for debugging. Will be removed after
* all operations work fine
*
* #return A string representation of this node
*/
#Override
public String toString() {
Node dummy = right;
StringBuilder sb = new StringBuilder();
sb.append(key).append(" -> (");
sb.append(dummy.child);
sb.append(") ");
while(dummy != this) {
sb.append(dummy.key).append(" -> (");
sb.append(dummy.child);
sb.append(") ");
dummy = dummy.right;
}
return sb.toString();
}
}
/**
* Pointer to the node with the smallest key
*/
private Node min;
/**
* Stores the number of nodes in the heap
*/
private int size;
/**
* Creates an empty Fibonacci Heap
*/
public FibonacciHeap() { }
/**
* Gets and returns the key with the
* smallest value
*
* #return the key with the smallest value
*/
public int getMin() {
if(min == null) {
throw new NoSuchElementException("Empty Fibonacci Heap");
}
return min.key;
}
/**
* Inserts a vertex along with a key. The
* key is the one used to measure whether
* this vertex is lesser than another
*
* #param vertex vertex to be added
* #param key key of the vertex
*/
public void insert(Vertex vertex, int key) {
if(min == null) {
min = new Node(vertex, key);
min.left = min;
min.right = min;
size = 1;
} else {
min.insert(new Node(vertex, key));
}
}
/**
* Removes the node with the smallest key from
* the heap, and updates the minimum node if needed
*
* #return The node with the smallest key prior to this method call
*/
public Vertex extractMin() {
if(isEmpty()) {
throw new NoSuchElementException("Empty Fibonacci Heap");
}
Vertex toReturn;
if(min == null) {
toReturn = null;
} else {
toReturn = min.val;
if(min.right == min) {
min = null;
} else {
min.remove();
min = min.right;
consolidate();
}
}
return toReturn;
}
/**
* Consolidates the heap. Consolidation is the process
* making every node in the root list have it's own
* unique degree. That is, every node in the top most
* layer has a unique amount of children
*/
private void consolidate() {
Node[] degrees = new Node[size];
degrees[min.degree] = min;
Node tempMin, dummy = (tempMin = min).right;
while(dummy != tempMin) {
if(dummy.key < min.key) {
min = dummy;
}
while(degrees[dummy.degree] != null) {
Node other = degrees[dummy.degree];
if(other.key < dummy.key) {
Node temp = dummy;
dummy = other;
other = temp;
}
dummy.link(other);
degrees[dummy.degree - 1] = null;
}
degrees[dummy.degree] = dummy;
}
}
/**
* Returns true if and only if the
* heap is empty
*
* #return if the heap is empty
*/
public boolean isEmpty() {
return min == null;
}
/**
* A string representation of this
* heap. Format of string is:
* node1 -> (node1.child.toString()) node2 -> (node2.child.toString()) ... noden -> (noden.child.toString())
* The string representation of the
* heap is the string representation of
* the minimum node
*
* #return A string representation of this heap
*/
#Override
public String toString() {
return min.toString();
}
}
This is the stack trace that it gives:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 10
at GraphTheory.ShortestPathAlgorithms.DijkstraShortestPath$FibonacciHeap.consolidate(DijkstraShortestPath.java:362)
at GraphTheory.ShortestPathAlgorithms.DijkstraShortestPath$FibonacciHeap.extractMin(DijkstraShortestPath.java:338)
at GraphTheory.ShortestPathAlgorithms.DijkstraShortestPath.main(DijkstraShortestPath.java:104)
The main error is given in the conditional statement of the inner while loop in the consolidate function. I also commented the line in the code. What is going wrong? My main testing method insert 10 random numbers from 1 - 10, and then extracts the minimum until it's empty. The error occurs the first time extract-min is called.
public static void main(String[] args) {
FibonacciHeap f = new FibonacciHeap();
StringBuilder sb = new StringBuilder();
for(int i = 0; i < 10; i ++) {
f.insert(new Vertex(i), (int) (Math.random() * 10));
}
while(!f.isEmpty()) {
System.out.println(f.extractMin());
}
}
Can't pinpoint the exact bug. But, I can tell you from experience that you should not find the minimum while consolidating. You consolidate and then you find the new minimum. You might get into trouble when you have multiple nodes with the same key and the one pointed to by min doesn't end up in the root list.
Also, while testing, don't use a random function. Create an array of arbitrary numbers and insert elements from the array into the heap.
I also don't understand how your implementation handles there being only one heap ordered tree in the Fib heap. What happens when you do an extract-min then?
You can find my Python implementation here if you need it.

Implementing LinkedList.java class to My Main Driver class to use the get and remove method?

I am currently doing a code that tries to implement a separate LinkedList.java class to my main driver class.
After doing that I will then show the output and ask the user to remove one of the elements stored inside the linkedlist and then show the output again showing the changes.
Question
How Do I implement or use the LinkedList.Java with my main driver class to get and then use the remove method ? Do I still have to use the add method?
I just don't know How the format would look like. Tried copy pasting the LinkedList class but I get an error.
Here is my code:
import java.util.Scanner;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.List;
import java.io.*;
import java.util.LinkedList;
import java.io.InputStreamReader;
public class TestingCode {
//private List<HawaiiNativeForestBirds> listofBirds = new LinkedList<HawaiiNativeForestBirds>();
//private String database = new String("birds3.csv");
/**
* The main method starts the program
*
*#param args is the input file
*/
public static void main(String[] args) {
//error checking for commandline input
if(args.length != 1){
System.out.println("Please enter at least one input file into the argument.");
//terminates the program if more than 1 is entered
System.exit(1);
}
String csvFile = args[0];
String line = "";
String cvsSplitBy = ",";
List<HawaiiNativeForestBirds> listofBirds = new LinkedList<HawaiiNativeForestBirds>();
try (BufferedReader br = new BufferedReader(new FileReader(csvFile))) {
while ((line = br.readLine()) != null) {
// use comma as separator
String[] bird = line.split(cvsSplitBy);
HawaiiNativeForestBirds Hawaiinbird= new HawaiiNativeForestBirds(bird[0],bird[1],bird[2],Integer.valueOf(bird[3]));
listofBirds.add(Hawaiinbird);
}
}
catch (IOException e) {
e.printStackTrace();
}
// Display the actual values
HawaiiNativeForestBirds[] hbirds=new HawaiiNativeForestBirds[listofBirds.size()];
int i=0;
hbirds= listofBirds.toArray(new HawaiiNativeForestBirds[listofBirds.size()]);
System.out.println("Display HawaiiNativeForestBirds linked list after adding objects from the input file into a linked list:");
System.out.println("index " + "name "+ " Scientific Name "+ " Color " + " Population");
i=0;
for (HawaiiNativeForestBirds hbird:hbirds){
i++;
System.out.println(i+" "+hbird.toString());
}
//remove method that asks the user for input on which row to delete
// get user input
try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))){
String input;
int num;
Scanner sc = new Scanner(System.in);
while (( input = br.readLine()) != null){
System.out.print("Enter the row number of the item you wish to delete: ");
num=sc.nextInt();
if (num <= 0) {
System.out.println("ERROR: The row number cannot be negative or zero.");
}
// check for row number too big
else if (num > listofBirds.size() + 1) {
System.out.println("ERROR: The row number is too big for the list.");
}
else {
for(int x=0;x<num;i++) {
listofBirds.delete(num);
}//for
}//else
}//while
}
catch (IOException e) {
e.printStackTrace();
}
// Display values again with the deleted row of data
hbirds= listofBirds.toArray(new HawaiiNativeForestBirds[listofBirds.size()]);
System.out.println("Display HawaiiNativeForestBirds linked list after deleting a row of objects from the linked list:");
System.out.println("index " + "name "+ " Scientific Name "+ " Color " + " Population");
i=0;
for (HawaiiNativeForestBirds hbird:hbirds){
i++;
System.out.println(i+" "+hbird.toString());
}
} // end of main
} //end of class
/**
* Class HawaiianNativeForestBirds stores and displays the data for each HawaiianTheme object
*
*
*/
class HawaiiNativeForestBirds {
private String name;
private String scientificname;
private String color;
private Integer population;
public HawaiiNativeForestBirds(){
}
//constructor - used to initialize the four data fields
/**
* Stores the name,scientific name, color and population of the Hawaiian Birds
*
*
* #param name is the name of the birds from the linked list
* #param scientificname is the scientific name of the birds in the linked list
* #param color is the color of each of the birds in the linked list
* #param population is the total number of birds in the linked list
*/
public HawaiiNativeForestBirds(String name, String scientificname,
String color, Integer population) {
super();
this.name = name;
this.scientificname = scientificname;
this.color = color;
this.population = population;
}
/**
* Gets each bird's name
*
* #return the birds name
*/
public String getName() {
return name;
}
/**
* Sets each birds name
*
* #param name is the bird's name
*/
public void setName(String name) {
this.name = name;
}
/**
* Gets the bird's scientific name
*
* #return the bird's scientific name
*/
public String getScientificname() {
return scientificname;
}
/**
* Sets the birds scientific name
*
* #param scientificname is the bird's scientific name
*/
public void setScientificname(String scientificname) {
this.scientificname = scientificname;
}
/**
* Gets the bird's color
*
* #return the bird's color
*/
public String getColor() {
return color;
}
/**
* Sets the bird's color
*
* #param color is the bird's color
*/
public void setColor(String color) {
this.color = color;
}
/**
* Gets the bird's population
*
* #return total population of the bird
*/
public Integer getPopulation() {
return population;
}
/**
* Sets the bird's population
*
* #param population is the total population of the bird
*/
public void setPopulation(Integer population) {
this.population = population;
}
/**
* Display the output
*
* #return the name, scientificname, color, and population of the bird
*/
public String toString() {
String output = name +" "+ scientificname + " "+ color +" "+ population;
return output;
}//end of toString
}// end of class
Here are my LinkedList.java, ListInterface.java, Node.Java and ListException.java that I will be trying to implement to my main driver which are all separate.
public class LinkedList<T> implements ListInterface<T> {
// reference to first node in the linked list (linked nodes)
protected Node<T> head = null;
// Total number of items, which is used
// for error checking and node removal.
protected Integer size = new Integer(0);
public LinkedList() {
// no code, because data fields already initialized
}
/**
* Adds an item (of any class) to the end of the list
*
* #param item
* is the object that is added to the list
*/
public void add(T item) {
// case 1: if empty list
if (head == null) {
// list is empty, so add to beginning of list
// make new node and assign to head of list
head = new Node<T>(item, null);
}
// if not empty list
else {
// case2: add to end of list
// current starts at 2nd node in list
Node<T> previous = head;
Node<T> current = head.getNext();
// while not at end of list
while (current != null) {
// advance to next node
previous = current;
current = current.getNext();
}
// Add new node to end of list:
// Make new node that has "null" for next.
// A node with "null" is always the last node
Node<T> node = new Node<T>(item, null);
// Point previous node (last node) to new node
previous.setNext(node);
}
// increase size of list
size++;
}
/**
* Gets an item (address to an item) from any position in the list.
*
* #param position
* The position of an item in the list.
* #returns the address to the requested item
* #exception ListException
* if an item does not exist at that position
*/
public T get(Integer position) throws ListException {
// check if empty list
if (head == null) {
throw new ListException("Cannot get an item from an empty list!");
}
// if position is outside range, throw exception
if (position < 1 || position > size) {
throw new ListException(position + " is outside list range!");
}
// Find node:
// counter to keep track of loops
Integer counter = new Integer(1);
// point to current node
Node<T> current = head;
while (!counter.equals(position)) {
// BAD CODE: while(counter != position){
// goto next node for current pointer
current = current.getNext();
// add 1 to counter
counter++;
}
// return the data (item) stored by the node
return current.getData();
}
/**
* Removes an item at any position from the list.
*
* #param position
* The position of an item in the list.
* #exception ListException
* if an item does not exist at that position
*/
public void remove(Integer position) throws ListException {
// check if empty list
if (head == null) {
throw new ListException("cannot remove from empty list");
}
// if position is outside range, throw exception
if (position < 1 || position > size) {
throw new ListException(position + " is outside list range.");
}
// if at beginning of list
if (position.equals(1)) {
// remove 1st node
head = head.getNext();
}
// if not at beginning of list
else {
// Find node:
// point previous to 1st node
Node<T> previous = head;
// point current to 2nd node
Node<T> current = head.getNext();
// loop position-2 number of times
for (int i = 2; i < position; i++) {
// goto next node for previous and current
previous = current;
current = current.getNext();
}
// Point the previous node to node after current node.
// This "skips" over one node, thus removing it!
previous.setNext(current.getNext());
}
// decrease size of list
size--;
}
/**
* Automatically called by println() or print()
*
* #return a String of the List in CSV (comma separated values) format
*/
public String toString() {
// instantiate empty string
String csvFormat = new String("");
// display position of each item to user
Integer position = new Integer(1);
// loop through all the nodes in linked list
for (Node<T> current = head; current != null; current = current
.getNext()) {
// keep adding to end of string
csvFormat = csvFormat + position + ", " + current.toString() + "\n";
// add one to position for each loop
position++;
}
return csvFormat;
}
/**
* This Is An "Accessor" Method - Used To Get A Data Field.
*
* #return the size of the list
*/
public Integer getSize() {
return size;
}
}// end of class
public interface ListInterface<T> {
/**
* Adds an item (of any class) to the list
*
* #param item
* is the object that is added to the list
*/
public void add(T item);
/**
* Gets an item (address to an item) from the list.
*
* #param position
* The position of an item in the list.
* #returns the address to the requested item
* #exception ListException
* if an item does not exist at that position
*/
public T get(Integer position) throws ListException;
/**
* Removes an item from a list.
*
* #param position
* The position of an item in the list.
* #exception ListException
* if an item does not exist at that position
*/
public void remove(Integer position) throws ListException;
/**
* This Is An "Accessor" Method - Used To Get A Data Field.
*
* #return the size of the list
*/
public Integer getSize();
}// end of interface
public class Node<T> {
// data fields (reference variables)
// data stores an object of any class
private T data;
// next points to the next node
private Node<T> next;
/**
* Constructor - Used To Create EAch Object & Initialize DAta Fields.
*
* #param data2
* initializes the data reference variable.
* #param next2
* initializes the next reference variable..
*/
public Node(T data2, Node<T> next2) {
data = data2;
next = next2;
}
/**
* Used to Display The Data Stored In EAch Node.
*
* #return a String for the data
*/
public String toString() {
return data.toString();
}
/**
* This Is An "Accessor" Method - Used To Get A Data Field.
*
* #return the data
*/
public T getData() {
return data;
}
/**
* This Is An "Accessor" Method - Used To Get A Data Field.
*
* #return the address to the next node
*/
public Node<T> getNext() {
return next;
}
/**
* This Is A "Mutator" Method - Used To Set A Data Field.
*
* #param data2
* is a pointer to an object.
*/
public void setData(T data2) {
data = data2;
}
/**
* This Is A "Mutator" Method - Used To Set A Data Field.
*
* #param next2
* is a pointer to the next node.
*/
public void setNext(Node<T> next2) {
next = next2;
}
} // end of class
public class ListException extends RuntimeException {
/**
* #param message
* describes the exact cause of the error.
*/
public ListException(String message) {
super(message);
}// end of constructor
}// end of class
Hopefully someone can help me out on this :(

Checking if a linked List a Palindrome using a Node Class

I have a project issue where I need to check if a linked list is a palindrome, the same forward as it is backward. I was given a class titled a Node class that contains specific information that I am not allowed to change so I must use what I have in that class and cant write more there to help me. My problem is I can get through the list, but I don't know how to go backwards through and compare values.
Disclaimer: I don't want a complete answer just tips/ideas!
Here is the class I can't change and have to work with:
class Node {
/**
* The value stored in the node.
*/
public Character value;
/**
* A pointer to the next node in
* the list.
*/
public Node next;
/**
* A pointer to the previous node
* in the list. (Note: having this
* pointer makes this a "doubly linked"
* list.
*/
public Node prev;
/**
* A constructor to set up a
* node with a value.
*
* #param value the value to put in the node
*/
public Node(Character value) {
this.value = value;
}
/**
* A constructor to set up a
* node with a value and a pointer
* to the previous node (so I can
* append items easily in my test
* code).
*
* #param value the value to put in the node
* #param prev the previous node in the list
*/
public Node(Character value, Node prev) {
this.value = value;
this.prev = prev;
}
/**
* Sets the next node in the list.
*
* #param n the next node in the list
*/
public void setNext(Node n) {
next = n;
}
/**
* Sets the previous node in the list.
*
* #param n the previous node in the list
*/
public void setPrev(Node n) {
prev = n;
}
}
So far this is what I have and I am just trying whatever I can:
public static boolean listPalindrome(Node input) {
if(input == null)
{
throw new IllegalArgumentException();
}
int count = 0;
while(input.next != null)
{
count++;
}
Node holder = new Node(null, input.next);
for(int i = 0;i<count;i++)
{
if(input.next != null)
{
break;
}
else
{
}
}
return false; //replace this
}
Please help!
Thanks!
You have an infinite loop with count++. input.next will always be non-null since you aren't updating the value of input in the loop.
If you were to get past that there is no reason to declare a new Node in your code. The loop you have also will break on the first iteration assuming the linked list is a size > 0, you should instead check input.next == null but put it at the end of the loop.
Also noting that your a GMU student it would be an honor code violation for me to help you any more than this ;)

Checking if elements are already in a Java array

The project I am working on right now involves me reading words from a text file and loading them into an array (and eventually a binary tree, but that will be finished later). I must load both the word and the word's frequency (initially 1) into the array, so I have packed both variables into an object WordNode. I am able to load the words into the array, but things fall apart when I try to check if a word is already in the array. If it is, I must increase the frequency by 1. However, my code does not even check the word and simply adds it anyway (I presume it's checking the reference to the variable and not the word itself). Below is my main method and the WordNode class.
Main method:
public class Driver {
/////////////// fields ///////////////
public static ArrayUnorderedList<WordNode> wordArray = new ArrayUnorderedList<WordNode>();
public static LinkedBinarySearchTree<WordNode> wordTree = new LinkedBinarySearchTree<WordNode>(); //tree to hold words
/////////////// methods ///////////////
public static void main(String[] args) throws Exception {
//ask for filename
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter the name of the file to read from: ");
Reader file = new FileReader(reader.readLine());
//read file
Scanner input = new Scanner(file);
while(input.hasNext()) {
//get words from file
String word = input.next();
//remove non-word characters and convert to lowercase
word = word.replaceAll("\\W", "");
word = word.toLowerCase();
//create node
WordNode newWord = new WordNode(word);
//if word is already in array
if(wordArray.contains(newWord)) {
System.out.println("Word is already in array");
//increment frequency by 1
int index = wordArray.find(newWord);
wordArray.list[index].setFrequency(wordArray.list[index].getFrequency() + 1);
System.out.println(newWord.getWord() + newWord.getFrequency());
} else {
System.out.println("Word is not yet in array");
//add word to tree
System.out.println(newWord.getWord());
wordArray.addToRear(newWord);
}
}
//insert into tree
//perform traversals on tree
}
WordNode class:
public class WordNode {
protected String word;
protected WordNode left, right;
protected int frequency;
/**
* Creates a new node with the specified data.
* #param obj the element that will become a part of the new node
*/
WordNode(String obj) {
word = obj;
left = null;
right = null;
frequency = 1;
}
/**
* Gets the word.
* #return the word
*/
public String getWord() {
return word;
}
/**
* Sets the word.
* #param word the word to set
*/
public void setWord(String word) {
this.word = word;
}
/**
* Gets the left.
* #return the left
*/
public WordNode getLeft() {
return left;
}
/**
* Sets the left.
* #param left the left to set
*/
public void setLeft(WordNode left) {
this.left = left;
}
/**
* Gets the right.
* #return the right
*/
public WordNode getRight() {
return right;
}
/**
* Sets the right.
* #param right the right to set
*/
public void setRight(WordNode right) {
this.right = right;
}
/**
* Gets the frequency.
* #return the frequency
*/
public int getFrequency() {
return frequency;
}
/**
* Sets the frequency.
* #param frequency the frequency to set
*/
public void setFrequency(int frequency) {
this.frequency = frequency;
}
}
Some methods from the ArrayList class:
/**
* Returns true if this list contains the specified element.
* #param target the element that the list is searched for
* #return true if the target is in the list, false if otherwise
*/
public boolean contains(T target) {
return (find(target) != NOT_FOUND);
}
/**
* Returns the array index of the specified element, or the
* constant NOT_FOUND if it is not found.
* #param target the element that the list will be searched for
* #return the integer index into the array containing the target element, or the NOT_FOUND constant
*/
public int find(T target) {
int scan = 0, result = NOT_FOUND;
boolean found = false;
if (!isEmpty()) {
while (!found && scan < rear) {
if (target.equals(list[scan])) {
found = true;
} else {
scan++;
}
}
}
if (found) {
result = scan;
}
return result;
}
The immediate reason your code doesn't work is that ArrayUnorderedList#contains() probably relies on the equals() method to determine if the entry is in the list. Without seeing the definition of the class it's impossible to know.
Since you haven't provided an override of equals(), it's using object identity (the default from Object) so every WordNode is distinct from every other WordNode.
If you want to use ArrayUnorderedList then you must implement WordNode#equals() with the correct behavior.
However, you should consider using a Map<String,Integer> (or Map<String,WordNode>) instead to store the frequencies. This will be much faster.
You need to override eqauls in your WordNode:
public boolean equals(Object o) {
if(o instanceof WordNode) {
WordNode temp = (WordNode) o;
return(temp.getWord().equals(this.word));
}
else
System.out.println("Object o you passed is not a WordNode");
}
This way if two different WordNode object has the same String as word field they are considered equals
how to call the equals:
WordNode n1 = new WordNode();
n1.setWord("test");
WordNode n2 = new WordNode();
n2.setWord("test");
System.out.println(n1.equals(n2));
So the equals receives an object of type Object but when you call the equals on a WordNode you havo to provide an object which is instance of WordNode too otherwise the cast i made fails (your exception) and of course it makes no sense to verify if an Object is equal to a WordNode

Categories