簡體   English   中英

這段代碼效率太低,如何提高內存和執行效率?

[英]This code is too inefficient, how can I increase memory and execution efficiency?

我正在嘗試完成以下挑戰: https//app.codesignal.com/challenge/ZGBMLJXrFfomwYiPs 我編寫的代碼似乎有效,但是它的效率很低,以至於它無法通過測試(執行時間太長而使用的內存太多)。 我有什么方法可以提高效率嗎? 我很擅長構建高效的腳本。 有人提到“map()”可以代替“for i in range(1,n)”。 感謝Xero Smith和其他人提出的優化建議:

from functools import reduce
from operator import mul
from itertools import combinations

# Starting from the maximum, we can divide our bag combinations to see the total number of integer factors                                                                                    

def prime_factors(n):
    p = 2
    dct = {}
    while n != 1:
        if n % p:
            p += 1
        else:
            dct[p] = dct.get(p, 0) + 1
            n = n//p
    return dct


def number_of_factors(n):
    return reduce(mul, (i+1 for i in prime_factors(n).values()), 1)


def kinderLevon(bags):
    candies = list()
    for x in (combinations(bags, i) for i in range(1, len(bags)+1)):
        for j in x:
            candies.append(sum(j))
    satisfied_kids = [number_of_factors(i) for i in candies]
    return candies[satisfied_kids.index(max(satisfied_kids))]

任何幫助將不勝感激。

謝謝,

亞倫

根據我的評論,我已經可以確定內存和復雜性的改進。 在您的factors功能中,因為您只需要多個因子,您只能計算它們而不是存儲它們。

def factors(n):
    k = 2
    for i in range(2, n//2 +1):
        if n % i == 0:
            k += 1
    return k

編輯 :正如評論中建議的那樣,早些時候停止計數器。

這實際上減少了大數字的時間復雜度,但對於較小的數字則不然。

這比使用列表推導(仍然分配內存)的改進要好得多

而且,兩次分配組合列表毫無意義。 你在做

x = list(combinations(bags, i));
for j in list(x):
    ...

第一行將元組(由combinations返回)轉換為列表,從而復制數據。 第二行list(x)重新分配列表的副本,占用更多內存! 你真的應該寫:

for j in combination(bags, i):
    ...

作為語法問題,請不要使用分號; 在Python中!

使用列表推導。 因子函數可以像這樣轉換:

def factors(n):
    return len([i for i in range(1, n + 1) if n % i == 0])

首先,組合是可迭代的。 這意味着您不必在迭代它們之前將它們轉換為列表; 事實上,這樣做非常低效。

接下來可以顯着改善的是你的factors程序。 目前它是線性的。 我們可以做得更好。 我們可以通過以下算法得到整數N的因子數:

  1. 得到N的素因子分解,使得N = p1^n1 * p2^n2 * ...
  2. N的因子數是(1+n1) * (1+n2) * ...

有關詳細信息,請參閱https://www.wikihow.com/Find-How-Many-Factors-Are-in-a-Number

還有一點,你當前的解決方案有很多未使用的變量和計算。 擺脫它們。

有了這些,我們得到以下應該工作:

from functools import reduce
from operator import mul
from itertools import combinations

# Starting from the maximum, we can divide our bag combinations to see the total number of integer factors                                                                                    

def prime_factors(n):
    p = 2
    dct = {}
    while n != 1:
        if n % p:
            p += 1
        else:
            dct[p] = dct.get(p, 0) + 1
            n = n//p
    return dct


def number_of_factors(n):
    return reduce(mul, (i+1 for i in prime_factors(n).values()), 1)


def kinderLevon(bags):
    candies = list()
    for x in (combinations(bags, i) for i in range(1, len(bags)+1)):
        for j in x:
            candies.append(sum(j))
    satisfied_kids = [number_of_factors(i) for i in candies]
    return candies[satisfied_kids.index(max(satisfied_kids))]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM