1

我正在编写一种方法,该方法允许我计算 String 类型的元素在 Strings 类型的 LinkedList 中出现的次数。我下面显示的代码不起作用。我在下面评论的那一行中不断出现索引超出范围。好像找不到bug

public int findDuplicate (LinkedList<String> e) {
int j = 1;
LinkedList<String> test = e;
while (!test.isEmpty()){
    test = e;
    String value = test.pop();
    //Screws up here when i = 6 
    for(int i =0; i<=test.size() && test.get(i)!=null; i++){ 
        String value3 = test.get(i);
        if(e.get(i).equals(value) && i<=test.size()){
            String value2 = test.get(i); 
            j++;
            String Duplicate = e.get(i);
            e.remove(i);
        }
    }
    System.out.println(value + " is listed " + j + " times");

}
return j;
}

使用哈希图..仍然不起作用

public void findDuplicate (LinkedList e) {

    Map<String,Integer> counts = new HashMap<String,Integer>();

    while(!e.isEmpty()){
        String value = e.pop();
        for(int i =0; i<e.size(); i++){
            counts.put(value, i);
        }
    }
    System.out.println(counts.toString());
}

我的代码应该通过链接列表找出列表中的元素出现多少次,并同时从列表中删除重复项。然后打印元素及其在列表中出现的次数。我昨晚发布了这个,但还没有得到回应。很抱歉重新发布。

4

5 回答 5

6

你跑出了列表的末尾。改变

for(int i =0; i<=test.size() && test.get(i)!=null; i++){ 

for(int i =0; i< test.size() && test.get(i)!=null; i++){ 

Lista (或数组)的有效索引是0through size() - 1

于 2013-03-04T21:41:22.830 回答
2

关于您的哈希图示例以计算重复项:

@Test
public void countOccurrences() {
    LinkedList<String> strings = new LinkedList<String>(){{
        add("Fred");
        add("Fred");
        add("Joe");
        add("Mary");
        add("Mary");
        add("Mary");
    }};

    Map<String,Integer> count = count(strings,new HashMap<String,Integer>());
    System.out.println("count = " + count);
}

private Map<String, Integer> count(List<String> strings, Map<String, Integer> runningCount) {
    if(strings.isEmpty()) {
        return runningCount;
    }
    String current = strings.get(0);
    int startingSize = strings.size();
    while(strings.contains(current)) {
        strings.remove(current);
    }
    runningCount.put(current, startingSize - strings.size());
    return count(strings,runningCount);
}

如果您希望保留原始字符串列表,您可以这样做

    Map<String,Integer> count = count(new LinkedList<String>(strings),new HashMap<String,Integer>());
    System.out.println("strings = " + strings);
    System.out.println("count = " + count);
于 2013-03-04T21:46:07.400 回答
2

查看 google 的 guava collections,它有一个完美的类来维护地图和获取计数:

https://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#BiMap

Multiset<String> wordsMultiset = HashMultiset.create();
wordsMultiset.addAll(words);
// now we can use wordsMultiset.count(String) to find the count of a word
于 2013-03-04T21:56:42.227 回答
1

这不会影响您的越界问题,但您正在从列表中删除元素,同时仍在评估它。如果你删除一个元素,你应该i--在之后调用,或者你跳过下一个实体(它被重新索引)进行评估。

另外值得注意的是,关于您的代码,我看到您正在尝试复制您的列表,但标准分配意味着test并且e都指向同一个实例。您需要使用Collections.copy()查看此 SO 线程来了解如何使用该类

于 2013-03-04T21:41:53.767 回答
1

我希望你明白test = e声明的作用。此语句执行后两者都test引用e一个对象。

如果他们中的任何一个人修改了列表,那么另一个人会看到它,因为他们都在看同一个对象。

如果这不是有意的,则需要先克隆列表,然后再将其分配给另一个列表引用。

于 2013-03-04T21:47:34.210 回答