计算每个数字在数组中出现的次数(正值和负值)

时间:2018-06-29 05:13:57

标签: java arrays counting

我正在处理一个处理数组的任务,我几乎完成了它,但是我一直坚持不使用排序,哈希图或列表来计数数组中的每个元素(正负)某种。我必须只能使用基本的Java技术。我的代码适用于所有正值,但我却忽略了如何计算负数。.有人可以阐明我如何修正代码,以便可以使用正负整数的整个范围吗?谢谢!

public static void countArray(int[] arr){
    int[] count = new int[arr.length];
    int temp = 0;

    for(int i = 0; i < arr.length; i++){
        temp = arr[i];
        count[temp]++;
    }
    for(int 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]);
        }
    }
}

3 个答案:

答案 0 :(得分:2)

您必须以某种方式将值映射到计数数组中的值。由于无法使用映射,因此可以使用另一个数组来包含从您要计数的值到counts数组中的索引的映射:

public static void count(int[] numbers) {
    int[] counts = new int[numbers.length];
    int[] mapping = new int[numbers.length];
    int mappings = 0; // how many mappings are used

    // map them
    for (int number : numbers) {
        boolean found = false;
        for (int i = 0; i < mappings; i++) {
            if (number == mapping[i]) {
                found = true; // already mapped
            }
        }
        if (!found) {
            mapping[mappings++] = number; // add a new mapping
        }
    }

    // count them
    for (int number : numbers) {
        int mapped = 0;
        boolean found = false;
        for (int i = 0; i < mappings; i++) {
            if (number == mapping[i]) {
                found = true;
                mapped = i; // found the mapping
                break;
            }
        }
        if (!found) throw new IllegalStateException("can't happen");
        counts[mapped]++;
    }

    // print them
    for (int i = 0; i < mappings; i++) {
        int number = mapping[i];
        int count = counts[i];
        System.out.format("%,d occurs %d time%s%n", number, count, count==1?"":"s");
    }
}

如果有重复项,则不会完全使用mappings数组,这就是为什么我们需要分别跟踪使用了多少个映射而不是循环到mapping.length的原因。

答案 1 :(得分:-2)

您可以使用Map<Integer,Integer>来保存计数,也可以进行第一遍计算最小值,然后递增count[temp-min]

更新:

实际上,您需要计算最小值和最大值,并分配一个长度为max-min+1的数组。

更新2:

public static void countArray(int[] arr){
    if (arr != null && arr.length > 0) {
        int min = Integer.MAX_VALUE;
        int max = Integer.MIN_VALUE;
        for (int i = 0; i < arr.length; ++i) {
            if (arr[i] < min) {
                min = arr[i];
            }
            if (arr[i] < max) {
                max = arr[i];
            }
        }
        int[] count = new int[max-min+1];
        int temp = 0;

        for(int i = 0; i < arr.length; i++){
            temp = arr[i];
            count[temp-min]++;
        }
        for(int i = 0; i < count.length; i++){
            if(count[i] == 1){
                System.out.printf("%d occurs %d time\n", i-min, count[i]);
            }else if(count[i] >= 2){
                System.out.printf("%d occurs %d times\n", i-min, count[i]);
            }
        }
    }
}

答案 2 :(得分:-2)

就像maja的建议一样,您可以分成两个数组。

public static void countArray(int[] arr){
    int[] positiveIntCounts = new int[Integer.MAX_VALUE];
    int[] negativeIntCounts = new int[Integer.MAX_VALUE];
    int max;
    int min;

    int temp = 0;

    for(int i = 0; i < arr.length; i++){
        temp = arr[i];
        if (temp >= 0) {
            positiveIntCounts[temp]++;
            if (temp > max) {
                max = temp;
            }
        }
        else {
            negativeIntCounts[-temp]++;
            if (temp < min) {
                min = temp;
            }
        }
    }

    for (int i = 1; i <= max; i++){
        if (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]);
        }
    }

    for (int i = 1; i <= -max; i++){
        if (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]);
        }
    }
}