在这篇文章中,我们将讨论打印一个给定数字的每一个因子组合的算法(所有因子化),我们已经探讨了递归和部分迭代的方法。
我们会看到什么?
问题陈述
我们必须设计并实现一种算法,打印出给定数字的所有唯一的因子组合。例如,假设给定的数字是16,那么输出结果应该是这样的
2 2 2 2 2 2
4
28
44
有许多方法可以解决打印一个数字的因子组合的问题。下面讨论其中的一些方法:
使用回溯概念的迭代方法
解决这个问题的基本思路是将迭代的数字乘以一个乘积变量,这个乘积变量最初为1,并在每一步检查乘积是否小于、等于或超过这个数字。
如果乘积小于输入的数字,我们就用下一个数字乘以乘积,然后再检查。
如果乘积等于数字,我们将输出乘积的因子组合(正在迭代的数字,乘积使其等于输入的数字),然后从乘积中删除或除以最后一个乘积的数字(即我们正在使用回溯的概念),并通过将下一个数字乘积来测试。
如果积超过了这个数字,我们就重复同样的回溯过程,直到积等于或小于输入的数字。
我们需要知道哪些因子的组合形成了乘积,为此,我们必须将每个被乘的数字存入列表或堆栈中。当我们从乘积中删除任何数字时,我们也必须从列表或堆栈中弹出或删除它。
在Python中的实现
factors = []
num = int(input("Enter a number: "))
def factorCombinations(n, product):
global l
# The base condition for recursive call
if product == num:
print(factors)
return
for i in range(n, int(num/2)+1):
# Returning to the last recursive call, if product exceeds the num.
if product*i > num:
return
# Multiplying the number to the product
product *= i
factors.append(i)
# Recursively calling the function with same number
factorCombinations(i, product)
# Using the backtracking approach
factors.pop()
product //= i
factorCombinations(2, 1)
在findCombinations(n, product)中,函数声明n是下一个要乘以乘积变量的数字,即第二个参数。
在每个递归调用或步骤中,产品值被更新并与输入的数字num进行比较。
如果乘积变量等于num变量,我们就打印列表中的因子组合,并返回或回溯到最后一次递归调用,从乘积中删除最后一个被乘的因子,并用下一个迭代的i值测试。
我们对相同的i值重复递归调用,即findCombinations(i, product),因为组合可能包括重复的因子,例如,16=[2, 2, 2, 2]。
递归方法
递归方法从3个参数开始:数字,在这个方法中作为乘积,类似于迭代方法,在每个递归步骤中存储当前的乘积,存储因子组合的字符串(printFactors),以及作为原始数字输入的父值(parentVal)。
在递归块内部,我们定义了一个新的变量newVal,最初给出的是parentVal(父值)的值。在number-1到2的范围内进行迭代,每次迭代时递减器i会减少1。
然后我们检查这个数字是否能被i整除,如果能被整除,则检查三个条件。条件一是如果newVal大于i的值,我们将newVal的值改为i。条件二是如果数字除以i(number/i)小于或等于parentVal,并且i小于或等于parentVal,数字除以i(number/i)小于或等于i,则打印parentFactors字符串,将其与变量i、装饰用空格和数字除以i的整数值连接起来。检查第三个条件,即如果i小于parentVal,我们通过调用printFactors函数来执行递归调用,参数为数字/i的整数值、parentFactors的连接字符串、i和一个空格字符,以及newVal作为第三个参数。
这种递归方法需要3个输入,即一个字符串,用于在while循环中携带i的当前值,以进行后续的还原,还有一个临时的整数,以知道何时不打印重复的反转,即8*3和3*8。
在Python中的实现
def printFactors(number, parentFactors, parentVal):
''' Initialising the variable newVal with value parentVal '''
newVal = parentVal
''' Initialising the iterable variable i iterating through number-1 to 2 '''
i = number-1
while (i>=2):
''' Checking if the number is divisible by i '''
if (number % i == 0):
''' Case when newVal is greater than i '''
if (newVal > i) :
''' Replacing the current value of newVal with i '''
newVal = i
''' Case when number/i is less than or equal to
parentVal, i is less than or equal to parentVal
and number/i is less than or equal to i '''
if (number / i <= parentVal and i <= parentVal and number / i <= i):
''' Printing the string of the desired output,
which is a combination of the factors
giving product equal to the parentVal '''
print(str(parentFactors)+str(i)+" "+str(int(number/i)))
''' Setting the newVal variable, the integer value of number/i '''
newVal = int(number/i)
''' Case when i is less than or equal to parentVal '''
if (i <= parentVal):
''' Recursively calling the printFactors to
print the next combination of factors '''
printFactors(int(number/i), str(parentFactors) + str(i) + " ", newVal)
''' Decrementing the i variable '''
i-=1
printFactors(16,"",16)
结论
在OpenGenus的这篇文章中,我们讨论了如何解决打印给定数字的因子的所有唯一组合的问题。我们讨论了使用回溯概念的递归和迭代的方法。