我已经尝试了嵌套循环的问题,但是如何在不使用嵌套循环的情况下在同一个类文件中解决它。问题是找出两个人在一个组中拥有相同生日的概率。它应该产生以下输出:在一组5人和10000个模拟中,概率为2.71%。注意:使用arraylist或hashmap是可能的。但我不知道怎么做。谢谢
public void process() {
int groupSize = System.out.getSize();
int simulationCount = System.out.getCount();
if (groupSize < 2 || groupSize > 365) {
System.out.makeAlertToast("Group Size must be in the range 2-365.");
return;
}
if (simulationCount <= 0) {
System.out.makeAlertToast("Simulation Count must be positive.");
return;
}
double percent = calculate(groupSize, simulationCount);
// report results
System.out.println("For a group of " + groupSize + " people, the percentage");
System.out.println("of times that two people share the same birthday is");
System.out.println(String.format("%.2f%% of the time.", percent));
}
public double calculate(int size, int count) {
int numTrialSuccesses = 0;
// Repeat and count.
for (int n=0; n < count; n++) {
Random rand = new Random(n);
// Generate birthdays (random array)
int[] birthdays = new int [size];
for (int i=0; i <size; i++) {
birthdays[i] = rand.nextInt (365);
}
// Check if any two match.
boolean matchExists = false;
for (int i=0; i < size; i++) {
for (int j=0; j < size; j++) {
if ( (i != j) && (birthdays[i] == birthdays[j]) ) {
// Note: musn't forget the i!=j test above!
matchExists = true;
if (matchExists) break;
}
}
}
if (matchExists) {
numTrialSuccesses ++;
}
} //end-for-trials
double prob = ((double) numTrialSuccesses *100)/ (double) count;
return prob ;
}
}
答案 0 :(得分:2)
使用花哨数据结构HashSet
的解决方案。正如评论中提到的那些你可以使用365元素的bool数组,如果遇到你可以切换为true。
以下是类似的想法。如果尚未包含生日,则将每个生日添加到集合中。如果Set 包含生日,则递增计数器。现在你不需要那个讨厌的第二次迭代,所以你的时间复杂度下降到O(n)。它下降到O(n),因为集合中的查找具有恒定时间。
public double calculate(int size, int count) {
int numTrialSuccesses = 0;
// Repeat and count.
for (int n=0; n < count; n++) {
Set<Integer> set = new HashSet<Integer>();
for (int i=0; i <size; i++) {
int bday = rand.nextInt (365);
Integer bday1 = new Integer(bday);
if(set.contains(bday1)){
numTrialSuccesses++;
break;
}else{
set.add(bday1);
}
}
} //end-for-trials
double prob = ((double) numTrialSuccesses *100)/ (double) count;
//like wise comments have noted this is not the probability!!! Just a simulation
return prob ;
}
答案 1 :(得分:0)
此代码:
Range
可以更改为:
int[] birthdays = new int [size];
for (int i=0; i <size; i++) {
birthdays[i] = rand.nextInt (365);
}
// Check if any two match.
boolean matchExists = false;
for (int i=0; i < size; i++) {
for (int j=0; j < size; j++) {
if ( (i != j) && (birthdays[i] == birthdays[j]) ) {
// Note: musn't forget the i!=j test above!
matchExists = true;
if (matchExists) break;
}
}
}
if (matchExists) {
numTrialSuccesses ++;
}
答案 2 :(得分:0)
在java-8中,
libName.so.1
我不知道它将如何与您的在线评分员合作,但使用视频流进行练习会很有趣。
答案 3 :(得分:0)
没有任何必要像原始数字那样固定生日。
创建一个365个存储桶的数组,并在每个存储桶中记录生日到生日的日期。这样可以使用有效的数组操作。
下面的代码不是每次都创建一个新数组,而是使用System.arraycopy
在现有数组上复制一个调零数组,这会提高性能。
尽管如此,相对于先前给出的HashSet
示例而言,性能提升最多是适度的,执行速度快5到6倍,但不快几个数量级。
因此,如果使用HashSet
和类似工具可以提高清晰度,那么请保持清晰度。
public double calculate(int size, int count) {
int numTrialSuccesses = 0;
int[] daysOfYear = new int[365];
final int[] empty = new int[365];
// Repeat and count.
for (int n = 0; n < count; n++) {
Random rand = new Random(n);
// Efficiently clear out the array
System.arraycopy(empty, 0, daysOfYear, 0, 365);
boolean matchExists = false;
for (int i = 0; i < size; i++) {
int birthday = rand.nextInt(365);
// Compare, then increment, the bucket for the birthday
if(daysOfYear[birthday]++>0){
matchExists = true;
break;
}
}
if (matchExists) {
numTrialSuccesses++;
}
} //end-for-trials
double prob = ((double) numTrialSuccesses * 100) / (double) count;
return prob;
}