1

只是一个免责声明:我第二次重复了我的 java mod,所以我的问题可能有点简单,希望我听起来不会太愚蠢。

编写一个 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"]

有用。

4

7 回答 7

1

你的实现有缺陷。

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

当你到达最后一个元素时会超出界限。

其次,当您直接从 arraylist 迭代时,您正在删除元素,这将不起作用。你迭代器代替。

于 2013-04-07T05:59:16.460 回答
1

I would suggest you change return type to ArrayList<String> and use Set to eliminate duplicates . Here's how :

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

Or , in your current code change upper limit of for loop to a.size()-1:

for(int i=0;i<a.size()-1;i++) // this should prevent arrayindexoutofbound exception.
于 2013-04-07T07:55:37.520 回答
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--;
}
于 2013-04-07T05:59:01.313 回答
0

您可以使用 Set 将在添加时删除重复元素

于 2013-04-07T05:59:29.470 回答
0

你的 for 循环应该是i < a.size() - 1.

让您的大小为 4。当您迭代 for 时i = 3,您将获得 word2 的 indexoutofbound,尝试访问索引 4 的值,该值实际上是从 0 到第 3 个索引。

于 2013-04-07T06:02:32.410 回答
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);
}

我希望这个代码块可以帮助你。

于 2013-04-07T06:16:12.077 回答
0

好的,所以我将向您介绍语法和一些列表迭代概念。振作起来,准备好您的 Java 7 API。


这个问题的解决方案如下,简单的步骤:

  • 遍历列表。
  • 检查列表中的相邻元素。
    • 如果它们匹配,请将其删除。
    • 否则,不管它。
  • 返回生成的非重复列表。

假设:

  • 假定具有不与其他重复元素相邻的重复元素的列表表现出非 Set 行为 - 也就是说,如果我输入 [A, B, B, A] 我希望 [A, BA] 为输出。这就是为什么我建议为此使用 aSet的原因。

仅使用时要注意remove()-如果同时访问此列表,那么您将遇到ConcurrentModificationException 一个首选且稍微干净的方法是使用IteratororListIterator接口。

在迭代之前,我们有四种情况要遇到:

  • 空(无元素) - 应该被禁止,因为我们 [实际上] 保证我们不会有一个空列表
  • 单例(只有一个元素,没有重复)
  • 二进制(两个元素,一个可能是重复的)
  • 聚(n > 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;
}
于 2013-04-07T06:55:21.813 回答