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);
}