在一个数组中计算出现次数(Java)

10

我完全被卡住了。我休息了几个小时,似乎无法解决这个问题。这真的很让人沮丧!

我知道我需要检查数组中的当前元素,并查看它是否在数组中的其他位置出现过。我的想法是输出以下内容:

用户被要求输入10个整数,并将这些整数分配给一个数组(因此方法的参数为“数字”)。假设我输入“1, 1, 2, 3, 3, 4, 5, 6, 7, 8”。打印的结果应该是“1出现了2次。2出现了1次。3出现了2次。4出现了1次。5出现了1次。6出现了1次。7出现了1次。8出现了1次。”这个打印将在另一个方法中完成。

我的代码中的所有内容都有效,除了我创建的用于计算出现次数的方法。

public static int getOccurrences(int[] numbers)
{
    int count = 0;

    for (int i = 0; i < numbers.length; i++)
    {
        int currentInt = numbers[i];;

        if (currentInt == numbers[i])
        {
            count++;
        }
    }

    return count;
}

我知道这里的问题所在。我将数组中的当前整数元素设置为变量currentInt。if语句计算数组中的每个整数元素,因此输出结果是“[I@2503dbd3出现了10次”。

我该如何跟踪每个元素在数组中出现的次数?


3
你正在将numbers[i]与numbers[i]进行比较;这总是为真并增加计数... - Constant
还有一个多余的分号。 - The name's Bob. MS Bob.
3
你的意思是“计算重复项”而不是“计算出现次数”吗?在getOccurrences()方法中,你想返回什么类型的整数?请给出一个小数组示例,并展示当传递到你的方法时你期望返回什么。 - Bohemian
2
@Z̷͙̗̻͖̣̹͉̫̬̪̖̤͆ͤ̓ͫͭ̀̐͜͞ͅͅαлγo,你的名字很让人烦恼 :) - Jean-François Savard
@Bohemian 用户被要求输入10个整数,并将这些整数分配给一个数组(因此方法的参数为“numbers”)。假设我输入“1, 1, 2, 3, 3, 4, 5, 6, 7, 8”。打印结果应该是1出现了2次。 2出现了1次。 3出现了2次。 4出现了1次。 5出现了1次。 6出现了1次。 7出现了1次。 8出现了1次。 - FrakkinShip
@FrakkinShip 请将此内容添加到您的问题中(单击 edit 链接) - Bohemian
16个回答

7
package countoccurenceofnumbers;

import java.util.Scanner;
public class CountOccurenceOfNumbers {


    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int [] num = new int[100]; 
        int [] count = new int[100];
        //Declare counter variable i
        //and temp variable that will
        //temporarily hold the value
        //at a certain index of num[] array
        int i,temp = 0;
        System.out.println("Enter the integers between 1 and 100: ");

        //Initialize num[] array with user input
        for(i=0; i < num.length; i++){
            num[i] = input.nextInt();
            //expected input will end when user enters zero
            if(num[i] == 0){
                break;
            }
        }//end of for loop

        //value at a given index of num array 
        //will be stored in temp variable
        //temp variable will act as an index value
        //for count array and keep track of number
        //of occurences of each number
        for(i = 0; i < num.length; i++){
                temp = num[i];
                count[temp]++;
            }//end of for looop

        for(i=1; i < count.length; i++){

            if(count[i] > 0 && count[i] == 1){
             System.out.printf("%d occurs %d time\n",i, count[i]);
             }
            else if(count[i] >=2){
                System.out.printf("%d occurs %d times\n",i, count[i]);
            }


         }//end of for loop

    }//end of main
    }//end of CountOccurrenceOfNumbers

///////////输出//////////////////////

输入1到100之间的整数:
2 5 6 5 4 3 23 43 2 0
数字2出现了2次
数字3出现了1次
数字4出现了1次
数字5 出现了2次
数字6出现了1次
数字23出现了1次
数字43 出现了1次
构建成功(总用时:3分钟23秒)


嘿,Brenda,你的代码很好,但我有几个问题要问。首先,count[temp]++是什么意思?尽管我已经努力了,但我还是不理解。其次,为什么count[]可以获得值,即使没有输入任何内容?第三,为什么在下一个数组中你从1开始而不是从0开始?你能否简要地解释一下,这样我就可以澄清我的概念。谢谢 :) - Alok
1
你好,Alok,谢谢。首先,count [temp] ++在temp索引处加一。这是完美的,因为如果我们有一个用户输入例如111,num数组包含这些值,每次我们都将临时将每个值放入temp变量中,并使用它作为我们在计数数组中的索引。例如,temp = 1 => count [temp] ++;或count [1] ++;或count [1] = count [1] + 1;所以由于计数数组中的每个元素都包含零,我们然后访问其内容并添加1。当我们遍历所有三个1时,我们就有了count [1]上的值3,因此输入了1三次。 - Brenda Mejia
第二,我认为我在第一个问题中已经回答了,如果你还有疑问,请告诉我。第三,在第一个for循环中,我从0开始是因为我想访问num数组的第一个元素以检索用户的输入,在第二个循环中,我不需要从索引0开始,因为0是确定我们输入停止的位置,我们只计算1-100之间的数字频率而不计算零的频率。 - Brenda Mejia

6
我们可以使用Java 8的Stream API来创建频率图。
``` Stream.of("apple", "orange", "banana", "apple") .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())) .entrySet() .forEach(System.out::println); ```
下游操作本身就是一个收集器(Collectors.counting()),它对类型为String的元素进行操作,并生成类型为Long的结果。collect方法调用的结果是一个Map。
这将产生以下输出:
``` banana=1 orange=1 apple=2 ```

3

@NYB,你几乎是对的,但你需要输出计数值,并在每个元素检查时从零开始。

    int count=0,currentInt=0;
    for (int i = 0; i < numbers.length; i++)
    {
    currentInt = numbers[i];
    count=0;

       for (int j = 0; j < numbers.length; j++)
           {
             if (currentInt == numbers[j])
                {
                  count++;
                 }
            }
            System.out.println(count);
      }

@loikkk,我稍微修改了你的代码以便打印出每个元素的出现次数。

int[] a = { 1, 9, 8, 8, 7, 6, 5, 4, 3, 3, 2, 1 };

    Arrays.sort(a);

    int nbOccurences = 1;

    for (int i = 0, length = a.length; i < length; i++) {
        if (i < length - 1) {
            if (a[i] == a[i + 1]) {
                nbOccurences++;
            }
        } else {
            System.out.println(a[i] + " occurs " + nbOccurences
                    + " time(s)"); //end of array
        }

        if (i < length - 1 && a[i] != a[i + 1]) {
            System.out.println(a[i] + " occurs " + nbOccurences
                    + " time(s)"); //moving to new element in array
            nbOccurences = 1;
        }

    }

2
你可以在这里找到你问题的答案:这里 我在我的例子中使用了 Arrays.sort() 方法:
public class MyTest {

    /**
     * @param args
     */
    public static void main(String[] args) {

        int[] a = {1, 9, 8, 8, 7, 6, 5, 4, 3, 3, 2, 1};

        Arrays.sort(a);
        int nbOccurences = 0;

        for (int i = 0, length = a.length - 1; i < length; i++) {
            if (a[i] == a[i + 1]) {
                nbOccurences++;
            }
        }

        System.out.println("Number same occurences : " + nbOccurences);
    }
}

2
你需要两个循环:
  1. 第一个循环是起始位置的索引

  2. 嵌套的循环,要比当前位置提前一个索引,除非你已经到达末尾。

你的数组中有一个你不希望出现的数字吗?如果有的话,可以将该值 (-1 例如) 作为哨兵值来计算重复次数并覆盖掉。然后,当你再次遍历数组查找下一个要检查出现次数的数字时,如果它有哨兵值,就会跳过它。


1
这是一个使用Java 8 Stream生成频率映射的完整解决方案。每个步骤都有注释来解释。
import java.util.Arrays;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

class Scratch {
    public static void main(String[] args) {
        int[] numbers = new int[]{1, 1, 2, 3, 3, 4, 5, 6, 7, 8};

        // Count up the occurrences of each number
        final Map<Integer, Long> numberToOccurrences = getFrequencyMap(numbers);

        // Print out the results
        for (Map.Entry<Integer, Long> entry : numberToOccurrences.entrySet()) {
            System.out.println(String.format("%d occurs %d times", entry.getKey(), entry.getValue()));
        }
    }

    public static Map<Integer, Long> getFrequencyMap(int[] numbers) {
        return Arrays.stream(numbers) // Use Java 8 stream
                .boxed() // convert IntStream to Stream<Integer>
                .collect(Collectors.groupingBy(
                        Function.identity(), // Key - the number
                        Collectors.counting() // Value - occurrences of the number
                ));
    }
}

运行它会打印输出

1 occurs 2 times
2 occurs 1 times
3 occurs 2 times
4 occurs 1 times
5 occurs 1 times
6 occurs 1 times
7 occurs 1 times
8 occurs 1 times

1

最有效的方法是在遍历数组时创建哈希表来保存元素的出现次数。这将在2n时间复杂度内完成,这对于解决此问题是最好的 -

HashMap<Integer, Integer> hmap = new HashMap<Integer, Integer>();
int count;    
for(int i=0;i<arr.length;i++){
       if(hmap.get(arr[i])==null){
         hmap.put(arr[i],1);
       }else{
         count=hmap.get(arr[i]);
         count++;
         hmap.put(arr[i],count);
       }
     }

0

你需要对数组中的数字进行排序。你可以使用 'sort()' 方法,它会将你的数字从小到大排列。

你还需要两个循环,一个用来与另一个比较。或者在我的解决方案中,我使用了一个 'while 语句' 和一个 'for 循环'。

我不知道我解决你的问题的方法是否符合你的要求。也许有更短、更好的方法来解决这个问题。这只是我想到的方法。祝你好运!

public static int getOccurrences(int[] numbers){

    Array.sort (numbers); //sorts your array in order (i,e; 2, 9, 4, 8... becomes, 2, 4, 8, 9)

    int count = 0;
    int start = 0; 
    int move = 0;

        while(start < numbers.length){
            for (int j = 0; j < numbers.length; j++){
                int currentInt = numbers[start];;
                if (currentInt == numbers[j])
                {
                    count++;
                    move++;
                }
            }
                if(count == 1){
                    return ("Number : " + numbers[start] + " occurs " + count + " time ");
            }   else {
                    return ("Number : " + numbers[start] + " occurs " + count + " times ");
            }
                count = 0;
                start = start + move;
                move = 0;
        }
}

0

只需复制并执行它,它将给出数组中整数出现的次数。

public class noOfOccurence{  

public static void main(String[] args){

    int a[] = {1,9,4,5,6,7,5,6,7,3,2,5,7,9,0,4,3,5,1,4,6,0,2,3,1,4,3,8};

    HashSet<Integer> al = new HashSet<Integer>();

   //Store the array in set as set will store unique elemnets
    for(int i=0;i<a.length;i++){
        //int count =0; 
        al.add(a[i]);
    }
    //printing the set
    System.out.println("al "+al);


    for(int set : al){
        int count = 0;
        for(int j=0;j<a.length;j++){

            if(set==a[j]){
                count++;
            }
        }
        System.out.println(set+" occurs "+count+" times");
    }
  }
}

0
import java.util.*;

public class noOfOccurence{  

public static void main(String[] args){
    
    int[] arr  = new int[200];
    Scanner sc = new Scanner(System.in);
    
    int n = sc.nextInt();
    Set<Integer> s = new HashSet<Integer>();
    
    for(int i = 0; i < n ; i++)
    {
        arr[i] = sc.nextInt();
        
        s.add(arr[i]);
        
    }
    
    for(int result : s)
    {
        int count = 0;
        for(int j=0; j<n; j++)
        {
            if(result == arr[j])
            {
                count++;
            }
        }
        
        if(count == 1)
        {
            System.out.println(result + " Present in " + count + " time");
        }
        else
        {
       System.out.println(result + " Present in " + count + " times");
        }
    }
    
    
    
    
}
}

请编辑您的答案,将您的导入和类语句放入代码块中。在发布前始终审查您的答案。 - Md. Kamrul Amin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接