查找给定复发的值

时间:2019-07-30 03:49:30

标签: python algorithm

给定递归为f0 = 0,f1 = 1,f2 = 2,fk = fk-1 + fk-3,n和ki。

我需要编写一个程序,在给定循环的ki位置上对n个数字进行计数

Example1 in

4
0 1 2 3

Example1 out

0 1 2 2

Example2 in

3
4 5 4

Example2 out

3 5 3

这是我的想法

def get_numbers():
    with open('input.txt','r') as file_in:
        n = int(file_in.readline()[:-1])
        input_list = map(int,file_in.readline().split(' '))
        print(foo(n,input_list))

def find_number(n):
    a, b, c = 0, 1, 2
    for _ in range(n+1):
        yield a
        a, b, c = b, c, a + c

def foo(n,input_values):
    result = str()
    for elem in (list(find_number(i))[-1] for i in input_values):
        result += str(elem) + " "
    return result[:-1]

get_numbers()

我试图使用生成器来加快我的代码的速度,但是却不知道如何使用更少的内存。

所以我试图使我的代码消耗更少的内存,或者只是寻找另一个(更简单的)解决方案。

4 个答案:

答案 0 :(得分:1)

完成了一些工作,因此很难解释我所做的全部。但是,我在您的原始代码中没有注意到的是函数foofind_number的关系;同样,函数foo正在执行许多字符串操作,这很昂贵。 我能够提出简化的代码,并且可以使用您提供的两个示例输入。但是,我无法对此进行进一步的测试。希望它对您有用。

# unchanged from yours.
def get_numbers():
    with open('input.txt', 'r') as file_in:
        n = int(file_in.readline()[:-1])
        input_list = map(int, file_in.readline().split(' '))
        print(foo(n, input_list))


# I removed the generator. I let the loop scramble
# the numbers, but only return the one bit that is
# relevant inside `foo`, which gets greatly simplified
def find_number(n):
    a, b, c = 0, 1, 2
    for _ in range(n):
        a, b, c = b, c, a + c
    return a

# With the change in `find_numbers` this gets much simpler
# which should help with speed and memory consumption  
def foo(n, input_values):
    return [find_number(i) for i in input_values]

答案 1 :(得分:0)

我不理解您的inputm输出或'n',但这是我的主意:如果定义了f0,f1,f2,则您的函数必须执行某些操作,只要k <2为k > 2和fk k。

我将f0称为f(0),所以:

def f(k):
    if (k < 2): return k
    return f(k-1) + f(k-3)

您可以这样做:

>>> f(4)

答案 2 :(得分:0)

获取更快但更重的代码:

k = int(input('Enter a value for k: '))

f0 = 0
f1 = 1
f2 = 2

def calc(k):
    try:
        return eval(f'f{k}')
    except:
        kLessOne = k-1
        kLessThree = k-3
        try:
            eval(f'f{kLessOne}')
        except:
            globals()[f'f{kLessOne}'] = calc(k-1)

        try:
            eval(f'f{kLessThree}')
        except:
            globals()[f'f{kLessThree}'] = calc(k-3)

        return eval(f'f{kLessOne} + f{kLessThree}')

print(calc(k))

此代码在运行时实例化全局变量,我不建议您这样做。

答案 3 :(得分:0)

您可以利用functools.lru_cachedoc)来缓存递归函数的结果:

from functools import lru_cache

@lru_cache(maxsize=None)
def f(k):
    if k < 3:
        return k
    return f(k-1) + f(k-3)

def f2(k):
    if k < 3:
        return k
    return f2(k-1) + f2(k-3)

from timeit import timeit

t1 = timeit(lambda: f(45), number=1)
t2 = timeit(lambda: f2(45), number=1)

print(t1)
print(t2)

在我的计算机上打印:

2.5337999886687612e-05
2.7258617150000646

对于k = 50,差异更大:

t1 = timeit(lambda: f(50), number=1)
t2 = timeit(lambda: f2(50), number=1)

打印:

2.6389000140625285e-05
18.368431184999736