如何解决生日悖论"在java中没有使用嵌套循环?

时间:2016-11-16 19:27:37

标签: java android-studio

我已经尝试了嵌套循环的问题,但是如何在不使用嵌套循环的情况下在同一个类文件中解决它。问题是找出两个人在一个组中拥有相同生日的概率。它应该产生以下输出:在一组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 ;

}

}

4 个答案:

答案 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;
  }