查找arraylist中重复元素的索引

时间:2012-10-25 16:58:51

标签: java arraylist binary-search

我正在尝试在字符串的arraylist中找到重复项的索引位置。我无法找到一种方法来有效地循环遍历arraylist并报告副本的索引。我最初的想法是使用Collections.binarySearch()来查找副本,但我不知道我怎么能用binarySearch将arraylist的元素相互比较。我唯一的另一个想法是涉及循环列表,这是相当大的,甚至是可行的太多次。我的Java知识有限,所以感谢任何帮助。

4 个答案:

答案 0 :(得分:4)

不优雅,但应该有效:

Map<String, List<Integer>> indexList = new HashMap<String, List<Integer>>();
for (int i = 0; i < yourList.size(); i++) {
    String currentString = yourList.get(i);
    List<String> indexes = indexList.get(currentString);
    if (indexes == null) {
         indexList.put(currentString, indexes = new LinkedList<Integer>());
    }
    indexes.add(i);
    if (indexes.size() > 1) {
        // found duplicate, do what you like
    }
}
// if you skip the last if in the for loop you can do this:
for (String string : indexList.keySet()) {
    if (indexList.get(string).size() > 1) {
        // String string has multiple occurences
        // List of corresponding indexes:
        List<Integer> indexes = indexList.get(string);
        // do what you want
    }
}

答案 1 :(得分:0)

听起来你运气不好。

您将拥有来检查每个元素(即遍历整个列表)。从逻辑上考虑一下 - 如果你能避免这种情况,那就意味着有一个你没有检查过的元素。但是这个元素可以是任何值,因此可能是另一个列表元素的副本。

当您意识到列表中存在某种关系时,二进制搜索是一种减少检查元素数量的明智方法 - 因此检查一个元素会为您提供有关其他元素的信息。例如,对于排序列表,如果中间元素大于5,则您知道其后的每个元素也大于5。

但是,在重复检查方面,我认为没有办法做出这样的推断。您必须根据“重复的元素数量”(这是问题)对列表进行排序,否则您对元素x执行的测试无法让您深入了解y是重复的。

答案 2 :(得分:0)

现在这可能不是一个内存有效的解决方案,但是我想这就是你要找的......可能这个程序可以进一步改进。

import java.io.*;
import java.util.*;

class ArrayList2_CountingDuplicates
{
public static void main(String[] args)throws IOException
{

ArrayList<String> als1=new ArrayList<String>();
ArrayList<String> als2=new ArrayList<String>();
int arr[];
int n,i,j,c=0;
String s;

BufferedReader p=new BufferedReader(new InputStreamReader(System.in));

n=Integer.parseInt(p.readLine());

arr=new int[n];

for(i=0;i<n;i++)
als1.add(p.readLine());

for(i=0;i<n;i++)
{

s=als1.get(i);
als1.remove(i);
als2.add(s);

arr[c]=1;

while(als1.contains(s))
{
j=als1.indexOf(s);
als1.remove(j);
arr[c]=arr[c]+1;
}
n=n-arr[c];
c=c+1;
i=-1;
}

    for(i=0;i<c;i++)
    System.out.println(als2.get(i)+" has frequency  "+arr[i]);
    }

}

答案 3 :(得分:0)

我一直在寻找这样的方法,最终我想出了我自己的解决方案,用更实用的方法来解决问题。

public <T> Map<T, List<Integer>> findDuplicatesWithIndexes(List<T> elems) {
    return IntStream.range(0, elems.size())
            .boxed()
            .collect(Collectors.groupingBy(elems::get))
            .entrySet().stream()
            .filter(e -> e.getValue().size() > 1)
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}

它返回一个由重复元素作为键和重复元素的所有索引列表作为值组成的映射。