Question

I have made a custom linked list and node classes for school and I have decided to practice how to use it by making a text-twist like game

In my linked list class, I have a traverse method which prints out the word and how long the word is into the console.

The code I have so far is this:

MyLinkedList.java

package game;

public class MyLinkedList {
    public int counter;
    public MyNode head;
    public MyNode tail;

    public MyLinkedList() {
        counter = 0;
    }

    public void InsertToHead(MyNode m) {
        if (counter == 0) {
            head = tail = m;
        } else {
            m.setNext(head);
            head.setPrev(m);
            head = m;
        }
        counter++;
    }

    public int size() {
        return counter;
    }

    public boolean isEmpty() {
        if (counter == 0) {
            return true;
        } else {
            return false;
        }
    }

    public MyNode retrieveWord(String s) {
        MyNode n = head;
        while (n.next != null) {
            if (s.equals(n.getWord())) {
                return n;
            } else {
                n = n.next;
            }
        }
        if (s.equals(tail.getWord())) {
            return tail;
        }
        return null;
    }

    public MyNode retrieveLength(int l) {
        MyNode n = head;
        while (n.next != null) {
            if (l == n.getLength()) {
                return n;
            } else {
                n = n.next;
            }
        }
        if (l == tail.getLength()) {
            return tail;
        }
        return null;
    }

    public void traverse() {
        MyNode n = head;
        if (head != null) {
            while (n.next != null) {
                System.out.println(n.getWord() + "\t" + n.getLength());
                n = n.next;
            }
            System.out.println(tail.getWord() + "\t" + n.getLength());
        }
    }
}

MyNode.java

package game;

public class MyNode {

    public String word;
    public int length;
    public MyNode next, previous;

    public MyNode() {
        word = null;
        length = 0;
        next = null;
        previous = null;
    }

    public MyNode(String w, int l) {
        word = w;
        length = l;
        next = null;
        previous = null;
    }

    public void setNext(MyNode n) {
        next = n;
    }

    public void setPrev(MyNode n) {
        previous = n;
    }

    public void toHead(MyNode n){
        while(n.previous != null){
            n.setPrev(n);
        }
    }
    public void setWord(String w){
        word = w;
    }
    public String getWord(){
        return word;    
    }
    public void setLength(int l){
        length = l;
    }
    public int getLength(){
        return length;
    }
    public boolean hasNext(){
        return next != null;
    }
}

WordSort.java

package game;

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

public class WordSort {
Scanner wordScan;

public WordSort() {
    MyLinkedList sixLetters = new MyLinkedList();
    MyLinkedList fiveLetters = new MyLinkedList();
    MyLinkedList fourLetters = new MyLinkedList();
    MyLinkedList threeLetters = new MyLinkedList();
    MyLinkedList rejects = new MyLinkedList();
    try {
        wordScan = new Scanner(new File("corncob_lowercase.txt"));
        wordScan.useDelimiter("\r\n");
        MyLinkedList ll = new MyLinkedList();
        while (wordScan.hasNext()) {
            String temp = wordScan.next();
            MyNode node = new MyNode();
            node.setWord(temp);
            node.setLength(temp.length());
            ll.InsertToHead(node);
            if (temp.length() == 6) {
                sixLetters.InsertToHead(node);
            } else if (temp.length() == 5) {
                fiveLetters.InsertToHead(node);
            } else if (temp.length() == 4) {
                fourLetters.InsertToHead(node);
            } else if (temp.length() == 3) {
                threeLetters.InsertToHead(node);
            } else {
                rejects.InsertToHead(node);
            }
        }
        wordScan.close();
        threeLetters.traverse();
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        System.out.println("Missing File: corncob_lowercase.txt");
    }
}
}

and finally, Driver.java

package game;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Driver extends JPanel {
private static final long serialVersionUID = 1L;

public Driver() {
    new WordSort();
}

public static void main(String[] args) {
    JFrame frame = new JFrame("Hidden Word");
    frame.setSize(500, 500);
    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setContentPane(new Driver());
    frame.setVisible(true);
}
}

Whenever I run this code, all the linked lists (threeLetters, fourLetters, fiveLetters, and sixLetters) are completely fine until the very end, when threeLetters.traverse() is called, I get this output (only the end portion)

act 3
ace 3
aby 3
abe 3
abducts 7
abductors   9
abductor    8
abductions  10
abduction   9
abducting   9
abducted    8
abdominal   9
abdomens    8
abdomen 7
abdication  10
abdicating  10
abdicates   9
abdicated   9
abdicate    8
abbreviations   13
abbreviation    12
abbreviating    12
abbreviates 11
abbreviated 11
abbreviate  10
abattoirs   9
abattoir    8
abatement   9
abashed 7
abasement   9
abandons    8
abandonment 11
abandoned   9
abandon 7
abalone 7
aardwolf    8
abe 8

I can't seem to find out why it's occurring, but it looks like it's printing out everything after abe and it prints abe twice, once with it registering as 3 letters and once as 8 letters long!

I got the text file from this website:

http://www.mieliestronk.com/corncob_lowercase.txt

Was it helpful?

Solution

Your problem here is mainly one of design. The main flaw: attempting to use one instance MyNode in multiple linked lists.

When you InsertToHead(node) you're modifying the contents of node itself, specifically the head and next references.

Fix: Simple declare a new MyNode for each LinkedList you want to use it in. In your project specifically you're using two for any given node. ll and one of the <inset_number>Letters lists. So declare a new MyNode for each list:

...
while (wordScan.hasNext()) {
    String temp = wordScan.next();
    MyNode node = new MyNode();
    MyNode node2 = new MyNode();
    node.setWord(temp);
    node2.setWord(temp);
    node.setLength(temp.length());
    node2.setLength(temp.length());
    ll.InsertToHead(node2);
...

That should fix your problem.

If you want to know WHY it was happening. Trace the code. It has to do with attempting to add nodes that already have some more nodes attached into a list.

Additional Notes:

  • Try your best to avoid public fields unless you're SURE you want them. I.E. in MyLinkedList someone using your class shouldn't be able to access (or even see!) the counter, head or tail, so those should be made private. If you really want to access them, create get and set methods

  • Your nested if block in WordSort is a perfect place for a switch like this:

        switch(temp.length()) {
        case 6:
            sixLetters.InsertToHead(node);
            break;
        case 5:
            fiveLetters.InsertToHead(node);
            break;
        case 4:
            fourLetters.InsertToHead(node);
            break;
        case 3:
            threeLetters.InsertToHead(node);
            break;
        default:
            rejects.InsertToHead(node);
            break;              
        }
    
  • MyNode works fine as a separate class. However I will many times choose to implement a simple class like a node as a nested class. It can make for some very clean code. Try it out!

  • Be careful when designing your classes. There are a lot of extra methods in your design. It can be easy to chug ahead creating methods you may or may not ever use. I like to only create methods when I see that I need them in a class that uses the class in question.

Happy Coding!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top