Java-计算最常见的元素

时间:2019-02-20 17:28:13

标签: java arrays algorithm element counting

任务是编写一个计算最常见数字的代码。例如,A[1,2,4,4,4,5,6,7,4]将是4,计数为4。 我需要保持这段代码简单,因为我只是尝试将我的代码从算法和数据结构实现到Java。

我的想法是这样,但是以某种方式我从未达到最后的状态。

public class countingNumbers{

     public static void main(String []args){
         System.out.print(counting(new int[]{1,1,1,2,3,4,4,4,4,5,6}));
     }

     public static int counting(int[] x){
         int memory = 0; 
         int counter = 0;
         int mostCommon = 0;
         for(int i = 0; i < x.length-1;i++){
             for(int j = i+1; j < x.length-1; j++){
                 if(x[i] == x[j]){
                     counter = counter +1;

                 }
                 else if(j == x.length-1 && counter >= memory){
                     mostCommon = x[i];
                     memory = counter;
                     counter = 0;


                 }
             }
         }
         return  mostCommon;
     }
}

->预先感谢您的所有回答,对此我表示感谢。我只是在寻找逻辑,而不是用于流,api或其他任何逻辑。 我尝试用手写方式编写代码,而java中的实现仅供我自己查看,是否可以解决,但不幸的是不能解决。

更新-正确的解决方案是这样:

公共类计数数字{

 public static void main(String []args){
     System.out.print(counting(new int[]{1,2,2,2,6,2}));
 }

 public static int counting(int[] x){
     int memory = 0; 
     int counter = 1;
     int mostCommon = 0;
     for(int i = 0; i < x.length;i++){
         for(int j = i+1; j <= x.length-1; j++){
             if(x[i] == x[j]){
                 counter = counter + 1;

             }
             if(j == x.length-1 && counter >= memory){
                 mostCommon = x[i];
                 memory = counter;
                 counter = 1;


             }
         }counter = 1;
     } return memory;


 }

}

4 个答案:

答案 0 :(得分:4)

我将流式处理数组并将其收集到地图中,以计算每个元素的出现次数,然后只返回计数最高的那个元素:

/**
 * @return the element that appears most in the array.
 * If two or more elements appear the same number of times, one of them is returned.
 * @throws IllegalArgumentException If the array is empty
 */
public static int counting(int[] x){
    return Arrays.stream(x)
                 .boxed()
                 .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
                 .entrySet()
                 .stream()
                 .max(Map.Entry.comparingByValue())
                 .map(Map.Entry::getKey)
                 .orElseThrow(() -> new IllegalArgumentException("x must not be empty"));
}

答案 1 :(得分:2)

如果您擅长使用流api ..或仅出于教育目的,可以使用groupingBy的流解决方案:

Integer[] arr = {1, 1, 1, 2, 3, 4, 4, 4, 4, 5, 6};

Map<Integer, Long> map = Arrays.stream(arr)
        .collect(Collectors.groupingBy(o -> o, Collectors.counting()));

Integer common = map.entrySet().stream()
        .max(Comparator.comparingLong(Map.Entry::getValue))
        .map(Map.Entry::getKey).get();

System.out.println(common);

更新:如果信息流与您不相关:

可以通过foor-loop完成,但是在这里使用Map还是很方便的:

public static int counting(int[] x) {
    Map<Integer, Long> map = new HashMap<>(); // key is a number, value is how often does it appear in the array 
    for (int number : x) {
        if (map.get(number) != null) {
            map.put(number, map.get(number) + 1);
        } else {
            map.put(number, 1L);
        }
    }
    return Collections.max(map.entrySet(), Map.Entry.comparingByKey()).getKey();
}

注意:有很多方法可以从与最大值相关联的映射中获取密钥。请参见此处以找到最合适的方法:Finding Key associated with max Value in a Java Map

还可以用java8中的merge方法替换if else语句:

map.merge(number, 1L, (a, b) -> a + b);

答案 2 :(得分:1)

看看这两行:

 for (int j = i + 1; j < x.length - 1; j++) {

} else if (j == x.length - 1 && counter >= memory)

j严格小于 x.length - 1的情况下循环播放,但是else if仅在j等于 x.length - 1。因此,您永远无法在您的else if块中找到代码。

此外,您的计数器实际上应该从1开始,因为您要对与您要查找的条目匹配的条目数进行计数,因此可以跳过对第一个条目的计数。但是,由于您不会在任何地方输出计数器,因此我认为它并不十分相关。

因此,要修复您的代码,请将您的内部for循环更改为j <= x.length - 1

答案 3 :(得分:0)

声明两个变量以保存最常见的数字及其频率:

int mostCommon =Integer.MIN_VALUE;

int highFreq = 0;

遍历数组。对于每个元素,再次遍历数组并计算其频率。如果当前计数大于highFreq,请通过将mostCommon设置为当前元素来进行更新,并设置highFreq当前计数。示例:

public class countingNumbers{

    public static void main(String[] args) {
        int[] res = counting(new int[]{6, 4, 5, 4, 5, 6, 4, 3, 2});
        System.out.println("most common number is: " + res[0] + " with " + res[1] + " counts");
    }

    public static int[] counting(int[] x) {
        int mostCommon = Integer.MIN_VALUE;
        int highFreq = 0;
        for (int i = 0; i < x.length; i++) {
            int currFreq = 0;
            for (int j = 0; j < x.length; j++) {
                if (x[i] == x[j]) {
                    currFreq++;
                }
            }
            if (highFreq < currFreq) {
                highFreq = currFreq;
                mostCommon = x[i];
            }
        }
        return new int[]{mostCommon, highFreq};
    }
}