任务是编写一个计算最常见数字的代码。例如,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;
}
}
答案 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};
}
}