2012-04-28 90 views
1

我被要求編寫一個程序來計算n和m度的兩個多項式的相加。我做了兩個字典(一個用於第一個多項式,另一個用於另一個多項式),因爲每個字典都有作爲值和度數的係數作爲關鍵字,所以我可以檢查兩個字典中的關鍵字是否相同,然後我可以將他們值。但我不知道爲什麼我總是得到一個錯誤。到目前爲止我的代碼是:使用python求和兩個多項式的問題

class poly: 
    def __init__(self, L=[], D=[]): 
     self.coef=L 
     self.deg=D 

    def __add__(self,L2): 
     if len(self.coef)>len(self.deg): 
      dec=dict(zip(self.deg,self.coef)) 
      dec[0]=self.coef[-1] 

     else: 
      dec=dict(zip(self.deg,self.coef)) 

     Dec1=dec 

     if len(L2.coef)>len(L2.deg): 
      dec=dict(zip(L2.deg,L2.coef)) 
      dec[0]=L2.coef[-1] 
     else: 
      dec=dict(zip(L2.deg,L2.coef)) 

     Dec2=dec 
     p=[] 

     if len(Dec2)>len(Dec1): 
      for i in Dec2: 
      if i in Dec1: 
       s=Dec1[i]+Dec2[i] 
       p=p+[s] 
      else: 
       p=p+p[Dec2[i]] 

      for x in Dec1: 
      if x in Dec2: 
       p=p 
      else: 
       p=p+[dec1[x]] 
     return(poly(p)) 

     if len(Dec2)<len(Dec1): 
     for x in Dec1: 
      if x in Dec2: 
       g=Dec1[x] 
       p=p+[g] 
      else: 
       p=p+[Dec1[x]] 

     for m in Dec2: 
      if m in Dec1: 
       p=p 
      else: 
       p=p+[Dec2[m]] 
     return (poly(p)) 

此代碼不爲我所有的例子,如

>>> p=poly([2,4,7,34],[6,4,2]) 
>>> p1=poly([6,3,7,2,8],[8,4,2,1]) 
>>> p2=p+p1 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    p2=p+p1 
    File "poly.py", line 31, in __add__ 
    p=p+p[Dec2[i]] 
IndexError: list index out of range 
>>> #The numbers in the first list is the coefficients and the second list is for degrees 

這不起作用工作!但是,當我在不使用類方法的情況下完成添加時它就起作用了。我是一名初學者,我盡力解決這個問題。

另一個問題是如何寫我的代碼def str?我真的不知道我應該在一開始寫什麼。我很抱歉,但我是編程新手,需要一個簡單的代碼,比如我的代碼。

+0

不是說它導致你的特定問題,但要小心使用'[]'作爲默認值在'__init__'(或其他地方,就此而言):http://stackoverflow.com/questions/1132941/least-astonishment-in-python-the-mutable-default-argument – lvc 2012-04-28 23:04:52

+2

此外,它可能會更有意義將多項式存儲爲係數的單個列表,以便'x^3 + 2'具有係數'[1,0,2]'。 – lvc 2012-04-28 23:18:25

+0

我都做過了!首先我的init沒有[],但它不起作用。所以我會騎它。對不起,沒有提到我期待用戶輸入一個字符串! – user1354396 2012-04-28 23:45:36

回答

2
  1. 通過共同的約定,類名應該大寫(即Poly
  2. 你有__add__做了很多的東西,沒有任何與添加。這應該是一個警告標誌。
  3. 很多__add__的工作都在關注數據存儲格式。也許你應該使用更好的存儲格式,不需要太多重新洗牌?
  4. __add__中有很多重複的代碼塊;這通常是代碼應該被分解到子程序中的一個指示器。
  5. 您有此對象(self)更改了另一個對象(L2)的內部細節 - 另一種難聞的氣味。

如果移動從__add__自我(if len(self.coef) > len(self.deg) ...)的標準化代碼爲__init__,這將解決#2,#3,#4的一半,#5於一身去(你不再需要「做到「L2,它會」做「本身)。

如果您意識到這與len(Dec1) > len(Dec2)無關,那麼您可以擺脫另一個冗餘代碼塊。這修復了#4的另一半。突然__add__從48行代碼縮減到12,並且變得更容易理解和調試。

爲了比較的緣故

from itertools import izip_longest, chain, product 
from collections import defaultdict 

class Poly(object): 
    def __init__(self, coeff=None, power=None): 
     if coeff is None: coeff = [] 
     if power is None: power = [] 
     self.d = defaultdict(int) 
     for c,p in izip_longest(coeff, power, fillvalue=0): 
      if c != 0: 
       self.d[p] += c 

    @classmethod 
    def fromDict(cls, d): 
     return cls(d.itervalues(), d.iterkeys()) 

    @property 
    def degree(self): 
     return max(p for p,c in self.d.iteritems() if c != 0) 

    def __add__(self, poly): 
     return Poly(
      chain(self.d.itervalues(), poly.d.itervalues()), 
      chain(self.d.iterkeys(), poly.d.iterkeys()) 
     ) 

    def __mul__(self, poly): 
     return Poly(
      (cs*cp for cs,cp in product(self.d.itervalues(), poly.d.itervalues())), 
      (ps+pp for ps,pp in product(self.d.iterkeys(), poly.d.iterkeys())) 
     ) 

    def __call__(self, x): 
     return sum(c*x**p for p,c in self.d.iteritems()) 

    def __str__(self): 
     clauses = sorted(((p,c) for p,c in self.d.iteritems() if c != 0), reverse=True) 
     return " + ".join("{}x^{}".format(c,p) for p,c in clauses) or "0" 

需要注意的是:

  1. 每種方法很短,不相關的東西就應該完成的唯一的東西。
  2. 我故意寫了__init__是非常容錯的;它會高興地接受給定功率的多個係數並對它們進行求和。這使我大大簡化了__add____mul__,基本上只是將所有結果子句放在一個新的Poly中,並讓它再次清理它們。
  3. 我已經包含了一個最小實現__str__,這將導致像5x^2 + -2x^1 + -5x^0這樣的中等難看的輸出。您可能希望對負係數和1或0的冪加上特殊處理,以使其產生5x^2 - 2x - 5
  4. 這是爲了理解,而不是抄襲;不要將它提交給你的老師,他將永遠不會在一百萬年內相信你真的寫了它;-)