1. 程式人生 > >小白專場-多項式乘法與加法運算-c語言實現

小白專場-多項式乘法與加法運算-c語言實現

目錄

  • 一、題意理解
  • 二、求解思路
  • 三、多項式的表示
    • 3.1 陣列
    • 3.2 連結串列
  • 四、程式框架搭建
  • 五、如何讀入多項式
  • 六、如何將兩個多項式相加
  • 七、如何將兩個多項式相乘
  • 八、如何將多項式輸出

一、題意理解

設計函式分別求兩個一元多項式的乘積與和,例:
\[ \text{已知以下兩個多項式:} \\ \begin{align} & 3x^4-5x^2+6x-2 \\ & 5x^{20}-7x^4+3x \end{align} \]

\[ \text{多項式和為:} \\ \begin{align} 5x^{20}-4x^4-5x^2+9x-2 \end{align} \]

假設多項式的乘積為\((a+b)(c+d)=ac+ad+bc+bd\),則多項式的乘積如下:
\[ \begin{align} 15x^{24}-25x^{22}+30x^{21}-10x^{20}-21x^8+35x^6-33x^5+14x^4-15x^3+18x^2-6x \end{align} \]
通過上述題意理解,我們可以設計函式分別求兩個一元多項式的乘積與和。

輸入樣例:
\[ \begin{align} & 3x^4-5x^2+6x-2 \quad --> \quad \text{4個}\,3\,4\,-5\,2\,6\,1\,-2\,0 \\ & 5x^{20}-7x^4+3x \quad --> \quad \text{3個}\,5\,20\,-7\,4\,3\,1 \\ \end{align} \\ \]

輸出樣例:
\[ \begin{align} & 15x^{24}-25x^{22}+30x^{21}-10x^{20}-21x^8+35x^6-33x^5+14x^4-15x^3+18x^2-6x \\ & 15 \, 24 \, -25 \, 22 \, 30 \, 21 \, -10 \, 20 \, -21 \, 8 \, 35 \, 6 \, -33 \, 5 \, 14 \, 4 \, -15 \, 3 \, 18 \, 2 \, -6 \, 1 \, 5 \, 20 \, -4 \, 4 \, -5 \, 2 \, 9 \, 1 \, -2 \, 0 \end{align} \]

二、求解思路

  1. 多項式表示
  2. 程式框架
  3. 讀多項式
  4. 加法實現
  5. 乘法實現
  6. 多項式輸出

三、多項式的表示

僅表示非零項

3.1 陣列

優點:程式設計簡單、除錯簡單

缺點:需要事先確定陣列大小

一種比較好的實現方法是:動態陣列(動態更改陣列的大小)

3.2 連結串列

優點:動態性強

缺點:程式設計略為複雜、除錯比較困難

資料結構設計:

/* c語言實現 */

typedef struct PolyNode *Polynomial;
struct PolyNode{
  int coef;
  int expon;
  Polynomial link;
}

四、程式框架搭建

/* c語言實現 */

int main()
{
  讀入多項式1;
  讀入多項式2;
  乘法運算並輸出;
  加法運算並輸出;
  return 0;
}

int main()
{
  Polynomial P1, P2, PP, PS;
  
  P1 = ReadPoly();
  P2 = ReadPoly();
  PP = Mult(P1, P2);
  PrintPoly(PP);
  PS = Add(P1, P2);
  PrintPoly(PS);
  
  return 0;
}

需要設計的函式:

  • 讀一個多項式
  • 兩多項式相乘
  • 兩多項式相加
  • 多項式輸出

五、如何讀入多項式

/* c語言實現 */

Polynomial ReadPoly()
{
  ...;
  scanf("%d", &N);
  ...;
  while (N--) {
    scanf("%d %d", &c, &e);
    Attach(c, e, &Rear);
  }
  ...;
  return P;
}

Rear初值是多少?

兩種處理方法:

  1. Rear初值為NULL:在Attach函式中根據Rear是否為NULL做不同處理

  1. Rear指向一個空結點

/* c語言實現 */

void Attach(int c, int e, Polynomial *pRear)
{
  Polynomial P;
  
  P = (Polynomial)malloc(sizeof(struct PolyNode));
  p->coef = c; /* 對新結點賦值 */
  p->expon = e;
  p->link = NULL;
  (*pRear)->link = P;
  (*pRear) = P; /* 修改pRear值 */

/* c語言實現 */

Polynomial ReadPoly()
{
  Polynomial P, Rear, t;
  int c, e, N;
  
  scanf("%d", &N);
  P = (Polynomial)malloc(sizeof(struct PolyNode)); // 連結串列頭空結點
  P->link = NULL;
  Rear = P;
  while (N--) {
    scanf("%d %d", &c, &e);
    Attach(c, e, &Rear); // 將當前項插入多項式尾部
  }
  t = P; P = P->link; free(t); // 刪除臨時生成的頭結點
  return P;
}

六、如何將兩個多項式相加

/* c語言實現 */

Polynomial Add(Polynomial P1, Polynomial P2)
{
  ...;
  t1 = P1; t2 = P2;
  P = (Polynomial)malloc(sizeof(struct PolyNode));
  P->link = NULL;
  Rear = P;
  while (t1 && t2){
    if (t1->expon == t2->expon){
      ...;
    }
    else if (t1->expon > t2->expon){
      ...;
    }
    else{
      ...;
    }
  }
  while (t1){
    ...;
  }
  while (t2){
    ...;
  }
  ...;
  return P;
}

七、如何將兩個多項式相乘

方法:

  1. 將乘法運算轉換為加法運算

將P1當前項(ci, ei)乘P2多項式,再加到結果多項式裡

/* c語言實現 */

t1 = P1; t2 = P2;
P = (Polynomial)malloc(sizeof(struct PolyNode)); P->link = NULL;
Rear = P;
while (t2){
  Attach(t1->coef * t2->coef, t1->expon + t2->expon, &Rear);
  t2 = t2->link;
}
  1. 逐項插入

將P1當前項(c1_i, e1_i)乘P2當前項(c2_i, e2_i),並插入到結果多項式中。關鍵是要找到插入位置

初始結果多項式可由P1第一項乘P2獲得(如上)

/* c語言實現 */

Polynomial Mult(Polynomial P1, Polynomial P2)
{
  ...;
  t1 = P1; t2 = P2;
  ...;
  while (t2){ // 先用P1的第一項乘以P2,得到P
    ...;
  }
  t1 = t1->link;
  while (t1){
    t2 = P2; Rear = P;
    while (t2){
      e = t1->expon + t2->expon;
      c = t1->coef * t2->coef;
      ...;
      t2 = t2->link;
    }
    t1 = t1->link;
  }
  ...;
}
/* c語言實現 */

Polynomial Mult(Polynomial P1, Polynomial P2)
{
  Polynomial P, Rear, t1, t2, t;
  int c, e;
  
  if (!P1 || !P2) return NULL;
  
  t1 = P1; t2 = P2;
  P = (Polynomial)malloc(sizeof(struct PolyNOde)); P->link = NULL;
  Rear = P;
  while (t2){ // 先用P1的第一項乘以P2,得到P
    Attach(t1->coef * t2->coef, t1->expon + t2->expon, &Rear);
    t2 = t2->link;
  }

  t1 = t1->link;
  while (t1){
    t2 = P2; Rear = P;
    while (t2){
      e = t1->expon + t2->expon;
      c = t1->coef * t2->coef;
      ...;
      t2 = t2->link;
    }
    t1 = t1->link;
  }
  ...;
}

/* c語言實現 */

Polynomial Mult(Polynomial P1, Polynomial P2)
{
  Polynomial P, Rear, t1, t2, t;
  int c, e;
  
  if (!P1 || !P2) return NULL;
  
  t1 = P1; t2 = P2;
  P = (Polynomial)malloc(sizeof(struct PolyNOde)); P->link = NULL;
  Rear = P;
  while (t2){ // 先用P1的第一項乘以P2,得到P
    Attach(t1->coef * t2->coef, t1->expon + t2->expon, &Rear);
    t2 = t2->link;
  }

  t1 = t1->link;
  while (t1) {
    t2 = P2; Rear = P;
    while (t2) {
      e = t1->expon + t2->expon;
      c = t2->coef * t2->coef;
      while (Rear->link && Rear->link->expon > e)
        Rear = Rear->link;
      if (Rear->link && Rear->link->expon == e){
        ...;
      }
      else{
        ...;
      }
      t2 = t2->link;
    }
    t1 = t1->link;
  }
  ...;
}

/* c語言實現 */

Polynomial Mult(Polynomial P1, Polynomial P2)
{
  Polynomial P, Rear, t1, t2, t;
  int c, e;
  
  if (!P1 || !P2) return NULL;
  
  t1 = P1; t2 = P2;
  P = (Polynomial)malloc(sizeof(struct PolyNOde)); P->link = NULL;
  Rear = P;
  while (t2){ // 先用P1的第一項乘以P2,得到P
    Attach(t1->coef * t2->coef, t1->expon + t2->expon, &Rear);
    t2 = t2->link;
  }

  t1 = t1->link;
  while (t1) {
    t2 = P2; Rear = P;
    while (t2) {
      e = t1->expon + t2->expon;
      c = t2->coef * t2->coef;
      while (Rear->link && Rear->link->expon > e)
        Rear = Rear->link;
      if (Rear->link && Rear->link->expon == e){
        if (Rear->link->coef + c)
          Rear->link->coef += c;
        else{
          t = Rear->link;
          Rear->link = t->link;
          free(t);
        }
      }
      else{
        t = (Polynomial)malloc(sizeof(struct PolyNode));
        t->coef = c; t->expon = e;
        t->link = Rear->link;
        Rear->link = t; Rear = Rear->link;
      }
      t2 = t2->link;
    }
    t1 = t1->link;
  }
  ...;
}

/* c語言實現 */

Polynomial Mult(Polynomial P1, Polynomial P2)
{
  Polynomial P, Rear, t1, t2, t;
  int c, e;
  
  if (!P1 || !P2) return NULL;
  
  t1 = P1; t2 = P2;
  P = (Polynomial)malloc(sizeof(struct PolyNOde)); P->link = NULL;
  Rear = P;
  while (t2){ // 先用P1的第一項乘以P2,得到P
    Attach(t1->coef * t2->coef, t1->expon + t2->expon, &Rear);
    t2 = t2->link;
  }

  t1 = t1->link;
  while (t1) {
    t2 = P2; Rear = P;
    while (t2) {
      e = t1->expon + t2->expon;
      c = t2->coef * t2->coef;
      while (Rear->link && Rear->link->expon > e)
        Rear = Rear->link;
      if (Rear->link && Rear->link->expon == e){
        if (Rear->link->coef + c)
          Rear->link->coef += c;
        else{
          t = Rear->link;
          Rear->link = t->link;
          free(t);
        }
      }
      else{
        t = (Polynomial)malloc(sizeof(struct PolyNode));
        t->coef = c; t->expon = e;
        t->link = Rear->link;
        Rear->link = t; Rear = Rear->link;
      }
      t2 = t2->link;
    }
    t1 = t1->link;
  }
  t2 = P; P = P->link; free(t2);
  return P;
}

八、如何將多項式輸出

/* c語言實現 */

void PrintPoly(Polynomial P)
{
  // 輸出多項式
  int flag = 0;  // 輔助調整輸出格式用,判斷輸出加法還是乘法
  
  if (!P) {printf("0 0\n"); return ;}
  
  while (P) {
    if (!flag)
      flag = 1;
    else
      printf(" ");
    printf("%d %d", P->coef, P->expon);
    P = P->link;
  }
  printf("\n");
}