📜  结合重复

📅  最后修改于: 2021-06-25 14:19:51             🧑  作者: Mango

假设我们有一个长度为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