И снова здравствуйте, StackOverflow,
Новый вопрос, требующий помощи с кодом. Пока я делаю генератор случайных чисел, который выбирает случайное число от 1 до 100 для бросков, а затем бросает «кубик» для числа между 1-6. Затем он распечатывает каждый рулон и число, свернутое до указанного случайного числа от 1 до 100.
У меня проблема вот в чем. Давайте будем простыми и скажем, что сгенерированное случайное число от 1 до 100 равно 9, а количество бросков кубика для каждого броска равно
1, 6, 3 , 5, 4, 2, 1, 6, 6
Результат в порядке, и усреднение в порядке. У меня новая проблема:
Add to the program a switch statement to keep track of how many times each number comes up.
У меня есть базовое представление о том, как это сделать, но я немного запутался в том, как на самом деле согласиться с этим и выполнить его. Помогите, пожалуйста
Мой текущий код: (ОБНОВЛЕНИЕ: первая проблема решена, новая проблема указана выше)
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);
}
}
Спасибо еще раз
Это твое домашнее задание?
Суммируйте все случайные числа в переменной и разделите на количество бросков.
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;
Я сделал это, и теперь каждый раз среднее значение распечатывается как 3,00.
@neil У меня хорошие результаты. Вы можете поделиться своим обновленным кодом?
отредактировал приведенный выше код, потому что у меня возникла новая проблема. Обновленный код приведен выше, я использовал код других комментаторов, и их код работал нормально.
@neil sum
должен быть double
, а не int
. int / int
приведет к int
. Всегда 3 из-за небольшого диапазона чисел. Преобразование sum
в double
double avg = (double)sum / rolls;
также поможет.
Вы также можете собрать случайные числа в массив и вычислить среднее значение с помощью потоков:
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]
Вы можете создать переменную типа int, которая будет подсчитывать сумму внутри цикла после каждого броска. После завершения цикла просто разделите полученную сумму на ваше количество роллов.
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);
}
}
Это генерирует число в диапазоне [0, 99], а не [1, 100]:
int rolls = (int)(Math.random()*100);
С точки зрения производительности рекомендуется повторно использовать 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;
Обратите внимание: если вы когда-либо использовали случайность для генерации важных для безопасности вещей, таких как коды активации, используйте вместо этого SecureRandom.
Чтобы рассчитать среднее значение, просто запишите сумму:
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);
Вы также можете создать отдельный класс для расчета среднего, быть полностью объектно-ориентированным и оценивать усилия:
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;
}
}
И ваш код будет использовать это так:
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());
Обновлено: Как правило, когда кто-то (или ваше домашнее задание) говорит вам добавить оператор switch: не делайте этого. Операторы переключения - это злые лужи мусора, в которых накапливаются демоны и воняют отвратительным запахом проектной комнаты, заполненной 2000 разработчиками PHP. Не надо. (Могу порекомендовать прочитать Чистый код от дяди Боба)
А если серьезно: отслеживание того, сколько раз появляется число, является допустимым требованием. Указание разработчику использовать для этого оператор switch - нет. Это тенденция, с которой вы часто будете сталкиваться с пользователями: они склонны указывать решение, которое они видят, вместо того, чтобы формулировать проблему, которую они хотят решить. Это опасно, так как если вы купитесь на это, вы вполне можете начать не с той ноги. Решение, предлагаемое заинтересованными сторонами, очень часто не является оптимальным и основывается на их прошлом опыте в предметной области, а не на технических и дизайнерских знаниях. </rant>
Вместо этого в этом случае используйте карту, чтобы отслеживать результаты. Если случаи более разнообразны, чем просто отслеживание значения, как здесь, вернитесь к шаблон стратегии, чтобы решить проблему объектно-ориентированным способом.
Поскольку я уже предлагал прекрасный класс «Средний», мы можем переименовать его в «Статистика» и украсить его картой:
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;
}
}
}
Функциональный подход (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;
}
Добавьте dienumber к другой переменной и просто разделите на ролики в конце. (Имея в виду, что если новая переменная является int, она проигнорирует любую плавающую точку. Например, 7/3 = 2.)