Python 使用单链表实现多项式 (Polynomial)

#!/usr/bin/python 
# -*- coding: utf-8 -*-


'''
Created on 2015-1-26
@author: beyondzhou
@name: linkPolynomail.py
'''


# Implementation of the Polynomial ADT using a sorted linked list
class linkPolynomial:
    # Create a new polynomial object
    def __init__(self, degree=None, coefficient=None):
        if degree is None:
            self._polyHead = None
        else:
            self._polyHead = _PolyTermNode(degree, coefficient)
        self._polyTail = self._polyHead


    # Returns the degree of the polynomial
    def degree(self):
        if self._polyHead is None:
            return -1
        else:
            return self._polyHead.degree


    # Returns the coefficient for the term of the given degree
    def __getitem__(self, degree):
        assert self.degree() >= 0, \
               "Operation not permitted on an empty polynomial."
        curNode = self._polyHead
        while curNode is not None and curNode.degree >= degree:
            curNode = curNode.next


        if curNode is None or curNode.degree != degree:
            return 0.0
        else:
            return curNode.degree


    # Evaluate the polynomial at the given scalar value
    def evaluate(self, scalar):
        assert self.degree() >= 0, \
            "Only non-empty polynomials can be evaluated."
        result = 0.0
        curNode = self._polyHead
        while curNode is not None:
            result += curNode.coefficient * (scalar ** curNode.degree)
            curNode = curNode.next
        return result


    # Polynomial addition: newPoly = self + rhsPoly
    def __add__(self, rhsPoly):
        assert self.degree() >= 0 and rhsPoly.degree() >= 0, \
            "Addition only allowed on non-empty polynomials."
        newPoly = linkPolynomial()
        nodeA = self._termList
        nodeB = rhsPoly._termList


        # Add corresponding terms until one list is empty
        while nodeA is not None and nodeB is not None:
            if nodeA.degree > nodeB .degree:
                degree  = nodeA.degree
                value = nodeA.coefficient
                nodeA = nodeA.next
            elif nodeA.degree < nodeB.degree:
                degree = nodeB.degree
                value = nodeB.coefficient
                nodeB = nodeB.next
            else:
                degree = nodeA.degree
                value = nodeA.coefficient + nodeB.coefficient
                nodeA = nodeA.next
                nodeB = nodeB.next
            self._appendTerm(degree, value)


        # If self list contains more terms appedn them
        while nodeA is not None:
            self._appendTerm(nodeA.degree, nodeA.coefficient)
            nodeA = nodeA.next


        # Or if rhs contains more temrs append them
        while nodeB is not None:
            self._appendTerm(nodeB.degree, nodeB.coefficient)
            nodeB = nodeB.next


        return newPoly


    # Polynomial subtraction: newPoly  = self - rhsPoly
    def __sub__(self, rhsPoly):
        assert self.degree() >= 0 and rhsPoly.degree() >= 0, \
            "Subraction only allowed on non-empty polynomials."
        newPoly = linkPolynomial()
        nodeA = self._termList
        nodeB = rhsPoly._termList


        # Add corresponding terms until one list is empty
        while nodeA is not None and nodeB is not None:
            if nodeA.degree > nodeB .degree:
                degree  = nodeA.degree
                value = nodeA.coefficient
                nodeA = nodeA.next
            elif nodeA.degree < nodeB.degree:
                degree = nodeB.degree
                value = nodeB.coefficient
                nodeB = nodeB.next
            else:
                degree = nodeA.degree
                value = nodeA.coefficient - nodeB.coefficient
                nodeA = nodeA.next
                nodeB = nodeB.next
            self._appendTerm(degree, value)


        # If self list contains more terms appedn them
        while nodeA is not None:
            self._appendTerm(nodeA.degree, nodeA.coefficient)
            nodeA = nodeA.next


        # Or if rhs contains more temrs append them
        while nodeB is not None:
            self._appendTerm(nodeB.degree, -nodeB.coefficient)
            nodeB = nodeB.next


        return newPoly


    # Polynomial multiplication: newPoly = self * rhsPoly
    def __mul__(self, rhsPoly):
        assert self.degree() >= 0 and rhsPoly.degree() >= 0, \
          "Multiplication only allowed on non-empty polynomials."


        # Create a new polynomial by multiplying rhsPoly by the first term
        node = self._polyHead
        newPoly = rhsPoly._termMultiply(node)


        # Ierate through the remaining terms of the poly computing the
        # product of the rhsPoly by each term
        node = node.next
        while node is not None:
            tempPoly = rhsPoly._termMultiply(node)
            newPoly = newPoly.add(tempPoly)
            node = node.next


        return newPoly


    # Helper method for creating a new polynomial from multiplying an 
    # existing polynomail by another term
    def _termMultiply(self, termNode):
        newPoly = linkPolynomial()


        # Iterate through the terms and compute the product of each term 
        # and the term in termNode
        curr = termNode.next
        while curr is not None:
            # compute the product of the term
            newDegree = curr.degree + termNode.degree
            newCoeff = curr.coefficient * termNode.coefficient


            # Append it to the new polynomial
            newPoly._appendTerm(newDegree, newCoeff)


            # Advance the current pointer
            curr = curr.next
        return newPoly
        
    # Helper method for appending terms to the polynomial
    def _appendTerm(self, degree, coefficient):
        if coefficient != 0.0:
            newTerm = _PolyTermNode(degree, coefficient)
            if self._polyHead is None:
                self._polyHead = newTerm
            else:
                self._polyTail.next = newTerm
            self._polyTail = newTerm


# Class for creating polynomial term nodes used with the linked list
class _PolyTermNode(object):
    def __init__(self, degree, coefficient):
        self.degree = degree
        self.coefficient = coefficient
        self.next = None
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值