JAVA-确定n的所有素数的递归函数

时间:2019-07-01 16:56:22

标签: algorithm recursion

我遇到的问题是,如果我只能将 n 作为函数的参数,我该如何编写一个添加到数组的递归方法。

4 个答案:

答案 0 :(得分:4)

您有两种情况:基本情况和递归情况。对于您的问题,高级逻辑如下所示:

if n is prime
    return array(n)   // return a one-element array
else {
    find a prime divisor, p
    // return an array of p and the factorisation of n/p
    return array(p, FACTORIZATION(n/p) )
}

这会让您动起来吗?您将需要知道如何使用所选语言制作和附加到数组,但这只是实现细节。

答案 1 :(得分:1)

它看起来像:

(618) 619-4120
(618) 795-0790
(618) 619-4120

这是一个幼稚的方法,为了保持简单。或者,您可以为递归函数提供更多(命名)参数,这也将允许传递列表。喜欢:

def factorize(n):
    factors= list()
    found= False
    t= 2
    while t*t <= n and not found:
        while (n % t) == 0:
            # divisible by 2
            factors.append(t)
            found= True
            n//= t
        t+= 1
    if found:
        factors.extend(factorize(n))
    else:
        factors.append(n)
    return factors

factorize(3*5*5*7*7*31*101)
# --> [3, 5, 5, 7, 7, 31, 101]

基本区别是,在这里您可以重用创建的顶层函数的列表。这样,您可以使垃圾收集器的工作量减少一些(尽管在分解函数的情况下这可能并没有多大区别,但在其他情况下,我认为确实可以)。第二点是,您已经测试了一些因素,而不必重新测试它们。这就是为什么我通过t。

当然,这仍然是幼稚的。通过避免每次迭代中的t * t

答案 2 :(得分:1)

工具箱中的另一种方法是不返回数组,而是返回链接列表。那是一种数据结构,其中每个数据都链接到下一个,链接到下一个,依此类推。因子分解并没有真正显示出它的力量,但是无论如何,这里仍然是:

def factorize(n, start=2):
    i = start
    while i < n:
        if n % i == 0:
            return [i, factorize(n//i, i)]
        elif n < i*i:
            break
        i = i + 1
    if 1 < i:
        return [n, None]
    else:
        return None

print(factorize(3*5*5*7*7*31*101)) # [3, [5, [5, [7, [7, [31, [101, None]]]]]]]

此方法的优势在于它不会修改返回的数据结构。因此,如果您正在做类似通过图形搜索最佳路径的操作,则可以跟踪多个后续动作而不会发生冲突。在修改动态编程算法以实际找到最佳解决方案,而不是报告其优缺点时,我发现这特别有用。

一个难题是您最终只能使用嵌套的数据结构。但您始终可以按以下步骤进行展平:

def flatten_linked_list (ll):
    answer = []
    while ll is not None:
        answer.append(ll[0])
        ll = ll[1]
    return answer

# prints [3, 5, 5, 7, 7, 31, 101]
print(flatten_linked_list( factorize(3*5*5*7*7*31*101) ))

答案 3 :(得分:0)

这是两种递归方法。第一个具有一个参数,并使用while循环查找除数,然后使用除法和征服来递归查询该除法两个结果中每个因子。 (此方法更多的是练习,因为我们可以轻松地更有效地执行此操作。)第二个方法依赖于第二个参数作为当前素数的指针,从而可以更有效地进行直接枚举。

JavaScript代码:

function f(n){
  let a = ~~Math.sqrt(n)
  while (n % a)
    a--
  if (a < 2)
    return n == 1 ? [] : [n]
  let b = n / a 
  let [fa, fb] = [f(a), f(b)]
  return (fa.length > 1 ? fa : [a]).concat(
    fb.length > 1 ? fb : [b])
}

function g(n, d=2){
  if (n % d && d*d < n)
    return g(n, d == 2 ? 3 : d + 2)
  else if (d*d <= n)
    return [d].concat(g(n / d, d))
  return n == 1 ? [] : [n]
}

console.log(f(567))
console.log(g(12345))