简体   繁体   English

计算Java中数组中整数的出现

[英]Counting occurrences of integers in an array in Java

Note: no mapping, no sorting 注意:没有映射,没有排序

Here's my code: 这是我的代码:

public static void countArray(int[] n){
    int[] m = new int[n.length]; //50 elements of integers between values of 10 & 20
    int count = 0;
    int sum = 0;

    for ( int i = 0; i < n.length ; i++){
        m[i] = n[i]; //make a copy of array 'n'
        System.out.print(m[i]+" ");

    }System.out.println();

    for ( int j =0; j < n.length ; j++){
        count =0;
        for(int i = 0; i < n.length ; i++){
            if (n[j]%m[i]==0 && n[j] == m[i])
                count++;
        }if ( n[j]%m[j] == 0)
        System.out.println(m[j] + " occurs = " + count);
    }   
}

So the problem is: I get repeating results like : "25 occurs = 5", on different lines. 所以问题是:我在不同的行上得到重复的结果,如:“ 25发生= 5”。

What I think: the problem occurs because of if ( n[j]%m[j] == 0) so I tried if ( n[j]%m[j+1] == 0) . 我的想法:由于if ( n[j]%m[j] == 0)所以我尝试了if ( n[j]%m[j+1] == 0) Another problem occurs since m[j] will be m[50] so it crashes but sort of give me the results that I want. 发生另一个问题,因为m[j]将为m[50]所以它崩溃了,但是给了我想要的结果。

Result that I want: something like this: no repetitions and covers all the random integers on a set 我想要的结果:像这样:没有重复并且覆盖了集合上的所有随机整数

17 occurs = 3
23 occurs = 2
19 occurs = 3
15 occurs = 2
12 occurs = 2

try this :(sort the array and then count the occurence of element) 试试这个:(对数组排序然后计算元素的出现)

public static void countArray(int[] n) {
    int count = 0;
    int i, j, t;
    for (i = 0; i < n.length - 1; i++) // sort the array
    {
        for (j = i + 1; j < n.length; j++) {
            if (n[i] > n[j]) {
                t = n[i];
                n[i] = n[j];
                n[j] = t;
            }

        }
    }

    for (i = 0; i < n.length;)
    {
        for (j = i; j < n.length; j++) {
            if (n[i] == n[j])
            {
                count++;
            } else
                break;
        }
        System.out.println(n[i] + " occurs " + count);
        count = 0;
        i = j;

    }

}

With some adaptation your code should work : 经过一些调整,您的代码应该可以工作:

public static void countArray(int[] n){
    boolean [] alreadyCounted = new boolean[n.length]; 

    for (int i = 0; i < n.length ; i++){
        int count = 0;
        if (alreadyCounted[i]) {
            // skip this one, already counted
            continue;
        }
        for(int j = 0; j < n.length ; j++){
            if (n[i] == n[j]) {
                // mark as already counted
                alreadyCounted[j] = true;
                count++;
            }
        }
        System.out.println(n[i] + " occurs = " + count);
    }   
}

You could definitely use the same logic with better code, I just tried to follow the original "coding style"; 您肯定可以使用具有更好代码的相同逻辑,而我只是尝试遵循原始的“编码样式”。

This is O(n^2) solution (read "very slow" ). 这是O(n ^ 2)解(读为“非常慢” )。
If you could use sorting, you could do it in O(n log(n)) - that is fast . 如果可以使用排序,则可以在O(n log(n))中进行-这是fast
With mapping you could do it in O(n) - that is blazingly fast ; 使用映射,您可以在O(n)中完成它- 速度非常

If you exploit the input limit you can lose the nested loop: 如果您利用输入限制,则可能会丢失嵌套循环:

public static void main(String[] args)
{
    //6 elements of integers between values of 10 & 20
    int[] countMe = { 10, 10, 20, 10, 20, 15 };

    countArray(countMe);
}

/** Count integers between values of 10 & 20 (inclusive) */
public static void countArray(int[] input)
{
    final int LOWEST = 10;
    final int HIGHEST = 20;

    //Will allow indexes from 0 to 20 but only using 10 to 20
    int[] count = new int[HIGHEST + 1]; 

    for(int i = 0; i < input.length; i++)
    {
        //Complain properly if given bad input
        if (input[i] < LOWEST || HIGHEST < input[i])
        {
            throw new IllegalArgumentException("All integers must be between " +
                    LOWEST + " and " + HIGHEST + ", inclusive");
        }

        //count
        int numberFound = input[i]; 
        count[numberFound] += 1;
    }

    for(int i = LOWEST; i <= HIGHEST; i++)
    {
        if (count[i] != 0) 
        {
            System.out.println(i + " occurs = " + count[i]);
        }
    }
}   

Here's a nice, efficient way to do it, rather more efficiently than the other solutions posted here. 这是一种不错的,高效的方法,比这里发布的其他解决方案更有效。 This one runs in O(n) time, where the array is of length n. 该数组以O(n)时间运行,其中数组的长度为n。 It assumes that you have some number MAX_VAL , representing the maximum value that you might find in your array, and that the minimum is 0. In your commenting you suggest that MAX_VAL==20 . 假设您有一些数字MAX_VAL ,它表示您可能在数组中找到的最大值,并且最小值为0。在您的注释中,建议MAX_VAL==20

public static void countOccurrences(int[] arr) {
    int[] counts = new int[MAX_VAL+1];
    //first we work out the count for each one
    for (int i: arr)
        counts[i]++;
    //now we print the results
    for (int i: arr)
        if (counts[i]>0) {
            System.out.println(i+" occurs "+counts[i]+" times");
            //now set this count to zero so we won't get duplicates
            counts[i]=0;
        }
}

It first loops through the array increasing the relevant counter each time it finds an element. 它首先遍历数组,每次找到一个元素时都会增加相关计数器。 Then it goes back through, and prints out the count for each one. 然后返回,并打印出每个计数。 But, crucially, each time it prints the count for an integer, it resets that one's count to 0, so that it won't get printed again. 但是,至关重要的是,每次打印整数的计数时,都会将其计数重置为0,这样就不会再次打印该计数。

If you don't like the for (int i: arr) style, this is exactly equivalent: 如果您不喜欢for (int i: arr)样式,则完全相同:

public static void countOccurrences(int[] arr) {
    int[] counts = new int[MAX_VAL+1];
    //first we work out the count for each one
    for (int i=0; i<arr.length; i++)
        counts[arr[i]]++;
    //now we print the results
    for (int i=0; i<arr.length; i++)
        if (counts[arr[i]]>0) {
            System.out.println(arr[i]+" occurs "+counts[arr[i]]+" times");
            //now set this count to zero so we won't get duplicates
            counts[arr[i]]=0;
        }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM