Сочетания
Необходимо получить все возможные сочетания чисел от 1 до K, которые имеют длину N (в последовательности могут быть одинаковые элементы).
Для решения задачи выделим в памяти глобальный массив A[N]. Представим себе, что все его первые q элементов (с номерами от 0 до q-1) уже определены и надо найти все сочетания, при которых эти элементы не меняются. Сначала ставим на место элемент с номером q. По условию на этом месте может стоять любое число от 1 до K, поэтому сначала ставим 1 и находим все варианты, при которых q+1 элементов уже поставлены (здесь будет рекурсивный вызов), затем ставим на это место 2 и т.д. Если q=N, то все элементы уже поставлены на место и надо печатать массив - это одна из нужных комбинаций. Ниже приведена рекурсивная процедура, которая использует массив A[N] и печатает все комбинации на экране.
#include <stdio.h> #include <time.h> #include <iostream> using namespace std; // --------------------------Вывод массива на экран void PrintData( int Data[], int N ) { for (int i = 0; i < N; i++ ) cout<< Data[i]; cout<<'\n'; } //------------------------------------------------- void Combinations ( int A[], int N, int K, int q ) { if (q == N) PrintData( A, N ); else for (int i = 1; i <= K; i ++ ) { A[q] = i; Combinations(A, N, K, q+1); } }
//----------------------------------------------- void main() { int A[8], N = 8, K = 2; Combinations ( A, N, K, 0 ); system("pause"); return; }
|
Результат 11111111 11111112 11111121 11111122 11111211 11111212 11111221 11111222 11112111 11112112 11112121 11112122 11112211 11112212 11112221 11112222 ... |
В основной программе надо вызвать процедуру с параметром q=0, поскольку ни один элемент
еще не установлен.
Контрольные вопросы раздела
1. (Да/Нет). При выполнении одних и тех же действий рекурсивная процедура требует выделения меньшего количества памяти из стека, чем нерекурсивная.
2. При выполнении какого из условий в процедуре Factorial прекращается рекурсивный вызов этой процедуры?
3. Какая команда выполняется в процедуре Factorial после завершения команды рекурсивного вызова?
4. Что произойдет, если с помощью процедуры Factorial попытаться вычислить значениевыражения 13!?
5. Задача повышенной сложности. Какое количество стековой памяти требуется для работы программы Factorial при вычислении 12!?
6. Задача повышенной сложности. Запишите на псевдокоде рекурсивный алгоритм, который генерирует первые 20 чисел последовательности Фибоначчи A, 1, 2, 3, 5, 8, 13, 21,...). Объясните, почему этот алгоритм не является эффективным.
