计算java数组中的出现次数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21871053/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 11:10:57  来源:igfitidea点击:

Counting number of occurrences in java array

java

提问by user3325959

The problem is: Write a program that reads integers between 1-100 and counts the occurrences of each. Assume the input ends with 0. If the number occurs more than once the plural "times" is used in the output. Here is a sample run of the program:

问题是:编写一个程序,读取 1-100 之间的整数并计算每个整数的出现次数。假设输入以 0 结尾。如果数字出现不止一次,则在输出中使用复数“时间”。这是程序的示例运行:

2 occurs 2 times
3 occurs 1 time
4 occurs 1 time
5 occurs 2 times
6 occurs 1 time
23 occurs 1 time
43 occurs 1 time

2次出现2次
3次出现1次
4次出现1次
5次出现2次
6次出现1次
23次出现1次
43次出现1次

I have fixed the read integer in my code to no longer be i but a separate variable "index" and understand why I am receiving the out of bounds exception, but I am kind of thick and don't understand how to fix it at the same time as add a sentinel value of 0.

我已将代码中的读取整数修复为不再是 i 而是一个单独的变量“索引”,并理解为什么我收到越界异常,但我有点厚,不明白如何在同时添加一个哨兵值 0。

import java.util.Scanner;

public class countNumberOccurrence{
  public static void main(String args[]){

  int[] numbers = new int[100];
  inputArray(numbers);

  }

  public static void inputArray(int[] myList){
    Scanner input = new Scanner(System.in);
      System.out.print("Enter integers from 1-100 (input 0 value to end inputs): ");
      int index = 0;
      for(int i = 1; i < myList.length - 1; i++){
        if(i > 0){
          index = input.nextInt();  
          myList[index-1]++;  
        }

        if(myList[index-1] > 1)
          System.out.println(index + " occurs " + myList[index-1] + " times ");
        else
          System.out.println(index + " occurs " + myList[index-1] + " time ");
      }             

  }

}

回答by Connor

I think your problem is in this line:

我认为你的问题在这一行:

if(myList[index-1] > 1)
      System.out.println(index + " occurs " + myList[index-1] + " times ");

If index is 0 you will be trying to access the -1 element of the array which is out of bounds. Try this instead:

如果索引为 0,您将尝试访问超出范围的数组的 -1 元素。试试这个:

if(index>0){
    if(myList[index-1] > 1)
      System.out.println(index + " occurs " + myList[index-1] + " times ");
    }
    else
      System.out.println(index + " occurs " + myList[index-1] + " time ");
}

This makes it so the line won't try and access the -1 element if your index is 0.

这使得如果您的索引为 0,该行将不会尝试访问 -1 元素。

回答by Connor

Since you say in a comment you can't do it the proper idiomatic way:

既然你在评论中说你不能以正确的惯用方式做到这一点:

The proper logic for detecting in input of a 0and ending the application would be:

检测 a 输入0并结束应用程序的正确逻辑是:

int nextInt;
while ((nextInt = input.nextInt()) != 0)
{
    // do your logic here
}
// print your output here

This is the proper way to handle the input.

这是处理输入的正确方法。

Never work with raw arrays if you don't have to!

如果不需要,永远不要使用原始数组!

Always use the appropriate java.util.collectionsclass and iterate with a for/eachor the proper Iteratorand you won't have these one off errors.

始终使用适当的java.util.collections类并使用 afor/each或适当的进行迭代,Iterator您将不会出现这些错误。

What you are looking for is called a Multimap

您正在寻找的称为 Multimap

Here is a JDK only solution:

这是仅 JDK 的解决方案:

import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;

public class Q21871053
{
    public static void main(final String[] args)
    {
        final Random rnd = new Random();

        final Map<Integer, AtomicInteger> counter = new HashMap<Integer, AtomicInteger>()
        {
            @Override
            public AtomicInteger get(final Object key)
            {
                if (!super.containsKey(key)) { super.put((Integer) key, new AtomicInteger(rnd.nextInt(100))); }
                return super.get(key);
            }
        };

        final AtomicInteger nextInt = new AtomicInteger(rnd.nextInt(100));
        while (nextInt.get() != 0)
        {
            counter.get(nextInt.get()).incrementAndGet();
            if (counter.size() > 1000) { nextInt.set(0); } // limit the run to 1000 numbers
            else { nextInt.set(rnd.nextInt(100)); }
        }

        for (final Integer i : counter.keySet())
        {
        final AtomicInteger integer = counter.get(i);
        final String format = integer.get() > 1 ? "%d occurs %s times\n" : "%d occurs %s time\n";
        System.out.format(format, i, integer);
        }
    }
}

Here is a sample output:

这是一个示例输出:

3 occurs 43 times
98 occurs 16 times
64 occurs 35 times
36 occurs 27 times
37 occurs 19 times
7 occurs 58 times
76 occurs 48 times
77 occurs 40 times
41 occurs 68 times
46 occurs 5 times
13 occurs 100 times
14 occurs 15 times
51 occurs 85 times
17 occurs 40 times
85 occurs 16 times
18 occurs 97 times
25 occurs 10 times
24 occurs 12 times
29 occurs 14 times
91 occurs 2 times

Google Guava has a great implementation of a Multimap.java

Google Guava 有一个很好的Multimap.java实现

@Override
public void functionToBeRateLimited(@Nonnull final String caller)
{
    // do some stuff every time here
    super.timesCalled.get(caller).incrementAndGet();

    // do some stuff only after a certain time has elapsed since the last time it was done
    if (LIMITER.get(caller).tryAcquire())
    {
        System.out.println(String.format("%s Called Rate Limited Logic up to 2 times a second ( 500 ms )", caller));
    }
}

回答by Inertiatic

Jarrod gave a great answer, but if you have certain assignment specifications, make sure to list them.

Jarrod 给出了很好的答案,但如果您有特定的作业规范,请务必列出它们。

Edited this, sorry for that mistake. Missed that you assigned index in the if block. The out of bounds issue arises when the user inputs 0 to end input. Even if the user is done, you try to insert into the array. So put an if statement to check for the 0.

编辑了这个,抱歉那个错误。错过了您在 if 块中分配的索引。当用户输入 0 结束输入时,会出现越界问题。即使用户完成了,您也尝试插入到数组中。因此,放置一个 if 语句来检查 0。

int index = 0;
  for(int i = 1; i < myList.length - 1; i++){
    if(i > 0){
      index = input.nextInt();  
      if (index > 0 && index < myList.length)
           myList[index-1]++;
      else
        break;  
    }

Now this will work, but it's not the best style. A for loop is not the best choice here because you don't know how many numbers the user will input. This will fix your out of bounds issue, but there are a few other issues with your implementation. Fix this first and then work on the rest of the code.

现在这将起作用,但它不是最好的样式。for 循环在这里不是最佳选择,因为您不知道用户将输入多少个数字。这将解决您的越界问题,但您的实施还有一些其他问题。首先解决这个问题,然后处理其余的代码。

回答by user3699979

package deneme;

import java.util.Scanner;

public class CountOccuranceNumbers {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Scanner input = new Scanner(System.in);

        int[] number = new int[100];

        System.out.print("Enter the integers between 1 and 100: ");
        for (int i = 0; i < number.length; i++) {
            int a = input.nextInt();
            number[a] += a;
            if (a == 0)
                break;
        }
        for (int i = 1; i < number.length; i++) {
            if (number[i] != 0) {
                if (number[i] / i > 1)
                    System.out.println(i + " occurs " + number[i] / i + " times");
                else
                    System.out.println(i + " occurs " + number[i] / i + " time");               }
        }
    }
}

回答by Srajesh

public class q7 {

    public static void main(String[] args) {
        int arr[] = {6, 22, 20, 11, 5, 18, 18, 16, 30, 9, 10, 10, 11, 5, 18, 18, 16};
        for (int i = 0; i < arr.length; i++) {
            int count = 0;
            for (int j = 0; j < arr.length; j++) {
                if (arr[i] == arr[j])
                  count++;
            }
            System.out.println(arr[i] + "\toccures\t" + count + " times");
        }
    }
}