如何在C中乘多项式?

时间:2015-11-20 14:48:54

标签: c

我希望这段代码有意义.....我创建两个多项式并尝试将它们相乘。问题是我不知道应该做些什么才能正确地将它们相乘。该程序将多项式相乘,将结果存储到另一个多项式,但不会添加具有相同功率的系数。

  

为了做到这一点,我该怎么办?另外我应该如何在这个程序中使用free()

#include <stdio.h>
#include <stdlib.h>

typedef struct poly {
  int coef;
  int exp;
  struct poly *next;
} poly;

int main(void) {
  poly * po1, *head, *po2, *head2, *po3, *head3 = NULL;
  int sel, c = 1;

  head = NULL;
  printf(
      "\nInsert elements for the first polynomial from the biggest to the smallest power of x. (Enter a power of zero (0) to stop)\n");
  while (1) {
    po1 = (poly *) malloc(sizeof(poly));
    printf("Give number: ");
    scanf("%d", &po1->coef);
    printf("Give power of x: ");
    scanf("%d", &po1->exp);
    po1->next = head;
    head = po1;
    if (po1->exp == 0) break;
  }

  head2 = NULL;
  printf(
      "\nInsert elements for the second polynomial from the biggest to the smallest power of x. (Enter a power of zero (0) to stop)\n");
  while (1) {
    po2 = (poly *) malloc(sizeof(poly));
    printf("Give number: ");
    scanf("%d", &po2->coef);
    printf("Give power of x: ");
    scanf("%d", &po2->exp);
    po2->next = head2;
    head2 = po2;
    if (po2->exp == 0) break;
  }

  po1 = head;
  po2 = head2;

  printf("Multiplying********\n");
  po1 = head;
  po2 = head2;
  while (po1 || po2) {
    po2 = head2;
    while (po1 && po2) {
      po3 = (poly *) malloc(sizeof(poly));
      po3->coef = (po1->coef) * (po2->coef);
      po3->exp = (po1->exp) + (po2->exp);
      po3->next = head3;
      head3 = po3;
      po2 = po2->next;
    }
    po1 = po1->next;
  }
  while (po3) {
    printf("%+d(x^%d)", po3->coef, po3->exp);
    po3 = po3->next;
  }
  printf("\n");

}

 }

3 个答案:

答案 0 :(得分:2)

首先,您需要一种更有条理的方法来向多项式添加项。仅将新系数添加到列表的末尾是不够的。您需要在列表中搜索正确的位置并在那里添加多项式。

// Adds coef * x ^ exp to poly.
void poly_add (poly ** add2me, int coef, int exp)
{
    poly ** p;

    // printf ("poly_add %d %d\n", coef, exp);

    // Advance p to the first node such that 
    //   *p is either the correct term or the subsequent term.
    for (p = add2me; *p != NULL && (*p)->exp > exp; p = &(*p)->next);

    // If *p is too small a coefficient / NULL,
    //   then it's pointing to the next term and you need to make a new node
    if (*p == NULL || (*p)->exp < exp)
    {
        poly * new_poly = malloc(sizeof(poly));
        new_poly->coef = coef;
        new_poly->exp = exp;
        new_poly->next = *p;
        *p = new_poly;
    }
    // Else *p is the correct exponent, in which case we add...
    else
    {
        (*p)->coef += coef;
    }
}

然后,它只是对你的乘法循环的一个小修改,以使事情有效。

printf("Multiplying********\n");
po1 = head;
po2 = head2;
po3 = NULL;

while(po1||po2){
    po2 = head2;
    while(po1&&po2) {
        int new_coef = (po1->coef)*(po2->coef);
        int new_exp = (po1->exp)+(po2->exp);
        poly_add(&po3, new_coef, new_exp);

        po2 = po2->next;
    }
    po1 = po1->next;
}

附录:free()

每个多项式都是一个链表,所以你想用一般的列表销毁函数手动清理多项式......

void poly_free (poly * free_me)
{
  poly * next;
  for (; free_me != NULL; free_me = next)
  {
    next = free_me->next; // Safe because free_me != NULL
    free(free_me);
  }
}

在程序终止之前,为每个多项式调用它。像valgrind这样的工具可以帮助您了解是否有泄漏记忆。

答案 1 :(得分:2)

扩展我的评论......

如果将数据存储在数组中,使得数组位置对应于指数,则将更容易管理系数。例如,您将3.0x2 - 2.0x + 1.0表示为

double c[3] = { 1.0, -2.0, 3.0 };

因此,二次多项式需要一个3元素阵列,一个三次多项式需要一个4元素阵列等。

将两个多项式相乘然后变成一个简单的嵌套循环:

void polymul( double *x, size_t xsize, double *y, size_t ysize, double *r, size_t rsize )
{
  memset( r, 0, sizeof *r * rsize );

  for ( size_t i = 0; i < xsize; i++ )
  {
    for ( size_t j = 0; j < ysize; j++ )
    {
      r[i + j] += x[i] * y[j];
    }
  }
}

如果将I / O和内存管理与计算分开,生活也会更简单。如果你知道输入多项式有多大,你就知道输出多项式需要多大:

double *x, *y;
size_t xsize, ysize;

getcoeffs( &x, &xsize );
getcoeffs( &y, &ysize );

size_t rsize = xsize + ysize - 1;
double *r = malloc( sizeof *r * rsize );

polymul( x, xsize, y, ysize, r, rsize );
...
free( r );
free( x );
free( y );

如果您承诺使用结构列表方法,那么QuestionC的答案就是一个很好的答案。我只是认为这种方法更简单。

答案 2 :(得分:1)

您有两种选择:

  • 进行第二次传递(例如按系数排序),并使用相同的功率合并系数。
  • 像在纸上一样进行乘法,计算列的总和(它可以是滚动总和)。最简单的方法是首先实现添加。