2012-08-02 136 views
3

我正在做一些家庭作業問題,並且我陷入了對夫婦的困境。我很難理解交換列表中數據的最佳方法。使用虛假列表類

我應該使該方法reverse(),它使用LinkedIntList類(下面)。這是一個有限的列表類,所以我只能使用那裏的東西。

的點是取項目的列表

[1,2,3,4,5] 和反向他們 [5,4,3,2,1]

我想我的僞代碼將是

採取第一條數據並將其附加到列表中。 在原始大小上循環(因爲發生變化) 並取出0 處的棋子,然後將當前棋子添加到末尾0,1位置。

對於這樣的輸入: [1,8,19,4,17]
預期是這樣的: 前 - > [17] - > [4] - > [19] - > [8] - > [1]/
我的代碼獲取此: 前 - > [19] - > [4] - > [17] - > [8] - > [19] - > [1]/

不知道我做錯了什麼。

public void reverse(){ 
    int x = this.size(); 
    this.add(front.data); 

    for (int i = 0; i < x; i++){ 
       this.remove(0); 
     this.add(this.size()-1, front.data); 
    } 
} 

// A LinkedIntList object can be used to store a list of integers. 
public class LinkedIntList { 
    private ListNode front; // node holding first value in list (null if empty) 
    private String name = "front"; // string to print for front of list 

    // Constructs an empty list. 
    public LinkedIntList() { 
     front = null; 
    } 

    // Constructs a list containing the given elements. 
    // For quick initialization via Practice-It test cases. 
    public LinkedIntList(int... elements) { 
     this("front", elements); 
    } 

    public LinkedIntList(String name, int... elements) { 
     this.name = name; 
     if (elements.length > 0) { 
      front = new ListNode(elements[0]); 
      ListNode current = front; 
      for (int i = 1; i < elements.length; i++) { 
       current.next = new ListNode(elements[i]); 
       current = current.next; 
      } 
     } 
    } 

    // Constructs a list containing the given front node. 
    // For quick initialization via Practice-It ListNode test cases. 
    private LinkedIntList(String name, ListNode front) { 
     this.name = name; 
     this.front = front; 
    } 

    // Appends the given value to the end of the list. 
    public void add(int value) { 
     if (front == null) { 
      front = new ListNode(value, front); 
     } else { 
      ListNode current = front; 
      while (current.next != null) { 
       current = current.next; 
      } 
      current.next = new ListNode(value); 
     } 
    } 

    // Inserts the given value at the given index in the list. 
    // Precondition: 0 <= index <= size 
    public void add(int index, int value) { 
     if (index == 0) { 
      front = new ListNode(value, front); 
     } else { 
      ListNode current = front; 
      for (int i = 0; i < index - 1; i++) { 
       current = current.next; 
      } 
      current.next = new ListNode(value, current.next); 
     } 
    } 

    public boolean equals(Object o) { 
     if (o instanceof LinkedIntList) { 
      LinkedIntList other = (LinkedIntList) o; 
      return toString().equals(other.toString()); // hackish 
     } else { 
      return false; 
     } 
    } 

    // Returns the integer at the given index in the list. 
    // Precondition: 0 <= index < size 
    public int get(int index) { 
     ListNode current = front; 
     for (int i = 0; i < index; i++) { 
      current = current.next; 
     } 
     return current.data; 
    } 

    // Removes the value at the given index from the list. 
    // Precondition: 0 <= index < size 
    public void remove(int index) { 
     if (index == 0) { 
      front = front.next; 
     } else { 
      ListNode current = front; 
      for (int i = 0; i < index - 1; i++) { 
       current = current.next; 
      } 
      current.next = current.next.next; 
     } 
    } 

    // Returns the number of elements in the list. 
    public int size() { 
     int count = 0; 
     ListNode current = front; 
     while (current != null) { 
      count++; 
      current = current.next; 
     } 
     return count; 
    } 

    // Returns a text representation of the list, giving 
    // indications as to the nodes and link structure of the list. 
    // Detects student bugs where the student has inserted a cycle 
    // into the list. 
    public String toFormattedString() { 
     ListNode.clearCycleData(); 

     String result = this.name; 

     ListNode current = front; 
     boolean cycle = false; 
     while (current != null) { 
      result += " -> [" + current.data + "]"; 
      if (current.cycle) { 
       result += " (cycle!)"; 
       cycle = true; 
       break; 
      } 
      current = current.__gotoNext(); 
     } 

     if (!cycle) { 
      result += " /"; 
     } 

     return result; 
    } 

    // Returns a text representation of the list. 
    public String toString() { 
     return toFormattedString(); 
    } 

    // Returns a shorter, more "java.util.LinkedList"-like text representation of the list. 
    public String toStringShort() { 
     ListNode.clearCycleData(); 

     String result = "["; 

     ListNode current = front; 
     boolean cycle = false; 
     while (current != null) { 
      if (result.length() > 1) { 
       result += ", "; 
      } 
      result += current.data; 
      if (current.cycle) { 
       result += " (cycle!)"; 
       cycle = true; 
       break; 
      } 
      current = current.__gotoNext(); 
     } 

     if (!cycle) { 
      result += "]"; 
     } 

     return result; 
    } 


    // ListNode is a class for storing a single node of a linked list. This 
    // node class is for a list of integer values. 
    // Most of the icky code is related to the task of figuring out 
    // if the student has accidentally created a cycle by pointing a later part of the list back to an earlier part. 

    public static class ListNode { 
     private static final List<ListNode> ALL_NODES = new ArrayList<ListNode>(); 

     public static void clearCycleData() { 
      for (ListNode node : ALL_NODES) { 
       node.visited = false; 
       node.cycle = false; 
      } 
     } 

     public int data;   // data stored in this node 
     public ListNode next;  // link to next node in the list 
     public boolean visited; // has this node been seen yet? 
     public boolean cycle;  // is there a cycle at this node? 

     // post: constructs a node with data 0 and null link 
     public ListNode() { 
      this(0, null); 
     } 

     // post: constructs a node with given data and null link 
     public ListNode(int data) { 
      this(data, null); 
     } 

     // post: constructs a node with given data and given link 
     public ListNode(int data, ListNode next) { 
      ALL_NODES.add(this); 
      this.data = data; 
      this.next = next; 
      this.visited = false; 
      this.cycle = false; 
     } 

     public ListNode __gotoNext() { 
      return __gotoNext(true); 
     } 

     public ListNode __gotoNext(boolean checkForCycle) { 
      if (checkForCycle) { 
       visited = true; 

       if (next != null) { 
        if (next.visited) { 
         // throw new IllegalStateException("cycle detected in list"); 
         next.cycle = true; 
        } 
        next.visited = true; 
       } 
      } 
      return next; 
     } 
    } 

// YOUR CODE GOES HERE 

} 
+3

您是否正在使用一個IDE來讓您逐步進行調試?它可以幫助你查看你的列表正在發生什麼。或者,在你的'for'循環中添加一個print語句('System.out.println(toFormattedString())')來觀察列表的變化。 – 2012-08-02 07:02:22

+0

它在練習網站上,所以我不能插入打印語句。這是我最大的抱怨,沒有調試代碼。 – hobbes131 2012-08-02 07:09:25

+1

但是你知道代碼的細節,你剛剛發佈了它。如果你能抓住一個Java IDE(比如說[Eclipse](http://www.eclipse.org/downloads/)),那麼把它放在一個新項目中並且玩一下就是一個簡單的任務。如果你掙扎,我們可以幫助你做到這一點。 – 2012-08-02 07:11:15

回答

2

這裏是你的代碼的打印語句:

public void reverse() { 
    System.out.println(toFormattedString()); 

    int x = this.size(); 
    this.add(front.data); 
    System.out.println(toFormattedString()); 

    for (int i = 0; i < x; i++) { 
    this.remove(0); 
    System.out.println(toFormattedString()); 
    this.add(this.size() - 1, front.data); 
    System.out.println(toFormattedString()); 
    } 
} 

輸出:

front -> [1] -> [2] -> [3] -> [4] -> [5]/
front -> [1] -> [2] -> [3] -> [4] -> [5] -> [1]/
front -> [2] -> [3] -> [4] -> [5] -> [1]/
front -> [2] -> [3] -> [4] -> [5] -> [2] -> [1]/
front -> [3] -> [4] -> [5] -> [2] -> [1]/
front -> [3] -> [4] -> [5] -> [2] -> [3] -> [1]/
front -> [4] -> [5] -> [2] -> [3] -> [1]/
front -> [4] -> [5] -> [2] -> [3] -> [4] -> [1]/
front -> [5] -> [2] -> [3] -> [4] -> [1]/
front -> [5] -> [2] -> [3] -> [4] -> [5] -> [1]/
front -> [2] -> [3] -> [4] -> [5] -> [1]/
front -> [2] -> [3] -> [4] -> [5] -> [2] -> [1]/

希望這有助於。

+0

是的,我當然可以看到,我的代碼不按照計劃。讓我試着將它插入eclipse中,看看我能否把它整理出來。謝謝! – hobbes131 2012-08-02 19:41:44

+0

HAHA!明白了,看着這個在行動中發生的事情是巨大的。偉大的電話格式化的字符串的東西。 – hobbes131 2012-08-02 20:45:27

+0

@ hobbes131很高興你很開心:-) – 2012-08-02 20:49:03

1

嗨,你總是把數據size()-1可能要做到這一點,而不是

this.add(this.size()-i-1, front.data); 

,然後刪除第一個元素另一次。

不要猶豫,逐步調試你的代碼,看看它是怎麼回事。


成爲某網站上不應該使用IDE阻止你,但a piece of paper將做的工作也是如此。

+0

謝謝!當我將它與下面的回覆結合起來時,這是一個很大的幫助。我從你的反饋開始,並努力解決問題。 – hobbes131 2012-08-02 20:44:54

1

首先,您應該將第一個元素添加到(x-i)的索引中。然後刪除第一個元素。我的意思是你的循環應該是;

for (int i = 0; i < x; i++){ 

    this.add(this.size()-i, front.data); 
    this.remove(0); 
} 

你也可以刪除;

this.add(front.data); 

我認爲這有助於。

+0

當我想通了,我回去調整並保存了幾行不必要的代碼。謝謝一堆! – hobbes131 2012-08-02 20:46:07