【问题标题】:How to multiply polynomials in C?如何在C中乘以多项式?
【发布时间】:2015-11-20 14:48:53
【问题描述】:

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

我应该怎么做才能做到这一点?另外我应该如何在这个程序中使用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");

}

 }

【问题讨论】:

  • 这里肯定有一些缺失的代码。请编辑您的问题,使其显示您的所有代码,并且格式正确。
  • 如果您将系数存储在数组中,您将有一个非常更轻松的时间,这样数组位置代表相应的指数(例如,3x^2 + 2x - 1 将表示为 @ 987654325@)。您的产品将在嵌套循环中计算为r[i+j] += x[i] * y[j]

标签: c


【解决方案1】:

扩展我的评论...

如果您将系数存储在数组中以使数组位置对应于指数,则管理系数会更轻松。例如,您将 3.0x<sup>2</sup> - 2.0x + 1.0 表示为

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

因此,2 次多项式需要 3 元素数组,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】:

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

    // 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 之类的工具将帮助您了解是否存在内存泄漏。

    【讨论】:

      【解决方案3】:

      你有两个选择:

      • 进行第二次遍历(例如,按系数排序),并以相同的幂合并系数。
      • 像在纸上那样做乘法,计算各列的总和(可以是滚动总和)。最简单的方法是先实现加法。

      【讨论】:

        猜你喜欢
        • 2019-04-26
        • 2013-08-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多