1

我被要求编写一个程序来计算 n 和 m 度的两个多项式的相加。我制作了两个字典(一个用于第一个多项式,另一个用于另一个多项式),因为每个字典都将系数作为值,将度数作为键,以便我可以检查两个字典中的键是否相同,然后我可以将它们相加价值观。但我不知道为什么我总是得到一个错误。到目前为止,我的代码是:

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?一开始我真的不知道我应该写什么。对不起,伙计们,但我是编程新手,我需要一个简单的代码,比如我的。

4

1 回答 1

3
  1. 按照惯例,类名应大写(即Poly
  2. __add__做了很多与添加无关的事情。这应该是一个警告信号。
  3. 很多__add__工作都在处理数据存储格式。也许您应该使用一种更好的存储格式,一种不需要太多重新洗牌的存储格式?
  4. 你有很多重复的代码块__add__;这通常表明代码应该被分解到子程序中。
  5. 你让这个对象 ( self) 对另一个对象 ( ) 的内部细节进行了更改L2- 另一种难闻的气味。

如果您将 self ( if len(self.coef) > len(self.deg) ...) 的规范化代码从__add__into__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__and __mul__,基本上只是将所有生成的子句扔到一个新的 Poly 并让它再次清理它们。
  3. 我已经包含了 . 的最小实现__str__,这将导致像5x^2 + -2x^1 + -5x^0. 您可能希望为负系数和 1 或 0 的幂添加特殊处理,以使其生成5x^2 - 2x - 5
  4. 这是为了理解,不是抄袭;不要按原样提交给你的老师,一百万年后他永远不会相信你真的写了它;-)
于 2012-04-29T16:06:52.017 回答