0

I have to write a program in C whereby I have to add two, single-variable polynomials. I can do it partly and I end up with wrong answer.

Consider the two polynomials:

5x^2 + 6x^3 + 9  
6x^3 + 5x^2 + 3x + 2  

I know what the answer is going to be, manually. Here is my logic:

if(term1->exp == term2->exp){ // same power of x
    // add them, store them in the final answer linked list
    // increment pointers of both the term1 and term2 linkedlist
}
if(term1->exp > term2->exp){ // term1 has higher power of x than term2
    // increment term1 linked list in search of lower power of x
    // ** term1 is now pending **
}

if(term1->exp < term2->exp){ // term1 has lesser power of x than term2
    // increment term2 linked list in search of lower power of x
    // ** term2 is now pending **
}  

The problem I face is with the pending terms. How do I take care of the pending terms ?
How do I add them properly ?

Code here: http://pastebin.com/70UJdNiQ

An SO User
  • 24,612
  • 35
  • 133
  • 221
  • 5
    Post the code that gives you the wrong answer. – WhozCraig Sep 03 '13 at 18:55
  • The brief snippet you has little context to which to respond. You need to show how your code steps through the terms and how you're capturing the resulting polynomial. – lurker Sep 03 '13 at 19:00
  • 1
    Update the question with how you'd solve the problem with paper. Then update the question with the code that implements that algorithm. Then update the question with whatever is wrong in the code that you have questions about. – dcaswell Sep 03 '13 at 19:02
  • @mbratch http://pastebin.com/70UJdNiQ I dont know why it displays polynomial 1 properly and polynomial 2 improperly. – An SO User Sep 03 '13 at 19:15
  • @WhozCraig Complete code posted. See link. – An SO User Sep 03 '13 at 19:17
  • You polynomials have the exponents unordered. You could need a previous reordering from lowest to highest exponent (or well from highest to lowest). If you don't want this, then you have to change your algorithm, because the automatic (in/dec)crement of exponents will cause loosing some terms. – pablo1977 Sep 03 '13 at 19:21
  • @pablo1977 I was considering adding another member to `struct` named `pending` and then re-iterate ? – An SO User Sep 03 '13 at 19:22
  • I think you can reiterate in each polynomial (1 and 2), after terminating the while(), without adding any member `pending`. Besides, check my answer below. – pablo1977 Sep 03 '13 at 23:54

2 Answers2

2

I have read your code.

You have memory issues inside the function addPolyomials.
This problem is caused bad a wrong logic: Leeor has given you the solution in his answer yet: you need to add the words else before the 2nd and 3rd ifs.
If you don't, then the when the 1st if gives TRUE, a new pointer is created and added to the list, and an advance is done.

Thus, when tne 2nd if is reached, the comparisson is done with these new advanced pointers.
This is a logical error.

By doing this change to the program, there are some issues yet.

Since you initialize polynomial3 to garbage, this is shown in the final result.
Maybe you have to initialize, also, the components exp and coef (to 0?).

        polynomial3->exp = 0;
        polyoomial3->coef = 0;

You have an error in main() when you "create" polynomial2.
There, you are using the list polynomial1.
The line has to be changed to:

            polynomial2 = addTerm(polynomial2,exp,coef);

With theses changes, we can watch the logic itself of the program.
I obtained a nonsense solution.
I think that your idea of defining some "pending" flag is not enough.

Your logic seems to consider the polynomials as if they were the exponents in order.
But the user will not enter the polynomials in this way.
Your examples at the top of your question have the exponents unordered (the first polynomial).

I think it could be good idea to handle your lists at the moment they are entered, putting the terms in order. Since the terms are added one at the time, this can be easily achieved by searching in the list from the top of it, and inserting the terms properly.
For example, if you have 5x^2 + 6x^3 + 9, the first step would insert 5 2 at the top of the list polynomial1. In the next iteration the pair 6 3 will inserted again at the top, before the pair (5, 2), and so on. Your final list would be:

  (6, 3, next), (5, 2, next), (9, 0, next), NULL

This procedure ensures that you can iterate as you want. (There is a minor problem: what happens if the user enters a repeated exponent? In this case no new element is added to the list: just add the new coefficient!)

Finally, we can analyze the "pending" coefficientes issue in the sum.
Observe that your while() is iterating only if both lists are not NULL.
When the while() arrives to its end, only three situations are possible:

         (polynomial1 != NULL && polynomial2==NULL)
 or well (polynomial2 != NULL && polynomial1==NULL), 
 or well both are NULL.  

It is enough to check for (polynomial1 != NULL) and (polynomial2 != NULL).
In the 1st case, just "paste" the pending terms of polynomial1 to polynomial3.
In the 2nd case, do the same for polynomial2.

Finally, in the display function you could handle in a better way the terms with coefficient 0.
Probably it is better that the terms with coefficient 0 be not shown.

Your program needs much more improvement, but this is out of the scope of your question.

pablo1977
  • 4,281
  • 1
  • 15
  • 41
1

You shouldn't advance the term with the higher power, if it's higher (and assuming your lists are sorted with descending powers), than you can just add it to the final answer and be done with it - you know the other list won't have any term to match that. In pseudo -

if (term1->exp == term2->exp) { add and store, advance both }
else if (term1->exp > term2->exp) { add term1 to the result list and advance it }
else  { add term2 to the result list and advance it }

then just deal with the list that has the leftovers (smaller terms)

In case the lists are not sorted, note that to find matches for every term you'll need to pay O(N^2), consider sorting both lists first (for a lower penalty of O(NlogN)), and then traverse them as above in O(N)

Leeor
  • 19,260
  • 5
  • 56
  • 87