順序表與連結串列實現多項式的加減乘與冪微分
阿新 • • 發佈:2020-10-10
1.連結串列實現
分為三個檔案進行編寫,分別為自定義標頭檔案,實現的cpp檔案與main主程式檔案.
整個過程中在實現乘的函式MutiplePoly和展示的Display函式上遇到較大困難.
1)MutiplePoly:由於一開始便預設資料是按低階到高階的,在設計乘演算法時強迫自己儘量不使用雙迴圈來計算.關鍵在於找到相乘後同階的所有項並相加,,故將兩個連結串列各迴圈一遍存入兩個陣列中方便訪問.在將兩個多項式各個係數相乘的結果規律排列成矩陣後,發現相乘後的階數規律排列.
如兩個陣列大小分別為4,3.則下標分別為0,1,2,3與0,1,2,相乘後係數相加得到如下矩陣:
0 | 1 | 2 | 3 |
1 | 2 | 3 | 4 |
2 | 3 | 4 | 5 |
矩陣中相同數字代表的項階數相同,則按斜線劃分成6層,大迴圈從0層開始遍歷到頂層.則計算可分為兩部分,一部分層數0~2,a[i]+b[j],i+j=當前層數,當j<0時跳出小迴圈.另一部分3~5,當i>3時跳出小迴圈.通過小迴圈將相同階數的係數全部相加.
2)Display:展示多項式的實現過程主要在於細節的繁多,如首項若為正項則不加符號,若為0則不顯示,非首項若為0則不顯示,為正項要新增正號等等.也因為這樣最後的實現體跳轉較多,程式碼顯得繁瑣.
順序表實現雖然用的是vector,但基本也符合順序表的定義,實現過程與連結串列相差無幾.故不多贅述.
最後附上完整連結串列實現程式碼:
標頭檔案:
#ifndef __POLY_H__ #define __POLY_H__ #include <iostream> #include <vector> using namespace std; // 儲存係數的結構體,採用雙鏈表結構 typedef struct data { int coefficient; struct data *next; struct data *pre; } Data; typedef Data *PtrToNode; // 儲存連結串列首末位置的結構體 typedef struct upper { PtrToNode head; PtrToNode end;int items; } list; //宣告連結串列 typedef list *List; void InitList(List &); //初始化連結串列 void Add(List &); //新增資料 void AddNode(List &); //新增節點 void GetInfo(List &); //輸入資料 void Calculate(List &); //運用霍納法則進行計算 void AddPoly(List &, List &, List &); //將兩個多項式相加 void SubtractPoly(List &, List &, List &); //將兩個多項式相減 void MutiplePoly(List &, List &, List &); //將兩個多項式相乘 // void DividePoly(List &, List &, List &); void Differential(List &); void Clear(List &); //清空列表 void Reset(List &, List &); //重新輸入兩個多項式 void menu1(); //展示選單1 void menu2(); //展示選單2 void Display(List &); //展示多項式 void ListToArray(List &, List &, vector<int> &, vector<int> &); //將連結串列資料轉化為陣列儲存 void DeleteHead(List &); //刪除首節點 #endif
實現檔案:
#include "poly.h" //給多項式新增資訊 void Add(List &l) { int num; cout << "Enter the number of terms:" << endl; cin >> num; cout << "Enter the coefficients in ascending power:" << endl; //提醒使用者以冪次的升序輸入係數 for (int i = 0; i < num; i++) { AddNode(l); GetInfo(l); } } // 初始化連結串列 void InitList(List &l) { l = (List) new list; l->head = NULL; l->end = NULL; l->items = 0; } //多項式相加 void AddPoly(List &l1, List &l2, List &l3) { PtrToNode cur1 = l1->head; PtrToNode cur2 = l2->head; while (cur1 != NULL || cur2 != NULL) { AddNode(l3); if (cur1 != NULL && cur2 != NULL) { l3->end->coefficient = cur1->coefficient + cur2->coefficient; cur1 = cur1->next; cur2 = cur2->next; } else if (cur1 == NULL) //處理多項式項數不同的情況 { l3->end->coefficient = cur2->coefficient; cur2 = cur2->next; } else { l3->end->coefficient = cur1->coefficient; cur1 = cur1->next; } } Display(l3); } // 多項式相減 void SubtractPoly(List &l1, List &l2, List &l3) { PtrToNode cur1 = l1->head; PtrToNode cur2 = l2->head; while (cur1 != NULL || cur2 != NULL) { AddNode(l3); if (cur1 != NULL && cur2 != NULL) { l3->end->coefficient = cur1->coefficient - cur2->coefficient; cur1 = cur1->next; cur2 = cur2->next; } else if (cur1 == NULL) { l3->end->coefficient = -cur2->coefficient; cur2 = cur2->next; } else { l3->end->coefficient = cur1->coefficient; cur1 = cur1->next; } } Display(l3); } void MutiplePoly(List &l1, List &l2, List &l3) { vector<int> a1; vector<int> a2; ListToArray(l1, l2, a1, a2); //根據冪次相加後形成的規律矩陣查詢每個冪次對應的項並相加,最後賦值 int top = (l1->items + l2->items - 2); int floor = 0; //冪次為0開始 int border = a2.size() - 1; int sum = 0; //儲存每個冪次對應的係數 while (floor <= top) { AddNode(l3); if (floor <= border) for (int i = 0, j = floor - i; j >= 0; i++, j--) { sum += a1[i] * a2[j]; l3->end->coefficient = sum; } else for (int j = border, i = floor - j; i < a1.size() && j >= 0; i++, j--) { sum += a1[i] * a2[j]; l3->end->coefficient = sum; } sum = 0; floor++; } Display(l3); } // 求一階導 void Differential(List &l) { DeleteHead(l); int time = 1; PtrToNode cur = l->head; while (cur != NULL) { cur->coefficient *= time; cur = cur->next; time++; } Display(l); } void Calculate(List &l) { //獲得x值 int x; cout << "Enter the value of x:" << endl; cin >> x; PtrToNode cur = l->end; //按照霍納法則從後往前遍歷 int poly = 0; while (cur != NULL) { poly = x * poly + cur->coefficient; //將多項式進行拆分成相乘形式 cur = cur->pre; } cout << "The result is " << poly << endl; } //兩個選單 void menu1() { cout << "Choose one to execute:" << endl; cout << "a)Add\nb)Subtract\nc)Mutiply" << endl; } void menu2() { cout << "Choose one to execute:" << endl; cout << "a)Calculate\nb)Retype the two polynomials\nc)Differential\nq)quit" << endl; } //獲得係數 void GetInfo(List &l) { cin >> l->end->coefficient; } void AddNode(List &l) { PtrToNode newNode = (PtrToNode) new Data; newNode->next = NULL; newNode->pre = l->end; if (l->head == NULL) { l->head = newNode; l->end = newNode; } else { l->end->next = newNode; l->end = newNode; } l->items++; } //清除結果 void Clear(List &l) { PtrToNode cur = l->head; PtrToNode temp; while (cur != NULL) { temp = cur->next; free(cur); cur = temp; } l->head = NULL; l->end = NULL; l->items = 0; } //重設l1,l2 void Reset(List &l1, List &l2) { Clear(l1); Clear(l2); Add(l1); Add(l2); } //將多項式以字串形式展示 void Display(List &l) { string polynomial; PtrToNode cur = l->head; if (l->items == 0) polynomial.append("0"); else //遍歷以確定係數是否全為0 { int cnt = 0; while (cur != NULL) { if (cur->coefficient == 0) cnt++; cur = cur->next; } if (cnt == l->items) { polynomial.append("0"); cout << polynomial << endl; return; } } //通過不斷將係數與符號append到string中從而展示 int time = 0; //記錄冪的次數 cur = l->head; while (cur != NULL) { if (cur == l->head) { if (cur->coefficient != 0) polynomial.append(to_string(cur->coefficient)); cur = cur->next; time++; continue; } else { if (cur->coefficient > 0) polynomial.append("+"); else if (cur->coefficient < 0) polynomial.append("-"); else //係數為零則跳過不顯示 { cur = cur->next; time++; continue; } polynomial.append(to_string(abs(cur->coefficient))); polynomial.append("x^"); polynomial.append(to_string(time)); time++; cur = cur->next; } } cout << polynomial << endl; } // 將連結串列儲存到陣列當中方便訪問 void ListToArray(List &l1, List &l2, vector<int> &a1, vector<int> &a2) { PtrToNode p1 = l1->head; PtrToNode p2 = l2->head; //通過if,else語句讓a1.a2分別固定儲存長多項式於短多項式 if (l1->items > l2->items) { while (p1 != NULL) { a1.push_back(p1->coefficient); p1 = p1->next; } while (p2 != NULL) { a2.push_back(p2->coefficient); p2 = p2->next; } } else { while (p1 != NULL) { a2.push_back(p1->coefficient); p1 = p1->next; } while (p2 != NULL) { a1.push_back(p2->coefficient); p2 = p2->next; } } } // 刪除第一個節點 void DeleteHead(List &l) { PtrToNode temp = l->head; if (l->items > 1) //項數大於1的情況 l->head->next->pre = NULL; l->head = l->head->next; delete temp; l->items--; }
主程式檔案:
#include "poly.h" int main(void) { List l1;//第一個多項式 List l2;//第二個多項式 List l3;//操作之後的多項式 char option; //初始化三個連結串列 InitList(l1); InitList(l2); InitList(l3); //輸入多項式 Add(l1); Add(l2); do { menu1(); cin >> option; switch (option) { case 'a': AddPoly(l1, l2, l3); break; case 'b': SubtractPoly(l1, l2, l3); break; case 'c': MutiplePoly(l1, l2, l3); break; case 'd': // DividePoly(l1, l2, l3); break; default: cout << "Invalid input" << endl; continue; } menu2(); cin >> option; switch (option) { case 'a': Calculate(l3); break; case 'b': Reset(l1, l2); break; case 'c': Differential(l3); break; case 'q': break; default: cout << "Invalid input" << endl; break; } Clear(l3); } while (option != 'q'); }