【问题标题】:Counting the amount of highest number in a string计算字符串中最大数字的数量
【发布时间】:2017-09-06 03:26:14
【问题描述】:

我正在尝试输出最高数字出现在用户输入中的次数,例如用户输入 2 4 3 4 2 4 0 最高数字是 4,它出现了 3 次,不知道该怎么做。

public static void main(String[] args) {
    // TODO Auto-generated method stub
    Scanner keyboard = new Scanner(System.in);

    String number, last;

    System.out.println("Enter an interger (0 ends the input): ");
    number = keyboard.nextLine();
    last = number.substring(number.length() - 1);

    while(!last.equals("0")){
        System.out.println("Must end the input with a 0: ");
        number = keyboard.nextLine();
        last = number.substring(number.length() - 1);
    }

    String[] array = number.split(" ");

    int max = Integer.MIN_VALUE, maxIndex = 0;

    int count;

    for (int i = 0; i < array.length; i++) {
         if (Integer.parseInt(array[i]) > max) {
             max = Integer.parseInt(array[i]);
             maxIndex = i;
         }
    }
    //String repeat = number.);
    System.out.println("The largest number is " + max);
}

【问题讨论】:

  • 嗯,基本逻辑很简单。对于字符串中的每个数字,存在三种可能性。 (1) 它大于之前最大的数字 - 所以将其存储为最大的,并将计数重置为 1。 (2) 它等于之前的最大数字 - 所以增加计数。 (3) 它小于以前最大的数字 - 所以忽略它。您现在需要做的就是将其转换为 Java。

标签: java arrays string for-loop int


【解决方案1】:

您可以使用 Java 8 的流来做到这一点,例如:

String number = "2 4 3 4 2 4 0";
String[] array = number.split(" ");
TreeMap<Integer,Long> numberMap = Arrays.stream(array)
    .map(s -> Integer.parseInt(s))
    .collect(Collectors.groupingBy(Function.identity(), TreeMap::new, Collectors.counting()));
System.out.println(numberMap.descendingMap().firstEntry().getValue());

这基本上存储了每个数字,并将其计入Map。由于我们使用的MapTreeMap,它按升序对键进行排序。然后我们从中获取最后一个(即最高)键并打印相应的值 3。

【讨论】:

  • 这会累积所有值的计数,这对于手头的任务来说太过分了。
  • @darshan 谢谢,我还没学会这就是我问的原因
  • 是的,这将比我概述并由@Andreas 发布的解决方案效率低。它也更难理解。
  • @Andreas 它只迭代Array 一次(O(n)),可以很容易地更改为假设获得min 频率并且不使用用户定义的类(以及大量样板代码)所以我会说这并不完全是一个overlill。
  • @DarshanMehta 它构建了一个TreeMap,所以性能复杂度是O(n log n),而不是O(n)。它还需要 O(n) 内存(最坏情况,O(log n) 平均,O(1) 最佳情况),同时找到最大可以使用 O(1) 内存完成(所有情况)。因此,在性能复杂性和内存复杂性都过高的情况下,我认为“矫枉过正”这个词是合适的。
【解决方案2】:

其他答案效率较低,所以我将显示suggested solution by David Wallace 的代码:

嗯,基本逻辑很简单。对于字符串中的每个数字,都有三种可能。

  1. 它大于之前的最大数 - 因此将其存储为最大数,并将计数重置为 1。
  2. 它等于之前最大的数字 - 所以增加计数。
  3. 它小于之前最大的数字 - 所以忽略它。

您现在需要做的就是将其转换为 Java。

原来是这样:

int[] input = { 2, 4, 3, 4, 2, 4 };

int count = 0, max = 0;
for (int value : input) {
    if (count == 0 || value > max) {
        max = value;
        count = 1;
    } else if (value == max) {
        count++;
    }
}

System.out.printf("Highest number of %d was found %d times%n", max, count);

输出

Highest number of 4 was found 3 times

如果这是您想在很多地方做的事情,您可以编写自己的收集器并使用 Java 8 Streams。

这里是收集器的使用:

int[] input = { 2, 4, 3, 4, 2, 4 };

Max max = Arrays.stream(input).collect(Max::new, Max::add, Max::merge);

System.out.printf("Highest number of %d was found %d times%n", max.getValue(), max.getCount());

这里是收集器本身:

public class Max {
    private int value;
    private int count;
    public void add(int newValue) {
        if (this.count == 0 || newValue > this.value) {
            this.value = newValue;
            this.count = 1;
        } else if (newValue == this.value) {
            this.count++;
        }
    }
    public void merge(Max other) {
        if (this.count == 0 || (other.count != 0 && other.value > this.value)) {
            this.value = other.value;
            this.count = other.count;
        } else if (other.value == this.value) {
            this.count += other.count;
        }
    }
    public int getValue() {
        return this.value;
    }
    public int getCount() {
        return this.count;
    }
}

【讨论】:

  • 我是否需要将它作为 int 我试图将其添加到我已经拥有的代码中。我已经拥有的 for 循环获得了最大数量,我需要获得的只是重复次数。我提供的数字只是一个例子,不是硬代码,对不起,我上周刚开始学习 java,所以我不熟悉事情是如何完成的。
  • @Angel 您的问题是关于计算最高数字的出现次数,而不是关于从用户那里收集这些数字,所以我只是在 example 代码中使用数组初始化器来显示计数逻辑,并且它有效。 for 循环是在迭代 int 值还是 double 值,还是迭代 String 值并将它们动态解析为数字,与计算最大值的逻辑无关。
猜你喜欢
  • 1970-01-01
  • 2021-09-28
  • 2017-10-20
  • 2013-09-17
  • 2021-07-22
  • 2014-04-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多