使用递归将多项式相加

时间:2011-03-30 20:22:15

标签: java recursion linked-list

我需要使用递归方法将两个多项式相加。 这是一个过期的任务(我想类似的事情将在测试中)。 主要课程:

public class Polynomial {

    private Node poly;


    public Polynomial(){
    poly = new Node();
    }

    private Polynomial(Node node){
    poly = node;
    }
    public void addTerm(int coef, int exp){
    Term term = new Term(coef, exp);
    Node node = new Node(term, null);

    Node iterator = poly;

    //if the list is empty just add the node
    if (poly.next == null){
        System.out.println("poly.next is null. adding node to first pos.");
        poly.next = node;
        return;
    }

    //if list isn't empty find the appropriate spot for it
    while (iterator.next != null){
        System.out.println("iterator.next != null...");
        if (exp < iterator.next.data.exp){
        System.out.println("\texp < iterator.next.data.exp");
        node.next = iterator.next;
        iterator.next = node;
        return;
        }
        if (exp == iterator.next.data.exp){
        System.out.println("\texp == iterator.next.data.exp");
        iterator.next.data.coef += coef;
        return;
        }
        iterator = iterator.next;
    }

    //if we get to this point then the list isn't empty
    //and it doesn't fit inside the list, hence it must
    //be added to the end of the list
    System.out.println("list wasn't empty, didn't fit inside");
    iterator.next = node;
    return;
    }

    @Override
    public String toString(){
    Node iterator = poly;
    String out = "";

    if (poly.next == null){
        return out;
    }
    while(iterator.next != null){
        out += iterator.next.data.coef;
        out += "*x^";
        out += iterator.next.data.exp;
        out += " + ";
        iterator = iterator.next;
    }
    return out.substring(0, out.lastIndexOf('+'));
    }



    public Polynomial addPolynomial (Polynomial that){
    Polynomial ret = new Polynomial();

    Polynomial iterator = this;

    return addPolynomial(that, ret, iterator);
    }

    public Polynomial addPolynomial(Polynomial that, Polynomial ret, Polynomial iterator){
    if (iterator.poly.next == null){
        return new Polynomial(that.poly);
    }

    if (that.poly.next == null){
        return new Polynomial(iterator.poly);
    }

    if (iterator.poly.next.data.exp < that.poly.next.data.exp){
        ret.addTerm(iterator.poly.next.data.coef, iterator.poly.next.data.exp);
        iterator.poly = iterator.poly.next;
        return iterator.addPolynomial(that);
    }

    if (iterator.poly.next.data.exp == that.poly.next.data.exp){
        ret.addTerm(iterator.poly.next.data.coef + that.poly.next.data.coef, iterator.poly.next.data.exp);
        iterator.poly = iterator.poly.next;
        that.poly = that.poly.next;
        return iterator.addPolynomial(that);
    }

    if (iterator.poly.next.data.exp > that.poly.next.data.exp){
        ret.addTerm(that.poly.next.data.coef, that.poly.next.data.exp);
        that.poly = that.poly.next;
        return iterator.addPolynomial(that);
    }
    return ret;
    }

    /*
     * Term
     */
    private class Term implements Comparable{
    int coef;
    int exp;

    public int getCoef() {
        return coef;
    }

    public void setCoef(int coef) {
        this.coef = coef;
    }

    public int getExp() {
        return exp;
    }

    public void setExp(int exp) {
        this.exp = exp;
    }

    public Term(int coef, int exp) {
        this.coef = coef;
        this.exp = exp;
    }
    public int compareTo(Object rhs){
        Term that = (Term)rhs;
        return this.exp - that.exp;
    }
    }//end Term


    /*
     * Node
     */
    private class Node{
    Term data;
    Node next;

    public Term getData() {
        return data;
    }

    public void setData(Term data) {
        this.data = data;
        this.next = null;
    }

    public Node getNext() {
        return next;
    }

    public void setNext(Node next) {
        this.next = next;
    }

    public Node() {
        this.data = null;
        this.next = null;
    }

    public Node(Term data, Node next) {
        this.data = data;
        this.next = next;
    }
    }//end Node




}

测试类:

public class Polynomials {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Polynomial p1 = new Polynomial();
        Polynomial p2 = new Polynomial();
        Polynomial p0 = new Polynomial();
        p1.addTerm(1, 2);
        p1.addTerm(1, 4);
        p1.addTerm(1, 6);
    p2.addTerm(1, 1);
    p2.addTerm(1, 3);
    p2.addTerm(1, 5);
    System.out.println("p1 = " + p1.toString());
    System.out.println("p2 = " + p2.toString());

    System.out.println("Adding p1 to p2...");
    p0 = p1.addPolynomial(p2);
    System.out.println(p0.toString());
    }
} 

2 个答案:

答案 0 :(得分:1)

您是否考虑过这种做法?

public class Polynomial {
public static void main(String[] args) {
    Polynomial p1 = new Polynomial();
    Polynomial p2 = new Polynomial();
    Polynomial p0 = new Polynomial();
    p1.addTerm(1, 2);
    p1.addTerm(1, 4);
    p1.addTerm(1, 6);
    p2.addTerm(1, 1);
    p2.addTerm(2, 3);
    p2.addTerm(2, 2);
    p2.addTerm(1, 5);
    System.out.println("p1 = " + p1.toString());
    System.out.println("p2 = " + p2.toString());

    System.out.println("Adding p1 to p2...");
    p0 = p1.addPolynomial(p2);
    System.out.println(p0.toString());

    for(int i = 0;i < 100;i++) {
        p1 = new Polynomial();
        p2 = new Polynomial();
        for(int j = 0;j < 4;j++) {
            p1.addTerm((int) (10 * Math.random()) - 5,
                    (int) (4 * Math.random()));
            p2.addTerm((int) (10 * Math.random()) - 5,
                    (int) (4 * Math.random()));
        }
        p0 = p1.addPolynomial(p2);
        System.out.println(p1 + "\n" + p2 + "\n" + p0 + "\n");
    }
}



enum Comp {
    LT, EQ, GT
}


static Comp cmp(int a, int b) {
    return (a < b) ? Comp.LT : (a == b) ? Comp.EQ : Comp.GT;
}

private Term poly;


public Polynomial() {
    poly = null;
}


public void addTerm(int coef, int exp) {
    if (coef == 0) return;
    Term term = new Term(coef, exp,null);
    if (poly == null) {
        poly = term;
    } else {
        poly = poly.add(term);
    }
}


@Override
public String toString() {
    if (poly == null) return "0";

    StringBuilder buf = new StringBuilder();
    poly.writeTo(buf);
    return buf.toString();
}


public Polynomial addPolynomial(Polynomial that) {
    Polynomial ret = new Polynomial();
    if (poly != null) {
        ret.poly = new Term(poly);
        if (that.poly != null) {
            ret.poly = ret.poly.add(new Term(that.poly));
        }
    } else if (that.poly != null) {
        ret.poly = new Term(that.poly);
    }
    return ret;
}


private class Term {
    final int coef;

    final int exp;

    final Term next;


    Term(int coef, int exp, Term next) {
        this.coef = coef;
        this.exp = exp;
        this.next = next;
    }


    Term(Term copy) {
        this.coef = copy.coef;
        this.exp = copy.exp;
        if (copy.next == null) {
            this.next = null;
        } else {
            this.next = new Term(copy.next);
        }
    }


    Term add(Term other) {
        if (other == null) return this;

        switch (cmp(this.exp, other.exp)) {
        case LT: {
            Term n = other.add(this);
            return n;
        }
        case GT: {
            if (next == null) {
                return new Term(coef,exp,other);
            }

            return new Term(coef,exp,next.add(other));
        }
        default: {
            Term n = (next==null) ? other.next : next.add(other.next);
            int nc = coef+other.coef;
            return (nc!=0) ? new Term(nc,exp,n) : n;
        }
        }
    }


    public void writeTo(StringBuilder app) {
        if (coef != 1 || exp == 0) app.append(coef);
        if (exp == 1) {
            app.append("x");
        } else if (exp != 0) {
            app.append("x^").append(exp);
        }
        if (next != null) {
            app.append('+');
            next.writeTo(app);
        }
    }
}
}

答案 1 :(得分:0)

那肯定比必要的复杂一点。

所以你想在已经存在的多项式中添加一个多项式,即: 4 * x ^ 2 + 4到5 * x ^ 4 + x + 5,结果为:5 * x ^ 4 + 4 * x ^ 2 + x + 9

你可以通过使用一个数组显然可以简化问题,但是对于链表也没那么难,代码看起来应该是这样的:

你有两个指针指向我们想要添加值(term1)的多项式中的当前位置,另一个指向我们想要添加的值(term2),两个指针都初始化为链表中的最低条目(其中我们假设根据指数排序。

while term1 != NULL && term2 != NULL do:
   term1 > term2:
      add term2 to list
      term2 = term2.next()
   term2 > term1:
      term1 = term1.next()
   term1 = term2:
      add term2 to term1
      term1 = term1.next()
      term2 = term2.next()
while term1 == NULL && term2 != NULL:
   add term2
   term2 = term2.next()   

您可以轻松地调整它以创建新的多项式,而不是将一个多项式添加到另一个。

好的,有关如何将迭代解决方案转换为递归解决方案的更多细节: 在考虑递归时,您始终要做的第一件事就是退出条件。

在这种情况下,如果您认为这很容易:只要term2不为NULL,我们才会工作,只要term2为NULL,我们就完成了。

下一步是考虑一个好的方法签名,这次也很容易,因为我们只需要这两个术语,所以你可以使用两个迭代器: void addTogether(Iterator term1,Iterator term2); (假设您使用的是与ListIterator类似的接口,因为您需要在term1之前的位置插入 - 有几种方法可以实现它)

现在你已经摆脱了while循环并用递归调用替换它们(在这种情况下你可以区分不同的情况,做必要的操作并再次调用它)