簡體   English   中英

Java - 計算最常見的元素

[英]Java - counting most common elements

任務是編寫一個計算最常見數字的代碼。 例如A[1,2,4,4,4,5,6,7,4]將是44計數。 我需要保持這段代碼簡單,因為我只是嘗試將我的代碼從算法和數據結構實現到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 class countingNumbers {

 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;


 }

}

我將流數組並將其收集到映射中,計算每個元素的出現次數,然后返回具有最高計數的數組:

/**
 * @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"));
}

如果你擅長流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();
}

注意:有很多方法可以從與最大值關聯的地圖中獲取關鍵字。 請參閱此處以找到最合適的方法: 在Java Map中查找與最大值關聯的密鑰

另外if else語句可以用java8中的merge方法替換:

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

看看這兩行:

 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阻止,你永遠不會在你的else if點擊代碼。

此外,您的計數器應該從一開始,因為您正在計算與您正在查看的條目匹配的條目數,因此您跳過計算第一個條目。 但是既然你沒有在任何地方輸出計數器,我猜它並不是非常相關。

因此,要修復代碼,請將內部for循環更改為j <= x.length - 1

聲明兩個變量以保存最常見的數字及其頻率:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM