Печать комбинаций кубиков в Java

#java #statistics

#java #Статистика

Вопрос:

Для проекта мне нужно найти способ печатать все способы броска 5 кубиков с 6 сторонами, порядок не важен. Я пытался использовать вложенные циклы for, подобные so, но я понимаю, что это печать перестановок вместо комбинаций:

 int counter = 0;
        for(int i=1; i<7; i  ) {
            
            for(int m = 1; m<7; m  ) {
                
                for(int j = 1; j<7; j  ) {
                    
                    for(int k = 1; k<7; k  ) {
                        
                        for(int h = 1; h<5; h  ) {
                            System.out.printf("-----",i,m,j,k,h);
                            counter  ;
                            System.out.println(" " counter);
                        }
                    }
                }
            }
        }
 

Есть ли эффективный способ сделать это?

Редактировать: я должен добавить, это для Java! Спасибо!

Редактировать еще раз: да, я имел в виду 5 кубиков, каждый из которых имеет 6 сторон. Извините за путаницу

Комментарии:

1. вы хотите вывести все возможные исходы из 5 6 sided кубиков?

Ответ №1:

если порядок не имеет значения, попробуйте:

 for (int i = 1; i < 7; i  ) {
    for (int m = i; m < 7; m  ) {
        for (int j = m; j < 7; j  ) {
            ...
 

то же самое для всех кубиков, опубликованный код показывает только 3 первых
то есть начальное значение никогда не меньше значения предыдущих кубиков — результат будет вроде как отсортирован.
(например, учитывая только 2 кубика, это исключит такие результаты, как 2 1 или 3 1 , но разрешит 1 1 1 2 и 1 3 )


Примечание: легче читать (IMO): for (int i = 1; i <= 6; i ) {

Комментарии:

1. Это работает отлично! Большое спасибо за ваш ответ!

Ответ №2:

Рассмотрим этот сокращенный пример с двумя шестигранными кубиками:

 for (int i = 1; i <= 6; i  )
    for (int j = 1; j <= 6; j  )
        System.out.println(i   " "   j);
 

Это выведет 36 (6 ^ 2) комбинаций. Но многие из них являются дубликатами. Например, пара чисел 1 2 и 2 1 в основном одинаковы. Что, если бы вы могли вычислять только УНИКАЛЬНЫЕ пары? Из 36 перечисленных пар при выполнении приведенного выше кода только 21 являются уникальными комбинациями. Итак, как бы вы это сделали?

 for (int i = 1; i <= 6; i  )
    for (int j = i; j <= 6; j  )
        System.out.println(i   " "   j);
 

Во внутреннем цикле я начинал каждую итерацию со значения i вместо 1. Что это делает? На первой итерации вы не распечатаете ничего, кроме уникальных пар. НО на последующих итерациях мне нужно исключить число, которое уже было выпало. Я делаю это, запуская внутренний цикл с текущим начальным значением i . Это гарантирует отсутствие повторяющихся пар. Например, на второй итерации я исключаю значение «1», начиная с текущего i значения 2; что устраняет повторяющуюся 2 1 пару и вместо этого запускает второй раунд 2 2 . К тому времени, когда вы дойдете до последней итерации, будет распечатана только одна оставшаяся уникальная пара : 6 6 .

Это достаточно просто. Но как добавление еще одного кубика влияет на решение? Используйте тот же подход. Запустите самый внутренний цикл со значением переменной counter непосредственного внешнего цикла следующим образом:

 for (int i = 1; i <= 6; i  )
    for (int j = i; j <= 6; j  )
        for (int k = j; k <= 6; k  )
            System.out.println(i   " "   j   " "   k);
 

Это решение выводит только 56 комбинаций, а не 216 (6 ^ 3). Это ОГРОМНОЕ улучшение производительности. Спроектируйте это улучшение с помощью большего количества внутренних циклов.

Комментарии:

1. Спасибо! Идеальное объяснение

2. @oshp Спасибо! Я забыл упомянуть, что для вашего примера количество итераций (5 кубиков) уменьшается с 7776 (с дублированием) примерно до 256 при таком подходе.