Benutzerdefinierte verknüpfte Liste mit unerwünschten Elementen
-
22-12-2019 - |
Frage
Ich habe eine benutzerdefinierte verknüpfte Liste und Knotenklassen für die Schule erstellt und beschlossen, die Verwendung zu üben, indem ich ein Texttrip-ähnliches Spiel mache
In meiner Klasse für verknüpfte Listen habe ich eine Traverse-Methode, die das Wort und die Länge des Wortes in der Konsole ausgibt.
Der Code, den ich bisher habe, ist dieser:
Meine verlinkte Liste.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());
}
}
}
Mein KnOten.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;
}
}
Wortsortierung.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");
}
}
}
und schließlich Fahrer.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);
}
}
Immer wenn ich diesen Code ausführe, werden alle verknüpften Listen (threeLetters
, fourLetters
, fiveLetters
, und sixLetters
) sind bis zum Schluss völlig in Ordnung, wenn threeLetters.traverse()
wird aufgerufen, bekomme ich diese Ausgabe (nur den Endteil)
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
Ich kann anscheinend nicht herausfinden, warum es auftritt, aber es sieht so aus, als würde danach alles ausgedruckt abe
und es druckt abe
zweimal, einmal mit 3 Buchstaben und einmal mit 8 Buchstaben Länge!
Ich habe die Textdatei von dieser Website erhalten:
Lösung
Ihr Problem hier ist hauptsächlich eines des Designs.Der Hauptfehler:versuch, eine Instanz zu verwenden MyNode
in mehreren verknüpften Listen.
Wenn Sie InsertToHead(node)
sie ändern den Inhalt von node
selbst, insbesondere der Kopf und die nächsten Referenzen.
Beheben:Einfach deklarieren a new MyNode
für jede verknüpfte Liste, in der Sie sie verwenden möchten.In Ihrem Projekt verwenden Sie speziell zwei für einen bestimmten Knoten. ll
und einer der <inset_number>Letters
Kundenliste.Also deklariere ein neues MyNode
für jede Liste:
...
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);
...
Das sollte dein Problem beheben.
Wenn du wissen willst, WARUM es passiert ist.Verfolgen Sie den Code.Es hat mit dem Versuch zu tun, Knoten, an die bereits weitere Knoten angehängt sind, zu einer Liste hinzuzufügen.
Zusätzliche Anmerkungen:
Versuchen Sie Ihr Bestes, um zu vermeiden
public
felder, es sei denn, Sie sind SICH SICHER, dass Sie sie möchten.Z.B.inMyLinkedList
jemand, der Ihre Klasse benutzt, sollte nicht in der Lage sein, darauf zuzugreifen (oder sogar zu sehen!) dercounter
,head
odertail
, also sollten diese gemacht werdenprivate
.Wenn Sie wirklich darauf zugreifen möchten, erstellen Sieget
undset
MethodenIhr verschachtelter if-Block in
WordSort
ist ein perfekter Ort für eine Schalter wie das: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 funktioniert gut als separate Klasse.Ich werde mich jedoch oft dafür entscheiden, eine einfache Klasse wie einen Knoten als zu implementieren verschachtelte Klasse.Es kann für einen sehr sauberen Code sorgen.Probieren Sie es aus!
Seien Sie vorsichtig beim Entwerfen Ihrer Klassen.Es gibt viele zusätzliche Methoden in Ihrem Design.Es kann einfach sein, Methoden zu entwickeln, die Sie möglicherweise jemals verwenden oder nicht.Ich möchte Methoden nur erstellen, wenn ich sehe, dass ich sie in einer Klasse benötige, die die betreffende Klasse verwendet.
Viel Spaß beim Codieren!