不要な要素を含むカスタム リンク リスト
-
22-12-2019 - |
質問
学校用にカスタムのリンク リストとノード クラスを作成したので、テキストツイストのようなゲームを作成してその使い方を練習することにしました
私のリンク リスト クラスには、単語とその単語の長さをコンソールに出力する traverse メソッドがあります。
これまでのところ私が持っているコードはこれです:
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;
}
}
ワードソート.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");
}
}
}
そして最後に 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);
}
}
このコードを実行すると、すべてのリンクされたリスト (threeLetters
, fourLetters
, fiveLetters
, 、 そして sixLetters
)最後までまったく問題ありません。 threeLetters.traverse()
が呼び出されると、この出力が得られます(最後の部分のみ)
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
なぜそれが起こっているのかはわかりませんが、その後すべてを出力しているようです abe
そしてそれは印刷されます abe
2 回、1 回目は 3 文字として登録され、もう 1 回目は 8 文字として登録されます。
この Web サイトからテキスト ファイルを入手しました。
解決
ここでの問題は主にデザインの問題です。主な欠陥:1 つのインスタンスを使用しようとしています MyNode
複数のリンクされたリストで。
あなたが InsertToHead(node)
の内容を変更しています node
それ自体、具体的には head 参照と next 参照です。
修理:シンプルに宣言する new MyNode
使用する LinkedList ごとに。特にあなたのプロジェクトでは、特定のノードに対して 2 つを使用しています。 ll
そしてそのうちの1つ <inset_number>Letters
リスト。したがって、新しいことを宣言します MyNode
各リストについて:
...
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);
...
これで問題は解決するはずです。
なぜそれが起こったのか知りたい場合。コードをトレースします。これは、すでにいくつかのノードがアタッチされているノードをリストに追加しようとすることに関係しています。
その他の注意事項:
最善を尽くして避けてください
public
確実に必要な場合を除き、フィールドを削除してください。I.E.でMyLinkedList
あなたのクラスを使用している人は、counter
,head
またはtail
, 、したがって、それらを作成する必要がありますprivate
. 。本当にアクセスしたい場合は、get
そしてset
メソッドネストされた if ブロック
WordSort
に最適な場所です スイッチ このような: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 は別のクラスとして正常に動作します。ただし、私は多くの場合、ノードのような単純なクラスを実装することを選択します。 入れ子になったクラス. 。非常にきれいなコードを作成できます。やってみて!
クラスを設計するときは注意してください。設計には追加のメソッドがたくさんあります。使用するかどうかわからないメソッドを急いで作成してしまうのは簡単です。私は、問題のクラスを使用するクラスでメソッドが必要であるとわかった場合にのみメソッドを作成するようにしています。
コーディングを楽しんでください!