[英]Java - counting most common elements
任務是編寫一個計算最常見數字的代碼。 例如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 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.