我为学校制作了一个自定义链接列表和节点类,我决定通过制作类似文本的游戏来练习如何使用它
在我的链表类中,我有一个遍历方法,可以打印出单词以及单词进入控制台的时间。
到目前为止我的代码是:
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");
}
}
}
最后,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
)完全正常,直到最后,{{{ 1}}被调用,我得到这个输出(只有结束部分)
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
两次,一次注册为3个字母,一次为8字母很长!
我从这个网站获得了文本文件:
答案 0 :(得分:1)
这里的问题主要是设计问题。主要缺陷:尝试在多个链接列表中使用一个实例MyNode
。
当你InsertToHead(node)
修改node
本身的内容时,特别是头部和下一个引用。
修正:
对于要在其中使用的每个LinkedList,简单地声明new MyNode
。在您的项目中,您特别为任何给定节点使用两个。 ll
和其中一个<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
方法
WordSort
中的嵌套if块是switch这样的完美位置:
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可以作为一个单独的类正常工作。但是,我会多次选择将一个简单的类(如节点)实现为nested class。它可以使一些非常干净的代码。试试吧!
设计课程时要小心。您的设计中有许多额外的方法。可以很容易地提前创建您可能使用或不使用的方法。我喜欢在我看到在需要使用该类的类中需要它们时才创建方法。
快乐的编码!