2013-04-07 56 views
1

只是一個免責聲明:我第二次重複了我的java mod,所以我的問題可能會有點簡單,希望我聽起來不太愚蠢。去除arraylist中的重複項

寫方法removeDuplicates是作爲一個參數排序的 ArrayList的字符串,並從列表中排除任何重複。 例如,假設名爲list的變量包含以下值 :{"be", "be", "is", "not", "or", "question", "that", "the", "to", "to"}調用removeDuplicates(list);列表 應存儲以下值:{"be", "is", "not", "or", "question", "that", "the", "to"}

因爲值將被排序,所有重複項將被組合在一起。

我嘗試這個:

public static void removeDuplicates(ArrayList <String>a){ 
    for(int i=0;i<a.size();i++){ 
     String word=a.get(i); 
     String word2=a.get(i+1); 

     if(word.equals(word2)){ 
      a.remove(word); 

     } 
     else{ 
      System.out.print(word); 

     } 
    } 
} 

的問題是,當我把它叫做:

["duplicate", "duplicate", "duplicate", "duplicate", "duplicate"] 

返回indexoutofbound。我知道這與i=i-1有關,並參考remove方法。嘗試插入它在這裏,但它不起作用。但是我很困惑,因爲這與我的代碼一起工作。當我打電話給:

["be", "be", "is", "not", "or", "question", "that", "the", "to", "to"] 

它的工作原理。

+0

這是否幫助? http://stackoverflow.com/questions/13429119/get-unique-values-from-arraylist-in-java – Aiias 2013-04-07 05:54:03

+1

爲什麼不能使用一個相同的集合。這不會讓您在第一時間輸入重複值。 – 2013-04-07 05:54:04

+0

你好啊,它並沒有真正的幫助。我不喜歡設置的方法。因爲它沒有被教導,所以會更喜歡與設置無關的東西 – user2179615 2013-04-07 05:56:33

回答

0

您有兩個錯誤: 第一個錯誤是您嘗試訪問不存在的對象。 當i = a.size(),String word2=a.get(i+1)哪個不存在!

另一個錯誤是在迭代列表時刪除元素。

您應該改用iterator

解決它,而無需使用迭代的方法是:使用 :

for(int i=0;i<a.size() - 1;i++){ 

和:

if(word.equals(word2)){ 
    a.remove(word); 
    i--; 
} 
+0

嗯,它不適用於[「重複」 ,「複製」,「複製」,「複製」,「複製」] – user2179615 2013-04-07 06:04:56

+0

這是一個新錯誤還是與以前相同? – BobTheBuilder 2013-04-07 06:15:07

+0

當我調用[「重複」,「重複」,「重複」,「重複」,「重複」]時出現新錯誤,它返回3 [重複,重複,重複] – user2179615 2013-04-07 06:17:11

1

你的實現有缺陷。

String word=a.get(i); 
String word2=a.get(i+1); 

將在u到達最後一個元素時出現界限。

其次,你正在刪除元素,因爲你直接從arraylist迭代,這是行不通的。您改爲迭代器。

0

您可以使用設定的附加給它

+0

這可能會刪除太多元素,每個約束。出現的元素(例如[A,B,B,A])將被視爲無效輸入,不應將其重複刪除。 – Makoto 2013-04-07 06:56:12

0

您的循環時,應i < a.size() - 1這將刪除重複的元素。

讓您的大小爲4.當您迭代i = 3時,您將獲得word2的indexoutofbound,嘗試訪問索引4的值,該值實際上是從0到第3個索引。

0

void unique (ArrayList<String> a) 
{ 
    if(a.length() == 0) 
     return; 

    int result = 0; 
    int first = 0; 
    int last = a.length(); 
    while (++first<last) 
    { 
     String r = a.get(result); 
     String cur = a.get(first); 
     if(!cur.euqals(r)) 
      a.set(++result,cur); 
    } 
    a.removeRange(++result,last); 
} 

我希望這個代碼塊可以幫助你。

0

好的,所以我打算在你身上拋出語法和一些列表迭代概念。振作起來,讓你的Java 7 API方便。


解決這個問題如下,在普通的步驟:

  • 迭代通過列表。
  • 檢查列表中的相鄰元素。
    • 如果它們匹配,請將其刪除。
    • 否則,讓它一個人。
  • 返回最終的非重複列表。

假設下進行:

  • 具有重複元件是不相鄰的其他重複元素被假定表現出非設置行爲的列表 - 也就是說,如果我有輸入[A, B,B,A]我期望[A,BA]作爲輸出。這就是我爲什麼不是推薦使用Set這個。

有謹慎的上只使用remove()一個字 - if this list is accessed concurrently, then you will run into ConcurrentModificationException!優選和稍微乾淨的方法是使用IteratorListIterator接口來代替。

我們有四個案件遇到之前我們反覆:

  • 空(無元素) - 應該被禁止,因爲我們是[幾乎]保證我們不會有一個空列表
  • 單(只有一個元素,沒有重複)
  • 二進制(兩個元件,一個威力是重複)
  • 聚(ñ> 2種元素)

有一個邊緣情況我們必須考慮 - 超過三個重複元素。這意味着,當我們迭代時,我們必須查看之前的下一個元素,以確定是否應該刪除它。

採取,例如,本實施例中輸入:

[A, A, A, B, C, D] 

如果我們在幼稚方法迭代(看着i + 1的同時推進),然後我們將完全跳過的元件。不看左,右上面的結果將是:

[A, A, B, C, D] 

爲了解決這個問題,我們使用ListIterator,它支持先前的操作。通過這個與天真的前一種方法

一個運行會產生更壞的結果比以前 - 因爲我們已經重置了當前光標的位置,我們已經檢查它,我們將前進到下一個節點將被認爲是錯誤的重複! (諷刺的是,你不會擺脫第一對重複。)

要解決,我們重置光標到原來的位置,我們在我們向左看。

下面是解決方案。它適用於任何規模的清單,關於我們上面定義的約束和預期行爲。

public List<String> removeDuplicates(final ArrayList<String> dupeList) { 
    if(dupeList.size() == 0) { 
     throw new IllegalArgumentException("Zero-length list == evil"); 
    } 
    ListIterator<String> li = dupeList.listIterator(); 
    String w1; 
    String w2; 
    if(dupeList.size() == 1) { 
     return dupeList; 
    } else if(dupeList.size() == 2) { 
     w1 = li.next(); 
     w2 = li.next(); 
     if(w1.equals(w2)) { 
      li.remove(); 
     } 
    } else { 
     while(li.hasNext()) { 
      if(li.hasPrevious()) { 
       w1 = li.previous(); 
       li.next(); // explained a bit above 
      } else { 
       w1 = li.next(); 
      } 
      if(li.hasNext()) { 
       w2 = li.next(); 
       if(w1.equals(w2)) { 
        li.remove(); 
       } 
      } 
     } 
    } 
    return dupeList; 
} 
1

我會建議你改變返回類型ArrayList<String>和使用Set消除重複。具體方法如下:

public static ArrayList<String> removeDuplicates(ArrayList <String>a){ 
    return new ArrayList<String>(new HashSet<String>(a)); 
} 

或者,在for循環a.size()-1當前的代碼更改上限:

for(int i=0;i<a.size()-1;i++) // this should prevent arrayindexoutofbound exception.