Python:将数字表示为素数之和

时间:2017-09-12 12:41:33

标签: python

我需要编写一个算法,它可以将数字表示为素数的最小和:

例如: 8 - > [2,2,2,2],[3,5],[2,3,3] 我需要得到min = this => 2

我已编写代码,但需要花费大量时间,因为它包含递归。如何更改它以改善时间?

import sys

x = int(sys.stdin.readline())

def is_prime(n):
    for i in range(2, n):
        if n % i == 0:
            return False
    return True

def decomposition(x):
    result = []
    for a in range(2, int(x/2 + 1)):
        if x-a >= 2:
            b = x - a
            pair = [a, b]
            result.append(pair)
    return result

def f(elem):
    list_of_mins = []
    if is_prime(elem) == True:
        return 1
    else:
        pairs = decomposition(elem)
        print(pairs)
        for a,b in pairs:
            list_of_mins.append(f(a)+f(b))
        return min(list_of_mins)


if str(int(x)).isdigit() and 2 <= int(x) <= 10 ** 9:
    sum = []import sys

x = int(sys.stdin.readline())

def is_prime(n):
    for i in range(2, n):
        if n % i == 0:
            return False
    return True

def decomposition(x):
    result = []
    for a in range(2, int(x/2 + 1)):
        if x-a >= 2:
            b = x - a
            pair = [a, b]
            result.append(pair)
    return result

def f(elem):
    list_of_mins = []
    if is_prime(elem) == True:
        return 1
    else:
        pairs = decomposition(elem)
        print(pairs)
        for a,b in pairs:
            list_of_mins.append(f(a)+f(b))
        return min(list_of_mins)


if str(int(x)).isdigit() and 2 <= int(x) <= 10 ** 9:
    sum = []
    print(f(x))

2 个答案:

答案 0 :(得分:0)

你的is_prime函数只需要测试除数为pow(n,0.5)+1的除数。这意味着您的代码将是:

def is_prime(n):
    for i in range(2, int(pow(n, 0.5)+1):
        if n % i == 0:
            return False
    return True

这可以显着提高您的算法速度。

答案 1 :(得分:0)

这是一个可能的解决方案:

import math


class Foo():

    def __init__(self, n):
        self.n = n
        self.primes = self.prime_sieve(n)

    def prime_sieve(self, sieve_size):
        sieve = [True] * sieve_size
        sieve[0] = False
        sieve[1] = False

        for i in range(2, int(math.sqrt(sieve_size)) + 1):
            pointer = i * 2
            while pointer < sieve_size:
                sieve[pointer] = False
                pointer += i

        primes = []
        for i in range(sieve_size):
            if sieve[i] == True:
                primes.append(i)

        return primes

    def sum_to_n(self, n, size, limit=None):
        if size == 1:
            yield [n]
            return
        if limit is None:
            limit = n
        start = (n + size - 1) // size
        stop = min(limit, n - size + 1) + 1
        for i in range(start, stop):
            for tail in self.sum_to_n(n - i, size - 1, i):
                yield [i] + tail

    def possible_sums(self):
        for i in range(2, self.n):
            result = list(self.sum_to_n(self.n, i))
            result = (
                [v for v in result if all([(p in self.primes) for p in v])])
            if result:
                yield result

    def result(self):
        for i in self.possible_sums():
            return i
        raise Exception("Not available result!")

if __name__ == '__main__':
    obj = Foo(8)
    print(list(obj.possible_sums()))
    print('-' * 80)
    try:
        v = obj.result()
        print("{} , length = {}".format(v[0], len(v[0])))
    except Exception as e:
        print(e)

结果:

[[[5, 3]], [[3, 3, 2]], [[2, 2, 2, 2]]]
--------------------------------------------------------------------------------
[5, 3] , length = 2