Data_Structure/作業/老師解答/unit2/poly-integer-root-v1.c
2025-01-20 21:25:33 +08:00

88 lines
3.6 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
Program: poly-integer-root-v1.c (Report comments/bugs to chikh@yuntech.edu.tw)
Function: 第二單元講義第21頁練習
Note: 針對多項式的表示方式本程式未採書本polynomial.c的方式導入Dummy本程式展示一個實作方式
不使用Dummy仍可有效運作供同學參考運用
*/
#include <stdio.h>
#include <stdlib.h> /* for malloc(), abs() */
#include <math.h> /* for pow() */
int findRoot(int p[], int q[]) /* p輸入的多項式q求得的整數根 */
{
int r, c = 0, i, j, k, sum;
int sign[2] = {1,-1};
if (p[2*p[0]]%p[2] != 0) return 0; /* 多項式的常數項若不能被最高階項的係數整除(譬如2x^2 - 3 = 0),則不存在整數解 */
r = abs(p[2*p[0]]/p[2]); /* r能遍除多項式係數的因數目的令最高階項的係數簡化為±1而常數項簡化為±r以利後續運算 */
for (i = 1; i <= r; i++) { /* 考慮r的所有因數i若i正好能令多項式函數為0則該因數i即為所求解之一 */
if (r%i != 0) continue; /* 此i無法整除ri不是r的因數故略過繼續考慮下一個i */
for (j = 0; j < 2; j++) { /* 導入此2回合的迴圈係因±i都可能是解j為0代表考慮+i的情境j為1代表考慮-i的情況 */
for (sum = 0, k = 1; k <= 2*p[0]; k+=2) /* 計算每一項的結果值(係數*x^指數)並累加到sum之中 */
sum += p[k+1]*(int)(pow(sign[j]*i,p[k])); /* ±i之值以sign[j]*i實現代入多項式內對應的項次求相應之值 */
if (sum == 0) q[c++] = sign[j]*i; /* bingo! 發現合乎條件的整數根將其寫入q陣列內 */
}
}
return c; /* 回傳解的個數 */
}
void show(int p[], int n, int mode) /* 輸入的p陣列可能描述多項式也可能代表整數根的內容將由mode區分差異化的處理方式 */
{
int i;
if (mode == 0) { /* mode為0代表p將被解讀為多項式之描述資訊將顯示該多項式 */
printf("方程式p(x)= ");
for (i = 1; i <= n; i += 2) {
if (abs(p[i+1])>1) /* 項係數不為±1 */
printf("%s%d",p[i+1]>1? "":"\b", p[i+1]); /* 若係數>1可直接顯示係數值若係數為負則游標倒退一格再顯示係數值(把前導的'+'號塗掉) */
else if (p[i+1]==-1) /* 項係數為-1 */
printf("\b-"); /* 游標倒退一格,隨後僅再顯示'-'號即可(前導的'+'號塗掉)(不需顯示為'-1') */
/* 項係數若為1則不用額外動作保留前導的'+',毋需另作更動 */
switch(p[i]) { /* switch架構處理每個項次內指數的部分 */
case 0: /* 該項指數為0意為常數項不需顯示x^0故僅顯示'+'號,為下一項的輸出作準備 */
printf("+");
break;
case 1:
printf("x+"); /* 該項指數為1不需顯示x^1故僅顯示'x+',為下一項的輸出作準備 */
break;
default:
printf("x^%d+",p[i]); /* 顯示x^n+形式,為下一項的輸出作準備 */
}
}
printf("\b "); /* 最後多餘的'+'號以空白塗掉 */
}
else { /* mode為1代表p將被解讀為多項式之根將顯示根的內容 */
for (i = 0; i < n; i++) printf("%d、",p[i]); /* 每秀出一個根,之後另顯示頓號 */
if (n > 0) printf("\b\b "); /* 最後顯示多餘的頓號以游標倒退二格的方式改以空白塗掉 */
}
}
int main()
{
int p[] = {4,3,1,2,-2,1,-1,0,2};
//int p[] = {4,3,3,2,-6,1,-3,0,6};
//int p[] = {2,2,1,0,-100};
//int p[] = {4,3,1,2,-7,1,4,0,12};
//int p[] = {5,4,1,3,3,2,-66,1,52,0,120};
//int p[] = {5,4,3,3,9,2,-198,1,156,0,360};
int c, *q = (int *)malloc(p[1]*sizeof(int)); /* p[1]紀錄最高階項之指數,依此值創建足夠元素空間的陣列存放所求得的整數根 */
/* c: 求得的整數根的個數將紀錄findRoot()回傳的根個數;
q: 存放求得根所用陣列根的個數最多與多項式最高階項之指數相同以p的屬性動態配置所需記憶體空間 */
printf("\n*** 解多項式之整數根 ***\n\n");
show(p,2*p[0],0); /* 秀出以p描述的多項式2*p[0]代表描述非零項所用的數值個數第三引數0為輸出模式(詳見底下show()的定義) */
c = findRoot(p,q); /* 執行求根程序輸入p所描述的多項式q將紀錄求得的根findRoot()回傳符合的根個數 */
if (c > 0) {
printf("\n\n解得整數根為:");
show(q,c,1); /* 秀出q的內容c為根的個數第三引數1代表呼叫show()運行所需的工作模式 */
}
else
printf("\n\n整數根不存在\n");
free(q);
return 0;
}