我强调不使用数组。是否有任何数学推导?
答案 0 :(得分:0)
您可以使用"Gosper's hack"操纵二进制数字,但是您可以根据您可以生成/表示这种方式的组合大小来限制机器的字长。
// 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
}
使用第一个x
初始化k
- 组合即x = (1L<<k) - 1L
(k
one
已设置)
这是做什么的:
one
s 对于组合的更多数论 - 表示,请参阅Combinatorial number system表示组合为整数,即从组合到整数的双射(如果要在不使用数组的情况下严格使用算术)明确地)
答案 1 :(得分:0)
十进制整数本质上是一个数字数组。一些简单的数学运算将允许对整数中的那些数字进行索引,就像任何其他数组一样。
以下python示例代码将通过利用这一事实完全符合您的要求:
#!/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)
由于没有指定是否允许重复数字,我写这个假设它们会。如果不是这样的话,可以简化一下。