The language is not important, I will explain with the example of the Python language:

myarray=['a', 'b', 'c'] number=3 def myfunc(myarray, number): #при number = 3 newarray=[] for s1 in myarray for s2 in myarray for s3 in myarray newarray.append(s1+s2+s3) return newarray 

should return: aaa, aab, aac, aba, abb, abc, etc., Ie if number = 4 , then all four digits, which can be compiled, if 5, then five digits, and so on.

How to do it?

  • Read about long arithmetic, you can use them here. Those. Your combinations with repetitions can be viewed as a gradual increase by one (aaa + 1 = aab, abc + 1 = aca). Only it will be necessary to take into account that the digit capacity of you is limited by the number. - BOPOH
  • Can you elaborate on what you mean? What to increase by one? ASCII character code? If yes, then this is not an option, there is not in order (some characters can be omitted, and there will not necessarily be letters, there may be special signs) - Samir Routh
  • no, not to increase the ascii-code, and the index in the array myarray. Those. at each step you will have the index of the next element equal to (index + 1) % 3 In the evening I will sign the algorithm - BOPOH

4 answers 4

 from itertools import product chars = 'abc' print(list(product(chars, repeat=3))) # [('a', 'a', 'a'), ('a', 'a', 'b'), ('a', 'a', 'c'), ... 

Output already convert to what you need.

Here is the pseudo- product() implementation code from the documentation :

 def product(*args, repeat=1): # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111 pools = [tuple(pool) for pool in args] * repeat result = [[]] for pool in pools: result = [x+[y] for x in result for y in pool] for prod in result: yield tuple(prod) 
  • I suspect that the algorithm itself is interested in the top-starter, and not the finished function from the library. - zed
  • @zed right. I need an algorithm. In the question newarray and return for understanding entered, but in fact all the combinations will be used "on the fly" (as generated). It will be expensive to keep in memory if it is an array of 20 elements per 20 repetitions (that is, 20 to 20 degrees of elements). - Samir Routh
  • @SamirRouth, of course, you actually calculate the elements of a Cartesian product of sets, where the sets are n lists ['a', 'b', 'c'] , nobody forces you to keep everything in memory - use, for example, generators ( to the word itertools, too, does not return everything to you in a crowd), look at this answer: stackoverflow.com/a/2419399/2787185 - Pavel Karateev
  • 2
    @SamirRouth, do not keep anything in mind - the product is an iterator. Just take values ​​out of it in the loop, that's all. In this answer, it was wrapped in print (list ()) for example only, so that the sequence could be output to the console. - Sergey Rufanov
  • Yes, stepped, it's an iterator! - Samir Routh

A simple algorithm for generating combinations with repetitions : we will present our set as a set of numbers. Then all possible combinations with repetitions are simply all possible numbers with a given digit capacity on a given set of numbers. The easiest way to get all the possible numbers is to choose a certain "zero" and gradually increase it.

Let's see how we do it in arithmetic. Suppose we have the digits A, B and C and the maximum digit capacity is 2. For the "zero" we take the first number, i.e. A (and taking into account digit capacity: AA)

Then, increasing this number by 1, we first increase the first digit by 1 (i.e., take the next possible digit), and if we overflow (i.e., there are no more digits available), then reset the current digit to "zero "and increment the next digit of the number by 1, etc.

A few examples:

 ноль - AA AA + 1 = AB (т.к. B - следующая цифра после A) AB + 1 = AC (т.к. C - следующая цифра после B) AC + 1 = BA (т.к. после C нет доступных цифр, то обнуляем первый разряд и увеличиваем на 1 второй разряд) и т.д. 

Those. The algorithm for generating our combinations is simple:

  1. We generate the first number of necessary digit capacity (zero)
  2. Increase the number obtained in the previous step by 1
  3. Repeat point 2 until we get an overflow in the last digit (i.e. the next possible number will be already with a bit greater than the specified one)

The algorithm for increasing the number by 1 is also simple:

  1. At the entrance we have possible digits of the number, the number itself and the digit that we are going to increase
  2. Increase current bit by 1
  3. If an overflow has occurred, reset the current discharge and repeat the algorithm for the next discharge.
  4. If an overflow occurred, but the current bit — the last one in the selected capacity — we received the maximum number in the selected capacity

In python code, it looks something like this:

 def increase_number(digits, number, increased_index = 0): number = list(number) total_digits_count = len(digits) number_digits_count = len(number) # было переполнение в последнем доступном разряде if increased_index >= number_digits_count: return False current_digit = number[increased_index] current_digit_index = digits.index(current_digit) # если в текущем разряде переполнение - увеличиваем на 1 следующий разряд if current_digit_index + 1 >= total_digits_count: number[increased_index] = digits[0] return increase_number(digits, number, increased_index + 1) # в текущий разряд пишем следующую по списку цифру number[increased_index] = digits[current_digit_index + 1] return number def product(digits, repeat=3): all_products = [] current_number = [digits[0]] * repeat while True: yield current_number current_number = increase_number(digits, current_number) # было переполнение последнего разряда, больше чисел нет if current_number == False: break myarray=['5', 'O', 'S'] result = product(myarray, 2) for number in result: print (''.join(number)) # Вывод: # 55 # O5 # S5 # 5O # OO # SO # 5S # OS # SS 

I did not bother, so here the numbers are a little upside down. Those. instead of the number 0123, the output will be 3210, but this in no way affects the result.

  • The comment was not included)) - Nick Volynkin
  • @NickVolynkin, not, why? entered (see comments to the question ), only the author did not understand what I wanted to say, I had to paint in more detail) - BOPOH

Recursive call

 def myfunc(myarray, number=3): result=[] if number > 1: for s1 in myarray: tmp = myfunc(myarray, number - 1) for item in tmp: result.append(s1+item) else: result = myarray return result 

    I just solved a similar problem in the topic about clustering (the procedure of combinations), generated combinations without repetitions.

    Adaptation of labor is not (PHP):

     function combi_all($chars, $num){ $combi = [""]; for($n = 0; $n < $num; $n++){ $combi_old = $combi; $combi = []; foreach($combi_old as $item){ for($m = 0; $m < $num; $m++){ $combi[] = $item.$chars[$m]; } } } return $combi; } $combi = combi_all(["a","b","c","d"],3); var_dump($combi); 

    Results:

     array (size = 27)
       0 => string 'aaa' (length = 3)
       1 => string 'aab' (length = 3)
       2 => string 'aac' (length = 3)
       3 => string 'aba' (length = 3)
       4 => string 'abb' (length = 3)
       5 => string 'abc' (length = 3)
       6 => string 'aca' (length = 3)
       7 => string 'acb' (length = 3)
       8 => string 'acc' (length = 3)
       9 => string 'baa' (length = 3)
       10 => string 'bab' (length = 3)
       11 => string 'bac' (length = 3)
       12 => string 'bba' (length = 3)
       13 => string 'bbb' (length = 3)
       14 => string 'bbc' (length = 3)
       15 => string 'bca' (length = 3)
       16 => string 'bcb' (length = 3)
       17 => string 'bcc' (length = 3)
       18 => string 'caa' (length = 3)
       19 => string 'cab' (length = 3)
       20 => string 'cac' (length = 3)
       21 => string 'cba' (length = 3)
       22 => string 'cbb' (length = 3)
       23 => string 'cbc' (length = 3)
       24 => string 'cca' (length = 3)
       25 => string 'ccb' (length = 3)
       26 => string 'ccc' (length = 3)
    

    The essence of the procedure is to get a new array of strings from the old one by writing a letter. Since the dimensions of the arrays do not match, the old one has to be rewritten.

    • Your result is correct for this question, but it is wrong to call it a combination without repeating (this is completely different). For example, in terms of aab and aba combinations, this is the same thing. Your function generates the Cartesian product of the input sequence - jfs
    • @jfs The original program generated the combinations, this one generates the Cartesian product. Difference on one index) - Yuri Negometyanov