1

n度とm度の2つの多項式の加算を計算するプログラムを作成するように依頼されました。2つの辞書(1つは最初の多項式用、もう1つは他の多項式用)を作成しました。それぞれに値としての係数とキーとしての度があり、両方の辞書のキーが同一であるかどうかを確認できるため、それらを合計できます。値。しかし、なぜいつもエラーが発生するのかわかりません。これまでの私のコードは次のとおりです。

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

これは機能しません!しかし、クラスメソッドを使用せずに追加を行った場合は機能しました。私は初心者で、問題を解決するために最善を尽くしました。

別の質問は、私のコードのdefstrをどのように書くかです。最初は何を書けばいいのかわからない。申し訳ありませんが、プログラミングは初めてで、私のような簡単なコードが必要です。

4

1 に答える 1

3
  1. 一般的な慣例により、クラス名は大文字にする必要があります(つまりPoly
  2. __add__追加とは関係のないことをたくさんやっています。これは警告サインであるはずです。
  3. の多く__add__の作業は、データストレージ形式をいじくり回しています。たぶん、それほど多くの再シャッフルを必要としない、より良いストレージフォーマットを使用する必要がありますか?
  4. __add__;にはコードの繰り返しチャンクがたくさんあります。これは通常、コードをサブルーチンに分解する必要があることを示します。
  5. このオブジェクト(self)が別のオブジェクト()の内部の詳細に変更を加えていますL2-別の悪臭。

self(if len(self.coef) > len(self.deg) ...)の正規化コードをから__add__に移動する__init__と、#2、#3、#4の半分、および#5がすべて一度に解決されます(L2を「実行」する必要がなくなり、「実行」されます。 to "自体)。

それがほとんど無関係であるかどうかに気付いた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. これは、盗用ではなく、理解を目的としています。それをそのままあなたの先生に提出しないでください、彼はあなたが実際にそれを書いたと百万年以内に決して信じません;-)
于 2012-04-29T16:06:52.017 に答える