TransWikia.com

C Polynomial Addition exercise

Stack Overflow Asked by aaa on February 23, 2021

I am currently working on an exercise for algorithm class. I was asked to write a C program which adds two polynomials entered by the user, which, I am able to do by asking the user the highest degrees of each polynomial and their coefficients.

The problem is that the input of the user must be something like for example -5x4+2x2+6 (all coefficients and degrees can go from 0 to 9).

I managed to convert this string to an array

void tableau(char *chaine) {
    int i = 0;
    while (1) {
        scanf("%c", &chaine[i]);
        if (chaine[i] == 'n') {
            break;
        } else {
            i++;
        }
    }
}

And I created a structure

struct polynome {
    int coeff;
    int degre;
};

I can’t find a way to convert this array to a polynomial, here are all the functions I have written to make it work but I always get weird outputs:

int DEGREMAXTAB(char TAB[]) {
    int i = 0;
    int degre0 = 0;
    while (TAB[i] != '') {
        if (TAB[i] == 'x' && (int)(TAB[i+1]) > degre0)
            degre0 = (int)(TAB[i+1]);
        i++;
    }
    return degre0; // it returns the right highest degree + 48 for some reason, I don't know
}

void tabpoly(char chaine[], int degre0, struct polynome polynome[]) {
    int k = 1;
    int i = 0, a = 0, b = 0;
    
    while (chaine[i]) { // I am sorry, all of this is really messy, I just tried
        if (chaine[i] == '')
            break;
        
        if (chaine[i] == '-') {
            k = -1;
            i++;
        }
        if (chaine[i] == '+') {
            k = 1;
            i++;
        }
        if (chaine[i] != 'x') {
            a = k * ((int)(chaine[i]));
            i++;
        }
        i++;
        b = ((int)(chaine[i]));
        polynome[degre0].coeff = a;
        polynome[degre0].degre = b;
        degre0++;
        i++;
    }
}

void afficher(struct polynome poly[], int degre0) { /* maybe something is wrong here too I
really can't find the issue except by tweaking everything and causing other issues */
    int i = 0;
    char signe;
    for (i = degre0; i >= 0; i--) {
        if (poly[i].coeff < 0) {
            signe = '';
        } else {
            signe = '+';
        }
        printf("%c%dx%d", signe,poly[i].coeff, poly[i].degre);
    }
}

My main so far :

int main(int argc, const char *argv[]) {
    struct polynome poly1[6]; // the maximum degree is 5
    int deg1 = 0, i = 0;
    char chainea[21];
    printf("Entrez votre premier polynômen");
    tableau(chainea);
    while (chainea[i] != '') {
        printf("%c",chainea[i]);
        i++;
    } // did this to check that there was no problem here
    
    deg1 = DEGREMAXTAB(chainea);
    printf("%dn", deg1); // same, except that I must return deg1-48 and idk why
 
    tabpoly(chainea, deg1, poly1);
    afficher(poly1, deg1);   
}

I know my code might be really messy and I apologize for that, I would be glad if someone here could help me figure this out. Here is the output I have when typing the input from the example.

Entrez votre premier polynôme
-5x4+2x2+6
-5x4+2x2+6
4
-101x4+0x0+0x0+0x0+0x1Program ended with exit code: 0


Entrez votre premier polynôme
2x2
2x2
2
+2x2+0x0+0x1Program ended with exit code: 0

Thank you really much, I tried to put as much information as I could. 🙂

3 Answers

There are multiple problems in your code:

  • you should read the polynomial with a simple fgets() instead of reading one character at a time with scanf(). scanf() is not the best tool for that.
  • the reason you get an offset of 48 is digits are ASCII characters, not integer values. You must subtract the value of '0' (which as the value 48 in ASCII) to get the corresponding number.
  • you experience undefined behavior as you access elements in the poly array beyond the maximum index value because of the 48 offset. You should check that the exponent is within the proper range.
  • you get random values because the poly array is uninitialized.

Here is a modified version:

#include <stdio.h>

struct polynome {
    int coeff;
    int degre;
};

int degremaxtab(const char tab[]) {
    int i, exp, max_exp = 0;
    for (i = 0; tab[i] != ''; i++) {
        if (tab[i] == 'x') {
            i++;
            if (tab[i] >= '0' && tab[i] <= '9') {
                exp = tab[i] - '0';
            } else {
                exp = 1;
            }
            if (max_exp < exp) {
                max_exp = exp;
            }
        }
    }
    return max_exp;
}

int skip_spaces(const char chaine[], int i) {
    while (chaine[i] == ' ' || chaine[i] == 't' || chaine[i] == 'n') {
        i++;
    }
    return i;
}

/* return the maximum exponent in the polynomial */
int tabpoly(const char chaine[], struct polynome polynome[], int max_degree) {
    int i, max_exp, sign, coeff, exp;

    for (i = 0; i <= max_degree; i++) {
        polynome[i].coeff = 0;
        polynome[i].degre = i;
    }

    i = 0;
    max_exp = 0;
    while (chaine[i] != '') {
        i = skip_spaces(chaine, i);
        // get sign (allow +-)
        sign = 1;
        if (chaine[i] == '+') {
            i++;
        }
        i = skip_spaces(chaine, i);
        if (chaine[i] == '-') {
            sign = -1;
            i++;
        }
        i = skip_spaces(chaine, i);
        if (chaine[i] >= '0' && chaine[i] <= '9') {
            coeff = chaine[i] - '0';
            i++;
        } else {
            coeff = 1;
        }
        if (chaine[i] == 'x') {
            i++;
            if (chaine[i] >= '0' && chaine[i] <= '9') {
                exp = chaine[i] - '0';
                i++;
            } else {
                exp = 1;
            }
        } else {
            exp = 0;
        }
        i = skip_spaces(chaine, i);

        // check for a complete term
        if (chaine[i] != '' && chaine[i] != '+' && chaine[i] != '-')
            return -2;  // syntax error
        if (exp > max_degree)
            return -1;  // exponent too large
        if (max_exp < exp)
            max_exp = exp;
        polynome[exp].coeff += sign * coeff;
    }
    return max_exp;
}

void afficher(struct polynome poly[], int degre0) {
    int i, pos;
    /* simple output */
    for (i = degre0; i >= 0; i--) {
        printf("%+dx%d", poly[i].coeff, poly[i].degre);
    }
    printf("n");
    /* clean output */
    pos = 0;
    for (i = degre0; i >= 0; i--) {
        int coeff = poly[i].coeff;
        int degre = poly[i].degre;
        if (coeff != 0) {
            if (coeff > 0) {
                if (pos > 0)
                    pos += printf("+");
                if (coeff != 1 || degre == 0)
                    pos += printf("%d", coeff);
            } else {
                if (coeff != -1 || degre == 0)
                    pos += printf("%d", coeff);
                else
                    pos += printf("-");
            }
            if (degre > 0) {
                printf("x");
                if (degre > 1)
                    pos += printf("%d", degre);
            }
        }
    }
    if (pos == 0) {
        printf("0");
    }
    printf("n");
}

int main(int argc, const char *argv[]) {
    struct polynome poly1[6]; // the maximum degree is 5
    char chainea[100];
    int deg1;

    printf("Entrez votre premier polynômen");
    // read a full line from stdin
    if (!fgets(chainea, sizeof(chainea), stdin))
        return 1;

    deg1 = degremaxtab(chainea);
    printf("exposant maximum: %dn", deg1);

    deg1 = tabpoly(chainea, poly1, 5);
    if (deg1 < 0) {
        if (deg1 == -1)
            printf("exposant trop grandn");
        else
        if (deg1 == -2)
            printf("erreur de syntaxen");
        else
            printf("erreurn");
    } else {
        afficher(poly1, deg1);
    }
    return 0;
}

Correct answer by chqrlie on February 23, 2021

@sadbro: your answer has some problems:

  • the array of coefficients should have a length of 10, and the loops should run to i <= 9 or i < 10. Better even: define MAX_POWER to 9 and use it in the array size an for loops.
  • if the coefficients are entered in increasing order, the output loop should iterate from the highest exponent down to 0.
  • you should not print the monomials with a 0 coefficient.
  • you should not print the coefficients equal to 1 or -1.
  • you should print negative coefficients without a leading +.
  • it is more general to not print the trailing newline in display().

Here is a modified version:

#include <stdio.h>

#define MAX_POWER  9

struct poly {
    int coef[MAX_POWER + 1];
};

struct poly add(struct poly P1, struct poly P2) {
    struct poly result;
    for (int i = 0; i <= MAX_POWER; i++) {
        result.coef[i] = P1.coef[i] + P2.coef[i];
    }
    return result;
}

// return the number of bytes printed
int display(struct poly P) {
    int pos = 0;
    for (int i = MAX_POWER; i >= 0; i--) {
        int coefficient = P.coef[i];
        const char *prefix = "";
        if (coefficient != 0) {
            if (pos) {
                if (coefficient > 0) {
                    prefix = " + ";
                } else {
                    prefix = " - ";
                    coefficient = -coefficient;
                }
            } else {
                if (coefficient < 0) {
                    prefix = "-";
                    coefficient = -coefficient;
                }
            }
            pos += printf("%s", prefix);
            if (coefficient != 1) {
                pos += printf("%d", coefficient);
            }
            if (i > 1) {
                pos += printf("x%d", i);
            } else
            if (i == 1) {
                pos += printf("x");
            }
        }
    }
    if (pos == 0) {
        pos += printf("0");
    }
    return pos;
}
  
int main() {
    struct poly p1, p2, result;
    printf("Enter coefficients in order[Po 1]: ");
    for (int i = 0; i <= MAX_POWER; i++) {
        if (scanf("%d", &p1.coef[i]) != 1)
            return 1;
    }
    printf("Enter coefficients in order[Po 2]: ");
    for (int i = 0; i <= MAX_POWER; i++) {
        if (scanf("%d", &p2.coef[i]) != 1)
            return 1;
    }
    result = add(p1, p2);
    printf("nThe Result is");
    for (int i = 0; i <= MAX_POWER; i++) {
        printf(" %d", result.coef[i]);
    }
    printf("n");
    display(result);
    printf("n");
    return 0;
}

Answered by chqrlie on February 23, 2021

I found a solution but the degrees are displayed in inverse; the constant is the first term. The indices are used as the degree of polynomial. enter image description here

#include <stdio.h>

struct poly {
    int coef[9];
};

struct poly add(struct poly P1, struct poly P2) {
    struct poly result;
    for (int i = 0; i < 9; i++) {
        result.coef[i] = P1.coef[i] + P2.coef[i];
    }
    return result;
}
   
void display(struct poly P) {
    printf("%d + %dx", P.coef[0], P.coef[1]);
    for (int i = 2; i < 9; i++) {
        printf(" + %dx%d", P.coef[i], i);
    }
    printf("n");
}
  
int main() {
    struct poly p1, p2, result;
    printf("Enter coefficients in order[Po 1]: ");
    for (int i = 0; i < 9; i++) {
        scanf("%d", &p1.coef[i]);
    }
    printf("Enter coefficients in order[Po 2]: ");
    for (int i = 0; i < 9; i++) {
        scanf("%d", &p2.coef[i]);
    }
    result = add(p1, p2);
    printf("nThe Result is ");
    for (int i = 0; i < 9; i++) {
        printf("%d ", result.coef[i]);
    }
    printf("n");
    display(result);
    return 0;
}

Answered by sadbro on February 23, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP