Personalizado da lista ligada ter elementos indesejados
-
22-12-2019 - |
Pergunta
Eu fiz um personalizado da lista ligada e nó de aulas para a escola e eu decidi prática de como usá-lo fazendo um texto torcer como jogo
Na minha lista ligada de classe, eu tenho um transversal método que imprime a palavra e o tempo que a palavra é para o console.
O código que eu até agora é esse:
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");
}
}
}
e, finalmente, 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);
}
}
Quando eu executar este código, todas as listas ligadas (threeLetters
, fourLetters
, fiveLetters
, e sixLetters
) são completamente bem até o final, quando threeLetters.traverse()
é chamado, eu tenho esse saída (apenas a parte final)
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
Eu não consigo descobrir por que isso está ocorrendo, mas parece que ele está imprimindo tudo depois abe
e imprime abe
duas vezes, uma vez com ele registrar-se como 3 letras e uma vez como 8 letras!
Eu tenho o arquivo de texto a partir deste site:
Solução
O problema aqui é, principalmente, uma de design.A falha principal:a tentar utilizar uma instância MyNode
em várias listas ligadas.
Quando você InsertToHead(node)
você está modificando o conteúdo de node
em si, especificamente a cabeça e ao lado de referências.
Correção:Simples declarar um new MyNode
para cada LinkedList pretende usá-lo.Em seu projeto, especificamente, você está usando dois para um determinado nó. ll
e um dos <inset_number>Letters
listas.Para declarar uma nova MyNode
para cada lista:
...
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);
...
Isso deve resolver o seu problema.
Se você quiser saber POR que foi acontecendo.O código de rastreamento.Tem a ver com a tentativa de adicionar nós que já ter um pouco mais de nós ligados em uma lista.
Notas Adicionais:
Tente o seu melhor para evitar
public
campos, a menos que você tem CERTEZA de que deseja-los.I. E.noMyLinkedList
se alguém utilizar sua classe não deve ser capaz de acessar (ou até mesmo ver!) ocounter
,head
outail
, portanto , estes devem ser feitasprivate
.Se você realmente deseja acessar, criarget
eset
métodosO if aninhado no bloco
WordSort
é um lugar perfeito para um mudar como esta: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 funciona bem como uma classe separada.No entanto, eu muitas vezes optar por implementar uma classe simples como um nó como um classe aninhada.Ele pode fazer para algumas código limpo.Experimente!
Tenha cuidado ao projetar suas aulas.Há uma série de métodos extra em seu design.Pode ser fácil para chug à frente na criação de métodos que você pode ou não pode usar.Eu gostaria apenas de criar métodos de quando eu ver o que eu preciso-los em uma classe que utiliza a classe em questão.
Codificação Feliz!