C多项式加法练习

C Polynomial Addition exercise

我目前正在做算法 class 的练习。我被要求编写一个 C 程序,将用户输入的两个多项式相加,我可以通过询问用户每个多项式的最高次数及其系数来完成。

问题是用户的输入必须类似于 -5x4+2x2+6(所有系数和度数都可以从 09)。

我设法将这个字符串转换为数组

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

然后我创建了一个结构

struct polynome {
    int coeff;
    int degre;
};

我找不到将此数组转换为多项式的方法,这是我为使其工作而编写的所有函数,但我总是得到奇怪的输出:

int DEGREMAXTAB(char TAB[]) {
    int i = 0;
    int degre0 = 0;
    while (TAB[i] != '[=12=]') {
        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] == '[=12=]')
            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 = '[=12=]';
        } else {
            signe = '+';
        }
        printf("%c%dx%d", signe,poly[i].coeff, poly[i].degre);
    }
}

到目前为止我的主要内容:

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ôme\n");
    tableau(chainea);
    while (chainea[i] != '[=13=]') {
        printf("%c",chainea[i]);
        i++;
    } // did this to check that there was no problem here
    
    deg1 = DEGREMAXTAB(chainea);
    printf("%d\n", deg1); // same, except that I must return deg1-48 and idk why
 
    tabpoly(chainea, deg1, poly1);
    afficher(poly1, deg1);   
}

我知道我的代码可能真的很乱,对此我深表歉意,如果有人能帮我解决这个问题,我会很高兴。这是我在示例中键入输入时的输出。

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

真的非常感谢,我尽可能多地提供信息。 :)

我找到了解决方案,但是度数显示是反的;常数是第一项。索引用作多项式的次数。

#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;
}

@sadbro:你的回答有一些问题:

  • 系数数组的长度应为 10,循环应 运行 i <= 9i < 10。更好的是:将 MAX_POWER 定义为 9 并在数组大小和 for 循环中使用它。
  • 如果系数按递增顺序输入,输出循环应从最高指数向下迭代到 0
  • 你不应该打印带有 0 系数的单项式。
  • 您不应打印等于 1-1 的系数。
  • 你应该打印没有前导的负系数 +
  • 通常不打印 display() 中的尾随换行符。

这是修改后的版本:

#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;
}

您的代码中存在多个问题:

  • 您应该使用简单的 fgets() 读取多项式,而不是使用 scanf() 一次读取一个字符。 scanf() 不是最好的工具。
  • 您得到 48 偏移量的原因是数字是 ASCII 字符,而不是整数值。必须减去 '0' 的值(即 ASCII 中的 48 值)才能得到相应的数字。
  • 您在访问 poly 数组中超出最大索引值的元素时遇到未定义的行为,因为偏移量为 48。您应该检查指数是否在适当的范围内。
  • 你得到随机值,因为 poly 数组未初始化。

这是修改后的版本:

#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] != '[=10=]'; 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] != '[=10=]') {
        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] != '[=10=]' && 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ôme\n");
    // read a full line from stdin
    if (!fgets(chainea, sizeof(chainea), stdin))
        return 1;

    deg1 = degremaxtab(chainea);
    printf("exposant maximum: %d\n", deg1);

    deg1 = tabpoly(chainea, poly1, 5);
    if (deg1 < 0) {
        if (deg1 == -1)
            printf("exposant trop grand\n");
        else
        if (deg1 == -2)
            printf("erreur de syntaxe\n");
        else
            printf("erreur\n");
    } else {
        afficher(poly1, deg1);
    }
    return 0;
}