假设我们有一个长度为n的字符串,并且我们想一次生成所有带r且不带重复的组合/排列。组合学有四个基本概念
1)没有重复/替换的组合。
2)与重复/替换的组合。
3)排列,无重复/替换。
4)带有重复/替换的排列。
下表是描述组合理论中基本概念的摘要表。
汇总表
Replacements/Repetitions allowed | Replacements/Repetitions not allowed | |
Permutations/Order Important | nr possibilities https://www.geeksforgeeks.org/print-all-combinations-of-given-length/ See the special case when r=n below https://www.geeksforgeeks.org/print-all-permutations-with-repetition-of-characters |
nPr possibilities https://www.geeksforgeeks.org/write-a-c-program-to-print-all-permutations-of-a-given-string/ Here r=n, as we are permuting all the characters of the string. |
Combinations/Order Not Important | n+r-1Cr possibilities
Current Article ( https://www.geeksforgeeks.org/combinations-with-repetitions ) |
nCr possibilities
https://www.geeksforgeeks.org/print-all-possible-combinations-of-r-elements-in-a-given-array-of-size-n/ |
本文是关于第三种情况的(顺序不重要,允许重复)。
这个想法是使字符串的所有可能性重复出现,即使字符在重复。
递归的基本情况是当总共有“ r”个字符并且可以打印组合时。
为了清楚起见,请参见字符串的递归树-“ 1 2 3 4”且r = 2
下面是实现。
C
// C program to print all combination of size r in an array
// of size n with repetitions allowed
#include
/* arr[] ---> Input Array
chosen[] ---> Temporary array to store indices of
current combination
start & end ---> Staring and Ending indexes in arr[]
r ---> Size of a combination to be printed */
void CombinationRepetitionUtil(int chosen[], int arr[],
int index, int r, int start, int end)
{
// Since index has become r, current combination is
// ready to be printed, print
if (index == r)
{
for (int i = 0; i < r; i++)
printf("%d ", arr[chosen[i]]);
printf("\n");
return;
}
// One by one choose all elements (without considering
// the fact whether element is already chosen or not)
// and recur
for (int i = start; i <= end; i++)
{
chosen[index] = i;
CombinationRepetitionUtil(chosen, arr, index + 1,
r, i, end);
}
return;
}
// The main function that prints all combinations of size r
// in arr[] of size n with repitions. This function mainly
// uses CombinationRepetitionUtil()
void CombinationRepetition(int arr[], int n, int r)
{
// Allocate memory
int chosen[r+1];
// Call the recursice function
CombinationRepetitionUtil(chosen, arr, 0, r, 0, n-1);
}
// Driver program to test above functions
int main()
{
int arr[] = {1, 2, 3, 4};
int n = sizeof(arr)/sizeof(arr[0]);
int r = 2;
CombinationRepetition(arr, n, r);
return 0;
}
Java
// Java program to print all combination of size r in an array
// of size n with repetitions allowed
class GFG {
/* arr[] ---> Input Array
chosen[] ---> Temporary array to store indices of
current combination
start & end ---> Staring and Ending indexes in arr[]
r ---> Size of a combination to be printed */
static void CombinationRepetitionUtil(int chosen[], int arr[],
int index, int r, int start, int end) {
// Since index has become r, current combination is
// ready to be printed, print
if (index == r) {
for (int i = 0; i < r; i++) {
System.out.printf("%d ", arr[chosen[i]]);
}
System.out.printf("\n");
return;
}
// One by one choose all elements (without considering
// the fact whether element is already chosen or not)
// and recur
for (int i = start; i <= end; i++) {
chosen[index] = i;
CombinationRepetitionUtil(chosen, arr, index + 1,
r, i, end);
}
return;
}
// The main function that prints all combinations of size r
// in arr[] of size n with repitions. This function mainly
// uses CombinationRepetitionUtil()
static void CombinationRepetition(int arr[], int n, int r) {
// Allocate memory
int chosen[] = new int[r + 1];
// Call the recursice function
CombinationRepetitionUtil(chosen, arr, 0, r, 0, n - 1);
}
// Driver program to test above functions
public static void main(String[] args) {
int arr[] = {1, 2, 3, 4};
int n = arr.length;
int r = 2;
CombinationRepetition(arr, n, r);
}
}
/* This Java code is contributed by PrinciRaj1992*/
Python3
# Python3 program to print all combination
# of size r in an array of size n
''' arr[] ---> Input Array
chosen[] ---> Temporary array to store
current combination
start & end ---> Staring and Ending indexes in arr[]
r---> Size of a combination to be printed
'''
def CombinationRepetitionUtil(chosen, arr, index,
r, start, end):
# Current combination is ready,
# print it
if index == r:
for j in range(r):
print(chosen[j], end = " ")
print()
return
# When no more elements are
# there to put in chosen[]
if start > n:
return
# Current is included, put
# next at next location
chosen[index] = arr[start]
# Current is excluded, replace it
# with next (Note that i+1 is passed,
# but index is not changed)
CombinationRepetitionUtil(chosen, arr, index + 1,
r, start, end)
CombinationRepetitionUtil(chosen, arr, index,
r, start + 1, end)
# The main function that prints all
# combinations of size r in arr[] of
# size n. This function mainly uses
# CombinationRepetitionUtil()
def CombinationRepetition(arr, n, r):
# A temporary array to store
# all combination one by one
chosen = [0] * r
# Print all combination using
# temprary array 'chosen[]'
CombinationRepetitionUtil(chosen, arr, 0, r, 0, n)
# Driver code
arr = [ 1, 2, 3, 4 ]
r = 2
n = len(arr) - 1
CombinationRepetition(arr, n, r)
# This code is contributed by Vaibhav Kumar 12.
C#
// C# program to print all combination of size r in an array
// of size n with repetitions allowed
using System;
public class GFG{
/* arr[] ---> Input Array
chosen[] ---> Temporary array to store indices of
current combination
start & end ---> Staring and Ending indexes in arr[]
r ---> Size of a combination to be printed */
static void CombinationRepetitionUtil(int []chosen, int []arr,
int index, int r, int start, int end) {
// Since index has become r, current combination is
// ready to be printed, print
if (index == r) {
for (int i = 0; i < r; i++) {
Console.Write(arr[chosen[i]]+" ");
}
Console.WriteLine();
return;
}
// One by one choose all elements (without considering
// the fact whether element is already chosen or not)
// and recur
for (int i = start; i <= end; i++) {
chosen[index] = i;
CombinationRepetitionUtil(chosen, arr, index + 1,
r, i, end);
}
return;
}
// The main function that prints all combinations of size r
// in arr[] of size n with repitions. This function mainly
// uses CombinationRepetitionUtil()
static void CombinationRepetition(int []arr, int n, int r) {
// Allocate memory
int []chosen = new int[r + 1];
// Call the recursice function
CombinationRepetitionUtil(chosen, arr, 0, r, 0, n - 1);
}
// Driver program to test above functions
public static void Main() {
int []arr = {1, 2, 3, 4};
int n = arr.Length;
int r = 2;
CombinationRepetition(arr, n, r);
}
}
// This code is contributed by PrinciRaj1992
输出 :
1 1
1 2
1 3
1 4
2 2
2 3
2 4
3 3
3 4
4 4
时间复杂度:对于长度为n的字符串,并且每次重复进行r重复,则总共需要O( n + r-1 C r )时间。
参考资料– https://en.wikipedia.org/wiki/Combination