Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/395.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何仅返回出现次数最少的字符串的ArrayList?_Java_Android_Arraylist - Fatal编程技术网

Java 如何仅返回出现次数最少的字符串的ArrayList?

Java 如何仅返回出现次数最少的字符串的ArrayList?,java,android,arraylist,Java,Android,Arraylist,我有一个字符串[],originalStringArray,其中包含重复项。所以{“狗”、“猫”、“狗”、“鱼”、“狗”、“猫”} 我想做一个函数,只返回恰好出现一定次数的字符串。在这里,如果我说3,它将返回“dog”而不是“cat” 以下是我当前的代码: public ArrayList<String> returnMultiples(String[] originalStringArray,int requiredCount){ ArrayList<Integer

我有一个
字符串[]
originalStringArray
,其中包含重复项。所以
{“狗”、“猫”、“狗”、“鱼”、“狗”、“猫”}

我想做一个函数,只返回恰好出现一定次数的字符串。在这里,如果我说3,它将返回“dog”而不是“cat”

以下是我当前的代码:

public ArrayList<String>  returnMultiples(String[] originalStringArray,int requiredCount){
    ArrayList<Integer> mCount = new ArrayList<>();
    List<String> list = Arrays.asList(originalStringArray);
    ArrayList<String> result = new ArrayList<>();

    // Count occurrences in original string
    for(String item: originalStringArray){
        mCount.add(Collections.frequency(list,item));
    }

    // If frequency is equal to count, add to array list
    for(int i=0; i<mCount.size(); i++){
        if(mCount.get(i) == requiredCount){
            result.add(originalStringArray[i]);
        }
    }

    return result;
}
public ArrayList returnMultiples(字符串[]originalStringArray,int requiredCount){
ArrayList mCount=新的ArrayList();
List List=Arrays.asList(originalStringArray);
ArrayList结果=新建ArrayList();
//计算原始字符串中出现的次数
用于(字符串项:originalStringArray){
mCount.add(集合、频率(列表、项目));
}
//如果频率等于计数,则添加到数组列表

对于(int i=0;i您必须使用
HashMap
执行此任务

假设您的
HashMap
将包含给定字符串的出现次数,因此它将是
HasMap

现在,让我们迭代您的集合:

  • 从集合中获取另一个字符串
  • 检查HashMap(#contains)中是否存在给定字符串
  • 如果不存在,则使用String键放置新元素(hashMap.put(stringKey,1)
  • 如果存在,则使用相同的键放置元素,但增加内部计数器(hashMap.put(stringKey,hashMap.get(stringKey)+1)
  • 继续
  • 现在,hashmap包含集合中给定字符串的确切出现次数


    快速查找将创建反向
    HashMap
    ,但计数可能会重复,这不起作用。要获取与给定字符串匹配的发生数,您必须迭代map的所有键,并仅返回那些发生数与您的条件匹配的字符串。

    您的算法将返回duplic艾茨

    哈希集是集合库的一部分,因此对您没有好处

    包含Collections.frequency的循环是一个O(n^2)算法。(对于OriginalStringaray Collections.frequency中的每个字符串,再次循环整个OriginalStringaray)

    你只需要一个HashMap就可以做到

    为OriginalStringAray中的每个字符串在映射中增加一个整数

    删除值与requiredCount不同的所有键

    如果确实要返回ArrayList,请将map.keySet()添加到新的ArrayList


    或者map.keySet().toArray(字符串[map.size()]),如果需要数组。

    执行此操作需要某种映射。下面是使用HashMaps编写的示例:

    public ArrayList<String> returnMultiples(String[] array, int min){
        HashMap<String, Integer> counts = new HashMap<String, Integer>();//instantiate a new HashMap
    
        //loop through the array and count the occurrences of each different string in the array
        for(int i = 0; i < array.length; i++){
            String word = array[i];
            if(counts.containsKey(word))
                counts.put(word, counts.get(word) + 1);
            else
                counts.put(word, 1);
        }
    
        ArrayList<String> multiples = new ArrayList<String>();
    
        //check if any of the words occur >= min times. if so, add them to the returning list.
        for(String key : counts.keySet()){
            if(counts.get(key) >= min){
                multiples.add(key);
            }
        }
    
        return multiples;//return the list we just created of the desired strings
    }
    
    public ArrayList returnMultiples(字符串[]数组,int-min){
    HashMap counts=new HashMap();//实例化一个新的HashMap
    //循环遍历数组并计算数组中每个不同字符串的出现次数
    for(int i=0;i=分钟。如果是,请将其添加到返回列表中。
    for(字符串键:counts.keySet()){
    if(counts.get(key)>=min){
    倍数。添加(键);
    }
    }
    return multiples;//返回我们刚刚创建的所需字符串的列表
    }
    

    根据字符串的长度,HashMap将比使用集合的效率稍高一些,尽管差别几乎可以忽略。

    您可以使用
    AVL树
    ,前提是如果数组中有1000000个项目,则需要
    1000000个步骤来处理该数据结构。使用
    AVL树
    需要
    O(Log(1000000))
    步骤,即
    ==6个步骤,非常整洁。如果数据是动态的,这将是一个很好的方法,尽管您必须优化插入

    使用AVL树,所有内容都将被排序,因此您将获得
    O(logn)
    时间。而不是像这样横穿数组进行
    N步

    你可以这样做:

    它检查根,发现
    Char
    c大于
    dog
    中的第一个
    Char
    ,并向左横切。基本上,每一步都减少搜索时间
    1/2
    ,使其
    O(Log N)
    步。你必须保持树的高度平衡

    AVL树的好处在于,您的数据总是按排序顺序排列的,因为树需要平衡


    但是,如果数据不经常更改,并且您不需要排序数据,那么使用
    哈希映射可能会更好,我想,使用哈希映射足够有效

    我脑海中出现的最短代码(使用HashMaps)如下所示:

    String[] filter(String[] collection, int requirement) {
        final HashMap<String, Integer> temp = new HashMap<>();
    
        for (String item : collection) {
            int current = temp.getOrDefault(item, 0);
            temp.put(item, ++current);
        }
    
        final Iterator<Entry<String, Integer>> iterator = temp.entrySet().iterator();
        while (iterator.hasNext()) {
            final Entry<String, Integer> entry = iterator.next();
            if (entry.getValue() != requirement) {
                iterator.remove();
            }
        }
    
        return temp.keySet().toArray(new String[temp.size()]);
    }
    
    并按预期生成输出:


    显示引用。Java Collections库经过了高度优化。那些说自己速度慢的人通常没有正确地使用它们。你是对的。你想要一个映射来解决这个问题。特别是,如果你想保持原始的外观顺序,请使用OrderedHashMap。如果你处理的数量很少,性能其实并不重要在我看来,是数据集。当处理数千个或更多的元素时,性能就开始起作用,即使在这个数量上也只有一点点。也就是说,你不能使用集合,因为每个集合元素都必须是唯一的。在初始数组循环期间,我会将每个元素及其引用插入hashmap。然后你需要循环在hashmap上,抓取与您的出现条件匹配的键。
    Multiset
    正是为此目的而设计的。@Gene嗯,坦率地说,引用将是对另一个SO问题的一个注释。N
    final String[] array = new String[]{
        "dog", "dog", "dog", "cat", "cat", "fish", "cat"
    };
    
    final String[] result = filter(array, 3);
    
    for (String item : result) {
        System.out.println(item);
    }