在Java数组中查找元素的频率

4

我有一个整型数组:

{1,2,4,2,3,5,6,4,3}

我该如何找到数组元素的频率,例如 1=1,2=2,3=2,4=4..。我需要一个类,可以将我的数组传递给它,并返回一个数组,其中包含数组元素的计数。例如: array{[0]=1,[1]=2,[2]=3,[3]=4..} (对于上述示例数组)。

19
闻起来像作业。 - Steve Kuo
5
你尝试过什么? - higuaro
2
Collections.frequency(Arrays.asList(...), X) - obataku
不鼓励提出“给我代码”的问题。 - Wug
1
@oldrinb,您能否看一下并检查一下为什么这段代码不起作用?http://ideone.com/QZD5jp(它对每个数字都返回零) - Hengameh
3
如果不使用可变参数,Arrays.asList(int[]) 方法会把整个 int[] 数组作为一个对象处理,并返回一个只包含该数组的单例列表 List<int[]>。如果想要得到每个元素的封装类型 Integer[],可以直接使用可变参数或传递 Integer[] 数组。具体实现可以参考这个链接:http://ideone.com/TwS3yJ - obataku
11个回答

8
class MapTest
{
    public static void main(String args[]){
        HashMap<Integer,Integer> h = new HashMap<Integer,Integer>();
        int arr[] = new int[]{2,2,3,3,5,6,7,9,9,0};
        for(int i=0; i<arr.length; i++){
            if(h.containsKey(arr[i])){
                h.put(arr[i], h.get(arr[i]) + 1);
            } else {
                h.put(arr[i], 1);
            }
        }
        System.out.println(h);
    }
}

Java8之前最精英的解决方案。我仍然更喜欢它。 - Vishwa Ratna

5
在Java 8中,您可以这样做。
Map<Integer, Long> freq = Arrays.stream(array).boxed().
                collect(Collectors.groupingBy(Integer::intValue, Collectors.counting()));

仅使用Function.identity()而不是Integer::intValue是否足够?在这种情况下,我们实际上不需要取消封箱整数。 - Anton Balaniuc
@Anton 是的,它应该可以工作,但我不确定它能节省多少。 - Masood_mj
如果您使用的是Java 8,您可以直接使用Collections#frequency - Pants

3
使用Java-8,我们可以在一行代码中找到数组的频率。
Map<Integer, Long> freq = Arrays.stream(a).boxed().
                          collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

此外,由于问题要求我们需要返回一个数组。
public Object[] getFrequencies(int[] a) {
    Map<Integer, Long> freq = Arrays.stream(a).boxed().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
    return freq.entrySet().toArray();
}

3

你需要做以下几件事情:

  1. 为数字范围定义上限和下限。
  2. 建立一个方便的对象/数据结构来存储这些数字的出现次数。
  3. 遍历传入的数组并计算每个数字的出现次数,将结果存储在方便的对象/数据结构中。

如果以简单的方式完成,只需从传入的数组中读取元素并打印输出最终结果即可。


2
import java.util.*;
class Findfreqarray
{
    public static void main(String args[])
    {
        int t, i, j, len, count=0;
        Scanner in = new Scanner(System.in);
        System.out.println("Enter number of elements to insert in an array: ");
        len = in.nextInt();
        int[] arr = new int[len];
        System.out.println("Enter elements to insert in an array: ");
        for(i=0;i<len;i++)
        {
            t = in.nextInt();
            arr[i] = t;
        }
        System.out.println("\n");
        for(i=0;i<len;i++)
        {
            count=1;
            for(j=i+1;j<=len-1;j++)
            {
                if(arr[i]==arr[j] && arr[i]!='\0')
                {
                    count++;
                    arr[j] = '\0';
                }
            }
            if(arr[i]!='\0')
            {
                System.out.println(arr[i] + " is " + count + " times.\n");
            }
        }        
    }
}

正如在a comment中指出的那样,如果输入数组包含多个0,则此方法会失败。 - Janez Kuhar
我建议添加一个布尔数组,用于跟踪已经计算过的元素,而不是修改输入数组。 - Janez Kuhar

2
如果数组元素的范围被限定在数组大小内,最好的解决方案是使用哈希映射。 T(n) = O(n),辅助空间 = O(n)。
public static void findCount3(int[] a){
    Map<Integer, Integer> hm = new HashMap<Integer, Integer>();     
    for(int i = 0; i < a.length; i++){
            if(!hm.containsKey(a[i])){
               hm.put(a[i], 1);
            }else{
               hm.put(a[i], hm.get(a[i])+1);
    }               
    System.out.println(hm);         
}

为什么需要第一个for循环? - ankit

1

我有一个解决方案,可以计算Java数组中元素的频率。

import java.io.BufferedReader;

import java.io.InputStreamReader;

public class ItemCount {

public static void main(String[] args)
{
    try{
            int count=1,index=1;
            BufferedReader  br=new BufferedReader(new InputStreamReader(System.in));
            System.out.print("Enter the Size of array : ");
            int size=Integer.parseInt(br.readLine());
            System.out.print("Enter the Elements of array : ");
            int arr[]=new int[size];

            for(int i=0;i<arr.length;i++)
            {
                System.out.print("arr["+i+"] :  ");
                arr[i]=Integer.parseInt(br.readLine());
            }
            System.out.print("Sorted Array is :");
            SortingArray.sortDescendind(arr);

            for(int i=0;i<arr.length;i++)
            {
                System.out.println("arr["+i+"] :  "+arr[i]);

            }

            for(int i=0;i<arr.length;)
            {
                count=1;
                for(index=i+1;index<arr.length;index++)
                {
                    if(arr[i]==arr[index])
                    {
                        count++;
                    }
                    else{

                        break;
                    }


                }
                System.out.println(""+arr[i] +"----> "+count);
                i+=count;

            }

    }catch(Exception ex)
    {
        ex.printStackTrace();
    }
}

}

/// 你可以选择任何排序方法来对数组进行排序——>SortingArray.sortDescendind(arr)


你的解决方案的时间复杂度是O(n^2),这并不是最优的。 - Hengameh
@hengameh,我猜最好的时间复杂度应该是O(n),因为你至少要读取一次数组。@JavaFun,tl;dr但我认为最快的方法是制作一个二维计数数组并只读取原始数组一次。当您读取数组时,每次遇到数组中的新元素,请将{element, occurrences}添加到计数数组中,如果遇到旧元素,请在其出现位置上加1。 - Lightfire228

1

不在此透露,这是一个很好的起点:

int[] array = {1,2,4,2,3,5,6,4,3};

        public int[] (array){
            //need to perform a sort...or a search
            //after searching check for matches,
            //sorting could make performing comparisons more efficient
            //not all searches/sorts are created equal.

            int[array.length] result += {"["+numberChecked+"]="+freqOccurred};
            return result;
        }

这段代码尚未编译,因此请将其视为伪代码。其目的是让您思考如何实现所需的目标。可能已经存在一个Java包,可以检查数组中的频率元素,但这很可能是您正在寻找的内容。祝你好运。


1
你可以计算HashMap<Element,Frequency>中每个元素的频率。
Map<Integer,Integer> h = new HashMap<>();
int arr[] = new int[]{2,2,3,3,5,6,7,9,9,0};

for(int elem:arr) {
  h.merge(elem, 1, Integer::sum);
}

Hashmap.merge()允许您指定如何更新哈希映射中的值。如果elem不存在,则类似于h.put(elem,1)。如果存在名为oldFreq的现有值,则会用Integer.sum(oldFreq, 1)替换它。


更新了。这个解决方案与Ankit的解决方案类似,但更为简洁。我认为它没有任何限制。 - Apoorv Gupta

0
package practice.learning;

import java.util.Arrays;
public class FreqElem {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String[] names= {"Pawan","Rohan","Sudesh","Pawan","Shiv"};

        for(int i=0;i<names.length;i++) {
            int count=0;
            //System.out.print(names[i]);
            String a=names[i];
            for(int j=0;j<names.length;j++) {
                if(names[j]==a) {
                    count+=1;
                }
                
                
            }
            System.out.println(names[i]+":"+count); 
        }
        
    }

}

输出: Pawan:2 Rohan:1 Sudesh:1 Pawan:2 Shiv:1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接