简体   繁体   English

在Java中找到两个随机数之间的平均值,然后计算使用switch语句将一个数字滚动多少次

[英]find average between two random numbers in java and then count how many times a number was rolled with a switch statement

Hello again StackOverflow, 您好,StackOverflow,

New question needing help with some code. 需要一些代码帮助的新问题。 So far I'm making a random number generator that will choose a random number between 1-100 for rolls and then roll a "die" for a number between 1-6 . 到目前为止,我正在制作一个随机数生成器,它将为掷骰选择1-100之间的随机数,然后为1-6掷一个“骰子”。 It then prints out every roll and number rolled up to said a random number between 1-100. 然后,它打印出每一卷,并将卷起来的数字表示为介于1到100之间的随机数。

The problem I'm having is this. 我遇到的问题是这个。 Let's be simple and say that the random number generated between 1-100 is 9 and the die rolls in order for each roll is 简单地说, 在1-100之间生成的随机数是9,而每个辊的模辊数量是

1, 6, 3 , 5, 4, 2, 1, 6, 6 1,6,3,5,4,2,1,6,6

The output is fine and the averaging is fine. 输出很好,平均也很好。 The new problem I have is this: 我的新问题是这样的:

Add to the program a switch statement to keep track of how many times each number comes up. 在程序中添加一个switch语句,以跟踪每个数字出现了多少次。

I have a basic idea on how to do this but I am a bit confused on how to actually go along with this and execute it. 我对如何执行此操作有基本的了解,但对如何实际执行并执行它感到有些困惑。 Help please 请帮助

My Current Code: (UPDATE: The first problem has been solved, the new problem is said above) 我当前的代码:(更新:第一个问题已解决,上面提到了新问题)

        class Main {
  public static void main(String[] args) 
  {

    int rolls = (int)(Math.random()*100);
    System.out.println("Number of Rolls: "+ rolls);

    System.out.println(" ");
    System.out.println("Rolls\t\tNumber");

    double sum = 0;
    for (int i = 1; i <= rolls ; i++)
      {
        int dienumber = (int)(Math.random()*6+1);    
        sum += dienumber;
        System.out.println(i + "\t\t" + dienumber);
      }

    double average = sum /(1.0*rolls);

    System.out.println(" ");
    System.out.printf("%-2s%.2f\n","Average: ", average);

  }
}

Thanks again 再次感谢

Sum all the random numbers in a variable, and divide by number of rolls 将所有随机数加到一个变量中,然后除以掷骰数

double sum = 0;
for (int i = 1; i <= rolls ; i++) {
    int dienumber = (int)(Math.random()*6+1);
    sum += dienumber;
    System.out.println(i + "\t\t" + dienumber);
}
double avg = sum / rolls;

You can as well collect you random numbers into an array and calculate average using streams: 您也可以将随机数收集到数组中,并使用流计算平均值:

int rolls = (int)(Math.random()*100);
int rollsArray[] = new int[rolls];
for (int i = 1; i < rollsArray.length ; i++)
{
    rollsArray[i] = (int)(Math.random()*6+1);

}
System.out.println(Arrays.stream(rollsArray).average()); 
// example output OptionalDouble[3.0]

You can create a int variable that will count the total inside the loop after each roll. 您可以创建一个int变量,该变量将在每次滚动后对循环内的总数进行计数。 After the loop, just divide this total by your number of rolls. 循环之后,只需将总数除以您的掷骰数即可。

class Main {
     public static void main(String[] args) 
    {

        int rolls = (int)(Math.random()*100);
        int total =0
        System.out.println("Number of Rolls: "+ rolls);

        System.out.println(" ");
        System.out.println("Rolls\t\tNumber");
        for (int i = 1; i <= rolls ; i++)
        {
            int dienumber = (int)(Math.random()*6+1);    
            System.out.println(i + "\t\t" + dienumber);
            total += dienumber; 
        }
        double average = total /(1.0d*rolls);
        System.out.println("Average = "+average);
    }
}

This generates a number in the range [0, 99], not [1, 100]: 这将生成范围为[0,99]而不是[1,100]的数字:

int rolls = (int)(Math.random()*100);

Performance-wise it's a good idea to re-use a Random instead of calling Math.random repeatedly: 在性能方面,最好重用Random而不是重复调用Math.random:

public class Main {

    private static final Random RANDOM = new Random();

    public static void main(String[] args) {
        int rolls = RANDOM.nextInt(99) + 1;

Note that, if you ever use randomness for generating security sensitive things like activation codes, use SecureRandom instead. 请注意,如果您曾经使用随机性来生成对安全敏感的事物(如激活码),请改用SecureRandom

To calculate the average just keep track of the sum: 要计算平均值,只需跟踪总和:

int sum = 0;
for (int i=1; i <= rolls ; i++) {
    int dienumber = RANDOM.nextInt(6) + 1;    
    System.out.println(i + "\t\t" + dienumber);
    sum += dieNumber;
}
double average = ((double) sum) / rolls;
System.out.printf("Average: %s%n", average);

You could also create a separate class to calculate the average, be all object-oriented and score brownie points for effort: 您还可以创建一个单独的类来计算平均值,所有类都面向对象,并在果仁评分上付出努力:

public class Average {

    private double total;
    private int count;

    public synchronized void add(double value) {
        total += value;
        count++;
    }

    public double getAverage() {
        if (count == 0) {
            throw new IllegalStateException("Cannot calculate average, no values added");
        }
        return total / count;       
    }

    public double getTotal() {
        return total;
    }

    public int getCount() {
        return count;
    }

    public synchronized void reset() {
        total = 0;
        count = 0;
    }
}

And your code would use this like so: 而且您的代码将这样使用:

Average average = new Average();
for (int i=1; i <= rolls ; i++) {
    int dienumber = RANDOM.nextInt(6) + 1;    
    System.out.println(i + "\t\t" + dienumber);
    average.add(dieNumber);
}
System.out.printf("Average: %s%n", average.getAverage());

EDIT: As a general rule of thumb, when someone (or your homework assignment) tells you to add a switch statement: don't do it. 编辑:作为一般的经验法则,当某人(或您的家庭作业)告诉您添加switch语句时:不要这样做。 Switch statements are evil pools of gunk which accumulate demons and reek of the foul stench of a project room filled with 2000 PHP developers. switch语句是一堆恶魔般的恶魔池,它们堆积着由2000个PHP开发人员组成的项目室的恶臭和臭气。 Don't. 别。 (I can recommend reading Clean Code by Uncle Bob ) (我建议阅读Bob叔叔的Clean Code

But seriously: keeping track of how many times a number comes up is a valid requirement. 但是请认真考虑:跟踪数字出现多少次是有效的要求。 Telling the developer to use a switch statement for this is not. 不告诉开发人员为此使用switch语句。 This is a tendency you will come across a lot with users: they tend to specify the solution they envision, instead of formulating the problem they want to solve. 这是用户会经常遇到的一种趋势:他们倾向于指定他们所设想的解决方案,而不是提出他们要解决的问题。 This is dangerous, since if you buy into it you may very well start off on the wrong foot. 这很危险,因为如果您购买它,很可能会从错误的脚开始。 The solution suggested by stakeholders is very often not optimal and rooted in their past domain experience, not technical and design knowledge. 利益相关者建议的解决方案通常不是最优的,而是植根于他们过去的经验,而不是技术和设计知识。 </rant>

Instead, in this case, use a Map to keep track of the outcomes. 相反,在这种情况下,请使用地图来跟踪结果。 If the cases are more diverse than just keeping track of a value like here, revert to the strategy pattern to solve the problem in an object-oriented way. 如果情况比仅仅跟踪此处的值更多样化,请还原为策略模式以面向对象的方式解决问题。

Since I already proposed the lovely 'Average' class we can rename this to 'Statistics' and adorn it with a Map: 由于我已经提出了可爱的“ Average”类,因此我们可以将其重命名为“ Statistics”并用Map进行修饰:

public class Statistics {

    private int total;
    private int count;
    private Map<Integer, Integer> distribution = new HashMap<>();

    public synchronized void add(int value) {
        total += value;
        count++;
        updateDistribution(value);
    }

    private void updateDistribution(int value) {
        Integer count = distribution.get(value);
        if (count == null) {
            count = 0;
        }
        count++;
        distribution.put(value, count);

    public double getAverage() {
        if (count == 0) {
            throw new IllegalStateException("Cannot calculate average, no values added");
        }
        return total / count;       
    }

    public double getTotal() {
        return total;
    }

    public int getCount() {
        return count;
    }

    public synchronized void reset() {
        total = 0;
        count = 0;
        distribution.clear();
    }

    public int getCount(int value) {
        Integer count = distribution.get(value); 
        if (count == null) {
            count = 0;
        }
    }
}

Functional approach (Java 1.8+): 功能性方法(Java 1.8+):

{
    // ...
    double average = IntStream.range(0, rolls)
            .map(this::roll)
            .average()
            .orElse(0);
    System.out.println("Average : " + average);

}

private int roll(int i) {
    int dieNumber = (int) (Math.random() * 6 + 1);
    System.out.println(i + "\t\t" + dieNumber);
    return dieNumber;
}

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

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