2013-02-24 3 views
1

Мне нужно написать метод, который возвращает число - количество раз, когда элемент находится в связанном списке. Пока что у меня есть;LinkedList - loop not working - Java

package Question4; 

import net.datastructures.Node; 

public class SLinkedListExtended<E> extends SLinkedList<E> { 
    // returns the number of occurrences of the given element in the list 
    public int count(E elem) { 

     Node<E> cursor = tail; 
    int counter = 0; 

    if ((cursor != null) && (!(cursor.getElement().equals(elem)))) { //tail isnt null and element is not equal to elem 

     cursor = cursor.getNext(); //go to next node 

    } else if ((cursor != null) && (cursor.getElement().equals(elem))){ //cursor isn't null and element equals elem 

     counter++; //increment counter 
    } 
    else { 
     return counter; //return counter 
    } 
    return counter; 
} 


public static void main(String[] args) { 

    SLinkedListExtended<String> x = new SLinkedListExtended<String>(); 

    x.insertAtTail("abc"); 
    x.insertAtTail("def"); 
    x.insertAtTail("def"); 
    x.insertAtTail("xyz"); 
    System.out.println(x.count("def")); // should print "2" 
    x.insertAtTail(null); 
    x.insertAtTail("def"); 
    x.insertAtTail(null); 
    System.out.println(x.count("def")); // should print "3" 
    System.out.println(x.count(null)); // should print "2" 
} 
} 

Я распространил на класс, который компилируется правильно, поэтому я знаю, что проблема в моем методе. Я не могу понять, что делать, мой код возвращает 0, что, вероятно, является целым числом счетчиков, остающимся на 0 и не проходящим через оператор цикла. Любые идеи приветствуются.

Редактировать. SLinkedList код:

import net.datastructures.Node; 

public class SLinkedList<E> { 
protected Node<E> head; // head node of the list 
protected Node<E> tail; // tail node of the list (if needed) 
protected long size; // number of nodes in the list (if needed) 

// default constructor that creates an empty list 
public SLinkedList() { 
    head = null; 
    tail = null; 
    size = 0; 
} 

// update and search methods 
public void insertAtHead(E element) { 
    head = new Node<E>(element, head); 
    size++; 
    if (size == 1) { 
     tail = head; 
    } 
} 

public void insertAtTail(E element) { 
    Node<E> newNode = new Node<E>(element, null); 
    if (head != null) { 
     tail.setNext(newNode); 
    } else { 
     head = newNode; 
    } 
    tail = newNode; 
    size++; 
} 

public static void main(String[] args) { // test 
    SLinkedList<String> list = new SLinkedList<String>(); 

    list.insertAtHead("lol"); 

} 

}

+0

У вас есть два отдельных вопроса для решения: 1. как перебирать список (будет зависеть от реализации суперкласса) и 2. как подсчитать элементы (равные плюс приращение счетчика). – entonio

ответ

0

Код в count не в цикле, так что это будет просто вернуться после первого элемента.

Попробуйте это:

public int count(E elem) { 
    Node<E> cursor = tail; 
    int counter = 0; 
    while (true) 
    { 
     if ((cursor != null) && (!(cursor.getElement().equals(elem)))) { //tail isnt null and element is not equal to elem 
      cursor = cursor.getNext(); //go to next node 
     } else if ((cursor != null) && (cursor.getElement().equals(elem))){ //cursor isn't null and element equals elem 
      counter++; //increment counter 
     } 
     else { 
      return counter; //return counter 
     } 
    } 
} 

Кроме того, обратите внимание, что cursor.getElement().equals(elem) возвратит NullPointerException когда cursor.getElement() является null. Самый простой способ справиться с этим, вероятно, написать отдельный метод Equals:

boolean equals(E e1, E e2) 
{ 
    if (e1 == null) 
    return e2 == null; 
    if (e2 == null) 
    return false; 
    return e1.equals(e2); 
} 

Кроме того, по-видимому Node<E> cursor = tail; делает его точку в конец списка и, вероятно, вы хотите Node<E> cursor = head; вместо этого.

+0

Хорошо, я сделал это, но он все равно возвращает 0. Вы видите что-то не так с моим кодом? –

+0

Я не вижу ничего плохого. Вы изменили все 3 вещи? Попробуйте помещать инструкции печати в вашу функцию или отлаживать. – Dukeling

0

Может быть, вы должны использовать время цикла вместо если п

**while** ((cursor != null) && (!(cursor.getElement().equals(elem)))) { 
0

Одна из основных вещей, которые вы пропали без вести был цикл. Поскольку вы в основном ищете что-то, вы хотите просмотреть весь список. Когда вы нажмете на элемент, который соответствует тому, который вы ищете, вы хотите увеличить счет на 1. После того, как вы закончите цикл по всему списку, вы хотите вернуть этот счет. Так что это мое решение. Я держу это просто, чтобы вы могли понять:

import java.util.LinkedList; 

public class Duplicates<E> extends LinkedList<E> { 

    public static void main(String[] args) { 
     Duplicates<String> duplicates = new Duplicates<String>(); 
     duplicates.add("abc"); 
     duplicates.add("def"); 
     duplicates.add("def"); 
     duplicates.add("xyz"); 
     System.out.println(duplicates.duplicateCount("def")); 
     duplicates.add(null); 
     duplicates.add("def"); 
     duplicates.add(null); 
     System.out.println(duplicates.duplicateCount("def")); 
     System.out.println(duplicates.duplicateCount(null)); 
    } 

    public int duplicateCount(E element) { 
     int count = 0; 
     for (E e : this) { 
      if (e == element) { 
       count++; 
      } 
     } 
     return count; 
    } 
} 

Выход:

2 
3 
2 
+0

OP использует пользовательский 'SLinkedList', а не' 'LinkedList'', поэтому на вопрос об итерации также должен быть дан ответ (но в ответе на него недостаточно данных). – entonio

+0

Я предполагаю, что пользовательский LinkedList фактически расширяет LinkedList, поэтому он по-прежнему является итерируемым. Мой метод все равно должен работать. –

+0

Поскольку это представлено как задание, я не думаю, что вероятно, что он расширяет 'LinkedList', но все возможно. – entonio

0

Я предлагаю вам совместить ответ Мартина (который говорит вам, как считать элементы) с этим, которые говорят вам, как быть способный использовать foreach - вам просто нужно сделать свой SLinkedListExtended инструмент Iterable, whioch должен быть чем-то вроде этого (вы можете сделать это на SLinkedList, но я предполагаю, что вам сказали не изменять код для этого):

public class SLinkedListExtended<E> extends SLinkedList<E> implements Iterable<E>() { 

    public Iterator<E> iterator() { 
     final Node<E> itHead = head; 
     return new Iterator<E>() { 

      Node<E> current = itHead; 
      long position = 0; 

      public boolean hasNext() { 
       return current != null && position < size; 
      } 

      public E next() { 
       current = current.getNext(); 
       ++position; 
       return current.getElement(); 
      } 

      public void remove() { 
       throw new UnsupportedOperationException("Not supported yet."); 
      } 

     }; 
    } 

}; 

Я не могу ручаться за все детали, но это должно охватывать большинство из них. Вы также можете использовать equals вместо ==, но не забудьте проверить элементы для nullity.

next следует называть только если hasNext является true, так что это не проблема, если он бросает исключение (но это должно быть NoSuchElementException, чтобы в соответствии с договором).

Реализация Iterable делает ваш класс совместит с библиотекой коллекций, поэтому поддержкой Еогеаспа, но вы можете использовать его, чтобы сделать сырую итерацию по телефону iteratorhasNext, и next себя.