2012-11-15 127 views
3

我試圖創建一個返回字符串鏈表的方法。有一棵樹,樹中的每個節點都存儲一個字符。該方法應該可以找到樹中所有可能的路徑。每個路徑都會創建一個字符串,並將其添加到列表中。遍歷列表中添加字符到Java中的字符串列表

在第二個for循環中似乎存在一個問題,我無法弄清楚。該方法只返回在第一個if語句中添加的字符。

每個節點都包含變量childList(它是子節點的鏈表)和nodevalue(它是節點正在存儲的字符)。

public LinkedList<String> findStrings() { 
    LinkedList<String> paths = new LinkedList<String>(); 
    //add character to list if there are no children 
    if (childList.isEmpty()){ 
     paths.add("" + nodevalue); 
     return paths; 
    } 
    //use recursion to add paths from all children to the list 
    for (TreeNode t : childList){ 
     paths.addAll(t.findStrings()); 
     //add nodevalue to the beginning of all strings in the list 
     for (String s : paths){ 
      s = nodevalue + s; 
     } 
    } 
    for (String s : paths) System.out.println(s); //for debugging 
    return paths; 
} 

回答

0

在此聲明:

for (String s : paths){ 
      s = nodevalue + s; 
} 

你沒有真正改變s的值。事實上,你現在不能這樣做。 for-each循環無法更改正在迭代的元素。

1

字符串是不可變的類型分配

s = nodevalue + s; 

不regognized

更好的解決辦法應該是

for (TreeNode t : childList){ 
    final List<String> pathes = t.findStrings(); 
    for (final String path : pathes) { 
     // add all pathes to paths list adding nodevalue to the beginning 
     paths.add(nodevalue + path); 
    } 
} 
2

當你在內部循環改變s,你只是重新分配變量s,而不是存儲在鏈接列表中的值。相反,您應該循環遍歷列表中的所有元素,逐個更新它們。我覺得這樣的事情應該工作:

//use recursion to add paths from all children to the list 
for (TreeNode t : childList){ 
    paths.addAll(t.findStrings()); 
    //add nodevalue to the beginning of all strings in the list 
    int length = paths.size(); 
    for (int i=0; i<length; i++) { 
     paths.offer(nodevalue + paths.poll()); 
    } 
} 

poll需要從列表前面的第一個項目,offer把背面的結果。您取下第一個項目,將其更改,然後將其放在back-repeat paths.size()時間,最後以最初順序更新項目。

+0

或者,使用['ListIterator'](http://docs.oracle.com/javase/6/docs/api/java/util/ListIterator.html)在迭代時更新值也可以很好地工作。 – DaoWen

1

增強for循環在這裏不起作用。

你將不得不去與傳統之一,如下所示:

for (int i=0; i<paths.size(); i++){ 
    paths.set(i, paths.get(i) + paths.get(i)); 
} 

這裏:public E set(int index, E element)

+0

隨機訪問'set'和'get'並不是'LinkedList'的最佳選擇。此外,'s'是他版本中的循環變量...... – DaoWen

+0

感謝您指出's',錯過了這一點。關於隨機訪問的觀點也是對的。我只是決定使用它,因爲文檔沒有提到它是可選的,'LinkedList'本身就是一個實現。 –

0

邁克爾說,你不能代替在條目的值,每個循環。由於字符串是不可變的,所以你不能改變現有的字符串。

你需要執行正常的循環:

for (int i=0;i<paths.size(); i++) { 
    paths.set(i, nodevalue +paths.get(i)); 
} 

請注意,你不改變現有的字符串的值,但在同一位置的新字符串替換它。

+0

如果你打算推薦使用'get'和'set',你還應該建議切換到'ArrayList'而不是'LinkedList'。 ('LinkedList'具有可怕的隨機訪問性能 - 可能是因爲它是一個鏈表)。 – DaoWen

+0

@DaoWen:你說得對。我不明白他爲什麼在這裏使用'LinkedList'而不是'ArrayList'。 –

+1

@BheshGurung - 因爲他特意說他想創建一個鏈表,所以我假設他這樣做是有原因的。 'ArrayList'實際上並不是你所有收藏的悲哀_那麼多人似乎認爲它是_panacea。 ArrayLists適用於隨機訪問,但他們很喜歡在最終的任何地方添加/刪除項目。 LinkedLists吸取隨機訪問權限,但您可以便宜地添加項目。哪一個是正確的選擇取決於你的應用。 – DaoWen

相關問題