Java查找数字出现的次数

3

我需要编写一个程序,查找一个由50个数字组成的数组中是否有数字出现了不止一次。

我已经生成了一个包含50个随机数的数组,但似乎无法想清楚如何编写循环来查看有多少个数字是相同的。


4
欢迎来到 Stack Overflow,你尝试过什么了吗? - PermGenError
你目前写了什么代码? - Mirco
使用映射,其中键是掷出的数字,值是它出现的次数。 - hoaz
我不会使用数组,而是使用ArrayList,这样你就可以使用contains()方法。这样可以避免使用for循环。 - Frank
最后一个示例展示了如何使用嵌套循环来完成。 - hoaz
显示剩余4条评论
2个回答

1
以下代码将统计每个掷出的数字,并将计数存储在numbers映射中:
Map<Integer, Integer> numbers = new HashMap<Integer, Integer>();
for (int i = 0; i < 50; i++) {
    Integer num = die.roll();
    Integer count = numbers.get(num);
    if (count == null) {
        count = Integer.valueOf(0);
    }
    count = Integer.valueOf(count.intValue() + 1);
    numbers.put(num, count);
}

然后您可以检查所有地图条目,并找到那些滚动超过一次的条目。

for (Map.Entry<Integer, Integer> entry : numbers.entrySet()) {
    if (entry.getValue().intValue() > 1) {
        System.out.println(entry.getKey() + " rolled more than once");
    }
}

或者您可以在第一个循环中更改条件以输出数字:

for (int i = 0; i < 50; i++) {
    Integer num = die.roll();
    Integer count = numbers.get(num);
    if (count != null) {
        System.out.println(num + " rolled more than once");
    } else {
        numbers.put(num, Integer.valueOf(1));
    }
}

最后,您仍然可以使用数组来查找其中的数字:

for (int i = 0; i < 50; i++) {
    nums[i] = die.roll();
    for (int j = i - 1; j >= 0; j--) {
        if (nums[i] == nums[j]) {
            System.out.println(nums[i] + " rolled more than once");
            break;
        }
    }
}

0

你可以尝试对数据进行排序

int[] nums = new int[50];
for(int i = 0; i < nums.length; i++) nums[i] = die.roll();
java.util.Arrays.sort(nums);
int dupes = 0;
for(int i = 0; i < nums.length - 1; i++) {
    if(nums[i] == nums[i+1) dupes++;
}

对数据进行排序可以将所有相等的元素放在一起,因此您可以通过一次遍历找到它们。当然,您必须对其进行排序,这不是一次操作。

这消除了使用映射的开销,仍然非常快速。排序是n lg n,比使用映射的n解决方案慢,但对于如此小的n,映射的开销可能很大。代码本身也非常简单易懂。

请参见此自包含示例,其中使用10个元素数组中的0-19数字(为了便于查看而缩小了数字;该概念完全适用)。

import java.util.*;
class Christine {
    static Random random = new Random();
    static int dieroll() {
        return random.nextInt(20);
    }
    public static void main(String[] args) {
        int[] nums = new int[10];
        for(int i = 0; i < nums.length; i++) nums[i] = dieroll();
        System.out.println(Arrays.toString(nums));
        Arrays.sort(nums);
        int dupes = 0;
        for(int i = 0; i < nums.length - 1; i++) {
            if(nums[i] == nums[i+1]) dupes++;
        }
        System.out.println(dupes);
    }


}

你可以这样运行示例:

c:\files\j>javac Christine.java

c:\files\j>java Christine
[2, 9, 8, 5, 11, 12, 15, 15, 16, 7]
1

c:\files\j>java Christine
[10, 10, 1, 18, 11, 6, 4, 3, 9, 5]
1

c:\files\j>java Christine
[8, 0, 13, 4, 5, 4, 16, 13, 6, 18]
2

在第一次运行中,有两个15。在第二次运行中,有两个10。在第三次运行中,有两个13和两个4。
考虑以下示例:
c:\files\j>java Christine
[17, 19, 19, 3, 19, 4, 18, 19, 1, 1]
4

这对于4个不同的19来说算是3个重复项,对于两个1来说是一个重复项。那么为什么19有3个重复项呢?因为如果我们将这些19称为a,b,c和d,那么a会把b视为重复项,b会把c视为重复项,c会把d视为重复项。所以就有了三个。您需要添加额外的逻辑来使其更加健壮,以捕获所有6个重复项。


你的代码会产生IndexOutOfBoundsException,糟糕。忽略它 - 我是盲人。 - hoaz
@Christine 它确实有效。我已经制作了一个自包含的示例,说明它确实有效,我将对其进行编辑。 - corsiKa

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