2012-11-26 40 views
0

我有一個程序,可以找到任何數字的主要因素n。運行它時,由於索引超出限制(其中限制爲sqrt(n)),所以出現索引錯誤。我不確定它爲什麼超出限制。誰能提供任何見解?IndexError:列表索引超出範圍---主要因素髮生器

我的代碼適用於大多數的數字:

>>> pFactors(250000) 
[2, 2, 2, 2, 5, 5, 5, 5, 5, 5] 
>>> pFactors(123456789) 
[3, 3, 3607, 3803] 
>>> pFactors(123456) 

Traceback (most recent call last): 
    File "<pyshell#2>", line 1, in <module> 
    pFactors(123456) 
    File "D:\my_stuff\Google Drive\Modules\factors.py", line 50, in pFactors 
    check = primes[index] 
IndexError: list index out of range 
>>> pFactors(123455) 

Traceback (most recent call last): 
    File "<pyshell#3>", line 1, in <module> 
    pFactors(123455) 
    File "D:\my_stuff\Google Drive\Modules\factors.py", line 50, in pFactors 
    check = primes[index] 
IndexError: list index out of range 

奇怪的是,到目前爲止,我只發現它無法對數字123400-1234

在這裏工作是我的代碼:

def pFactors(n): 
    import primes as p 
    from math import sqrt 
    global pFact 
    pFact, primes, limit, check, num, index = [], [], int(round(sqrt(n))), 2, n, 0 
    if type(n) != int and type(n) != long: 
     raise TypeError("Argument <n> can only be <type 'int'> or <type 'long'>") 
    else: 
     if p.isPrime(n): 
     pFact = [1, n] 
     else: 
     p.prevPrimes(limit) 
     for i in p.primes_dict: 
      if p.primes_dict[i]: 
       primes.append(i) 
     while check <= limit: 
      if check in primes and (num%check==0): 
       pFact.append(check) 
       num = num/check 
       if num in primes: 
        pFact.append(num) 
        break 
      else: 
       check = primes[index] 
       index += 1 
     return pFact 

我相信問題不在於primes.py,因爲這工作正常。如果任何人有解決方法,請告訴我。謝謝!

+1

爲什麼在地球上導入功能內的模塊?也請。如果你想檢查一個對象是否是給定的類型,我們使用'isinstance'(例如'if isinstance(n,(int,long))'),或者甚至更好的情況是你的情況只適用於'n = int(n)如果它不能從'n'創建一個整數,它將會引發'TypeError'。 作爲一個方面說明,我相信只是迭代奇數到'sqrt(n)'會比首先查找素數更快(因爲您必須已經遍歷它們來標記素數......)。 – Bakuriu

+0

我最終做的是檢查+ = 1,並刪除sqrt(n)的整個素數。這也大大加快了速度(這個數字快了50倍:來自Project Euler的600851475143)。 –

回答

2

您希望使用平方根的天花板作爲列表長度,但您只是將其舍入,這意味着它有時會舍入。

更好的是,使用基於int的平方根函數而不是math.sqrt,這樣它就可以用於雙倍數的太大的數字。

另外,global pFact是可怕的設計。根本沒有理由使用全局列表,除非你正在嘗試調試它或者什麼的,即使這樣也是有問題的。

最後,我不確定爲什麼你想返回1作爲素數的一個因子。這是違背慣例,與你的複合材料案件不符,但我想你可以這樣做,如果你真的想。

無論如何,這裏有一個簡單的方法來做分解。首先你可以考慮優化它。

def factor(x): 
    n = int(x) 
    if n < 1: 
     raise ValueError("Argument must be positive") 

    factors = [] 
    d = 2 

    while d*d <= n: 
     while n%d == 0: 
      n = n // d 
      factors.append(d) 
     d += 1 
    if n>1: 
     factors.append(n) 
    return factors 
相關問題