How to print all the possible combinations of a N digit number without using arrays?

自作多情 提交于 2019-12-08 14:06:49

问题


I'm stressing on the point of without using an array. Is there any mathematics derivation for this?


回答1:


You can use "Gosper's hack" manipulating binary numbers but you are limited by the word length of the machine on the size of combinations you can generate/represent this way.

// find next k-combination
bool next_combination(unsigned long& x) // assume x has form x'01^a10^b in binary
{
  unsigned long u = x & -x; // extract rightmost bit 1; u =  0'00^a10^b
  unsigned long v = u + x; // set last non-trailing bit 0, and clear to the right; v=x'10^a00^b
  if (v==0) // then overflow in v, or x==0
    return false; // signal that next k-combination cannot be represented
  x = v +(((v^x)/u)>>2); // v^x = 0'11^a10^b, (v^x)/u = 0'0^b1^{a+2}, and x ← x'100^b1^a
  return true; // successful completion
}

Initialise x with the 1st k-combination i.e x = (1L<<k) - 1L (k ones are set)

What this does:

  1. Uses two different representations of a combination a) as a choice and b) as a binary number
  2. Uses gray coding (or minimal change coding) to move from one combination (binary number) to the next combination (binary number), maintaining same number of ones in the binary representation
  3. Eventually all combinations are generated this way (but not lexicographicaly)

For a more number-theoretic representation of a combination see Combinatorial number system which represents combinations as integers, i.e a bijection from combinations to integers (if you want to use strictly artithmetic without using arrays explicitly)




回答2:


An decimal integer is essentially an array of digits. Some simple math will allow the indexing of those digits in the integer just like any other array.

The following python sample code will do exactly what you wanted by exploiting this fact:

#!/usr/bin/python3

def getNumDigits(number):
    if number == 0:
        digits = 1
    else:
        digits = 0
        while number > 0:
            digits += 1
            number //= 10
    return digits

def getDigitAtPosition(position, number):
    return (number // (10**position)) % 10

def swapDigits(number, position_one, position_two):
    digit_one = getDigitAtPosition(position_one, number)
    digit_two = getDigitAtPosition(position_two, number)
    difference = digit_one - digit_two
    return number + (difference * 10**position_two) - (difference * 10**position_one)

def sortNumber(number, num_digits=None):
    if num_digits is None:
        num_digits = getNumDigits(number)
    for i in range(num_digits-1):
        for j in range(i+1, num_digits):
            if getDigitAtPosition(j, number) < getDigitAtPosition(i, number):
                number = swapDigits(number, i, j)
    return number

def isDigitInNumber(digit, number):
    for i in range(getNumDigits(number)):
        if getDigitAtPosition(i, number) == digit:
            return True
    return False

def printCombinations_sorted(number, prepend, num_digits):
    if num_digits == 1:
        print(number + (prepend * (10**num_digits)))
    else:
        lead_position = num_digits-1
        lead_digit = getDigitAtPosition(lead_position, number)
        digits_swapped = lead_digit
        printCombinations_sorted(number % 10**(lead_position), (prepend*10) + lead_digit, num_digits-1)
        for i in range(num_digits-1):
            sub_number = swapDigits(number, num_digits-1, num_digits-2-i)
            sub_lead_digit = getDigitAtPosition(lead_position, sub_number)
            if not isDigitInNumber(sub_lead_digit, digits_swapped):
                digits_swapped = digits_swapped*10 + sub_lead_digit
                printCombinations_sorted(sub_number % 10**(lead_position), (prepend*10) + sub_lead_digit, num_digits-1)

def printCombinations(number):
    num_digits = getNumDigits(number)
    number = sortNumber(number, num_digits)
    printCombinations_sorted(number, 0, num_digits)

if __name__ == "__main__":
    number = 101010
    printCombinations(number)

Since it was not specified if repeated digits would be allowed, I wrote this with the assumption that they would. It could be simplified quite a bit if that is not the case.



来源:https://stackoverflow.com/questions/30684360/how-to-print-all-the-possible-combinations-of-a-n-digit-number-without-using-arr

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!