原程式要求使用者按降冪序輸入多項式項(如 3x² + 2x + 1 須依序輸入 3,2 2,1 1,0),否則運算錯誤。需修改為任意順序輸入,程式自動排序後再運算。
typedef struct PolyTerm {
int coef; // 係數
int exp; // 指數
struct PolyTerm *next; // 下一項指標
} Term;
// 將新項插入多項式鏈結串列,保持指數降序
// 回傳新的頭節點指標(可能因插在頭部而改變)
Term* insert_term(Term *head, Term *new_term) {
if (!new_term) return head;
// 情況 1:空串列 或 新項指數 > 現有頭部指數 → 插在頭部
if (!head || new_term->exp > head->exp) {
new_term->next = head;
return new_term;
}
// 情況 2:遍歷尋找插入位置
Term *curr = head;
while (curr->next && curr->next->exp > new_term->exp) {
curr = curr->next;
}
// 檢查重複指數(同指數項應合併係數,這裡選擇拒絕重複輸入)
if (curr->next && curr->next->exp == new_term->exp) {
printf("錯誤:指數 %d 已存在,請合併係數後輸入。\n", new_term->exp);
free(new_term);
return head;
}
// 插入:新項接在 curr 之後
new_term->next = curr->next;
curr->next = new_term;
return head;
}
Term* create_poly() {
Term *head = NULL;
int coef, exp;
char cont = 'y';
printf("輸入多項式項 (係數,指數),如: 3 2 表示 3x^2\n");
while (cont == 'y' || cont == 'Y') {
printf("係數 指數: ");
if (scanf("%d %d", &coef, &exp) != 2) {
printf("輸入格式錯誤\n");
while (getchar() != '\n'); // 清緩衝區
continue;
}
if (coef == 0) {
printf("係數為 0 略過\n");
continue;
}
Term *new_term = (Term*)malloc(sizeof(Term));
new_term->coef = coef;
new_term->exp = exp;
new_term->next = NULL;
head = insert_term(head, new_term);
printf("繼續輸入? (y/n): ");
scanf(" %c", &cont); // 空格吃掉殘留換行
}
return head;
}
Term* poly_add(Term *a, Term *b) {
Term *result = NULL;
Term *tail = NULL;
while (a && b) {
Term *new_term = (Term*)malloc(sizeof(Term));
new_term->next = NULL;
if (a->exp == b->exp) {
new_term->exp = a->exp;
new_term->coef = a->coef + b->coef;
a = a->next;
b = b->next;
if (new_term->coef == 0) { // 係數抵銷為 0,不加入結果
free(new_term);
continue;
}
} else if (a->exp > b->exp) {
new_term->exp = a->exp;
new_term->coef = a->coef;
a = a->next;
} else { // b->exp > a->exp
new_term->exp = b->exp;
new_term->coef = b->coef;
b = b->next;
}
// 尾插法建立結果串列
if (!result) result = tail = new_term;
else { tail->next = new_term; tail = new_term; }
}
// 剩餘項直接接上(因已排序,直接連接即可)
Term *remaining = a ? a : b;
while (remaining) {
Term *new_term = (Term*)malloc(sizeof(Term));
new_term->coef = remaining->coef;
new_term->exp = remaining->exp;
new_term->next = NULL;
if (!result) result = tail = new_term;
else { tail->next = new_term; tail = new_term; }
remaining = remaining->next;
}
return result;
}
每一項與另一多項式所有項相乘,產生中間結果再合併同指數項。
Term* poly_multiply(Term *a, Term *b) {
Term *result = NULL;
for (Term *pa = a; pa; pa = pa->next) {
for (Term *pb = b; pb; pb = pb->next) {
int new_exp = pa->exp + pb->exp;
int new_coef = pa->coef * pb->coef;
// 將乘積項插入/合併到結果中
result = insert_or_merge(result, new_coef, new_exp);
}
}
return result;
}
// 輔助:插入或合併同指數項
Term* insert_or_merge(Term *head, int coef, int exp) {
if (coef == 0) return head;
// 找到指數位置
Term *pre = NULL;
Term *curr = head;
while (curr && curr->exp > exp) {
pre = curr;
curr = curr->next;
}
// 找到同指數 → 合併係數
if (curr && curr->exp == exp) {
curr->coef += coef;
if (curr->coef == 0) { // 係數歸零 → 刪除節點
if (pre) pre->next = curr->next;
else head = curr->next;
free(curr);
}
return head;
}
// 新指數 → 插入新節點
Term *new_term = (Term*)malloc(sizeof(Term));
new_term->coef = coef;
new_term->exp = exp;
new_term->next = curr;
if (pre) pre->next = new_term;
else head = new_term;
return head;
}
void print_poly(Term *head) {
if (!head) { printf("0\n"); return; }
Term *curr = head;
while (curr) {
printf("%dx^%d", curr->coef, curr->exp);
if (curr->next) printf(" + ");
curr = curr->next;
}
printf("\n");
}
void free_poly(Term *head) {
while (head) {
Term *tmp = head;
head = head->next;
free(tmp);
}
}
int main() {
printf("=== 多項式運算系統 ===\n");
printf("輸入第一個多項式:\n");
Term *poly1 = create_poly();
printf("\n輸入第二個多項式:\n");
Term *poly2 = create_poly();
printf("\n多項式 1: "); print_poly(poly1);
printf("多項式 2: "); print_poly(poly2);
Term *sum = poly_add(poly1, poly2);
printf("加法結果: "); print_poly(sum);
Term *product = poly_multiply(poly1, poly2);
printf("乘法結果: "); print_poly(product);
// 釋放所有記憶體
free_poly(poly1);
free_poly(poly2);
free_poly(sum);
free_poly(product);
return 0;
}
=== 多項式運算系統 === 輸入第一個多項式: 輸入多項式項 (係數,指數),如: 3 2 表示 3x^2 係數 指數: 2 3 繼續輸入? (y/n): y 係數 指數: 5 1 繼續輸入? (y/n): y 係數 指數: 1 0 繼續輸入? (y/n): n 輸入第二個多項式: 係數 指數: 3 2 繼續輸入? (y/n): y 係數 指數: -5 1 繼續輸入? (y/n): n 多項式 1: 2x^3 + 5x^1 + 1x^0 多項式 2: 3x^2 + -5x^1 加法結果: 2x^3 + 3x^2 + 0x^1 + 1x^0 乘法結果: 6x^5 + -10x^4 + 15x^3 + -25x^2 + 3x^1 + -5x^0
| 技術點 | 實作細節 |
|---|---|
| 有序插入 | O(n) 遍歷尋找位置,支援頭插、中插、尾插,自動維持降序 |
| 重複指數處理 | 輸入時拒絕、加法時合併、乘法時累加 |
| 零係數清理 | 係數歸零立即釋放節點,避免輸出 0x^n |
| 記憶體管理 | 每個 malloc 配對 free,主程式結束前釋放所有串列 |
| 指標操作 | 雙指標(pre/curr)遍歷、尾插法建立結果串列 |
double coef)