多项式乘法问题
多項式乘法問題
實驗目的:設計一個一元稀疏多項式簡單計算器。
實驗內容與要求:
一元稀疏多項式簡單計算器的基本功能是:
(1)輸入并建立多項式;
(2)輸出多項式,序列按指數降序排列。
(3)多項式a與多項式b相乘,建立多項式。
實驗內容和實驗步驟:
概覽:
輸入:a項的項數以及分別輸入每項的系數和指數,可以不按指數的大小亂序輸入,可以輸入多項帶有相同指數的項(程序會將其自動累加);項數c是float型(輸出時保留一位小數),指數e是int型。
輸出:相乘的結果。結果按指數的大小降序排列,其中的項的系數若是負號,則不輸出加號,系數為0的項刪除,指數為1的項只輸出該項系數而不輸出x。題目要求的輸出太過簡略,而本程序輸出比題目要求更加直觀易懂,但實現起來更為復雜,下面再來討論。
設計概要:
從主函數進入后,先初始化鏈表。再依次用循環輸入數據并以此建立a、b兩個鏈表。每建立一個鏈表,用check函數檢查并刪掉多余項,最后用multiple函數求積(內置check函數刪掉多余項),通過toString函數輸出答案。
本程序采用鏈表實現:鏈表單元是PNode;cmp用來比較排序(用于insertList);insertList用來輸入多項式(按照指數的降序順序排列);checkList用來遍歷檢查鏈表,若發現系數為0的項就將其剔除(用于運算操作之后),multiple用來實現乘法運算,toString用來打印多項式。
注:為了使輸入和輸出看起來更加舒服,toString輸出的格式更符合人們的習慣,比如:
x^2 - 2x^1 + 1
15.0x^3 + 16.0x^2 + 9.0x^1 + 2.0
以下是程序的詳細說明:
#include<iostream> using namespace std; typedef struct PNode { //定義鏈表中的節點float c; //系數int e; //指數struct PNode *next; }PNode, *PNodeList;void InitList(PNodeList &l) {//初始化鏈表函數,為鏈表加一個頭節點//頭節點只是指向作用,其系數指數均為0l = new PNode(); }int cmp(PNodeList a, PNodeList b) {return b->e - a->e; }void insertList(PNodeList &L, float c, int e) {//插入新節點,以指數的降序順序排列。int status = 1; //用來指示節點是否在中途插入,也可以用bool型變量來表示PNodeList p = L;PNodeList temp = new PNode(); //初始化要插入的節點temp->c = c;temp->e = e;while (p->next != NULL) {if (cmp(temp, p->next)<0) { //如果要插入的節點比后一個大,則將其插在后一個之前。temp->next = p->next;p->next = temp;status = 0;break;}else if(!cmp(temp, p->next)){ //如果要插入的節點等于后一個節點,則只改變后一個節點系數即可。p->next->c += c;status = 0;break;}p = p->next;}if (status) {//要插入的節點比所有的節點小。則放在鏈表最后即可。p->next = temp; } }//雙for循環遍歷兩表,將結果依次加入結果 void multiple(PNodeList a, PNodeList b, PNodeList c) {//用來檢查并刪掉系數為0的項PNodeList pa = a;PNodeList pb = b;if (pa->next == NULL || pb->next == NULL) return; //若a、b為0,則直接退出for (pa = a; pa->next != NULL;) {pa = pa->next;for (pb = b; pb->next != NULL;) {pb = pb->next;insertList(c, pa->c*pb->c, pa->e + pb->e);} void checkList(PNodeList c) {//用來檢查并刪掉系數為0的項PNodeList delete_node;while (c != NULL&&c->next != NULL) {//這里要考慮到兩種情況:末尾節點和非末尾節點if (c->next->c == 0) {delete_node = c->next;c->next = delete_node->next;delete[] delete_node;}c = c->next;} }void toString(PNodeList L) { //打印鏈表if (L->next == NULL) {printf("\n");}else {L = L->next;if(L->e==0)printf("%.1f", L->c);elseprintf("%.1fx^%d", L->c, L->e);L = L->next;while (L != NULL) {if (L->e == 0) {if (L->c > 0) printf(" +");printf(" %.1f", L->c);}else {if (L->c > 0) printf(" +");printf(" %.1fx^%d", L->c, L->e);}L = L->next;}}printf("\n"); }int main() {PNodeList a,b,c;InitList(a);InitList(b);InitList(c);int n1, n2;cout << "請輸入a表中的多項式項數:";cin >> n1;cout << "請依次輸入a表中的系數和指數:" << endl;for (int i = 0; i < n1; i++) {printf("第%d項的系數和指數分別是:",i + 1);float c;int e;cin >> c;cin >> e;insertList(a, c, e);}checkList(a);cout << "您輸入的a式是:" << endl;toString(a);cout << "請輸入b表中的多項式系數:";cin >> n2;cout << "請依次輸入b表中的系數和指數:" << endl;for (int i = 0; i < n2; i++) {printf("第%d項的系數和指數分別是:", i + 1);float c;int e;cin >> c;cin >> e;insertList(b, c, e);}checkList(b);cout << "您輸入的b式是:" << endl;toString(b);cout << "相乘的結果為:" << endl;multiple(a, b, c);toString(c);return 0; }實驗用測試數據和相關結果分析:
例如:
(輸入相同指數其的系數自動合并,輸入的項若系數相消為0,則將其刪去)
該程序的時間復雜度是O(N^2),因為在計算時有兩個for循環;
空間復雜度為O(N),因為只存在單向鏈表。
**實驗總結:**總的來說,本程序通過鏈表來實現了多項式的乘法運算(加法減法也是同理),其本質是利用了鏈表易于增刪改查以及容量可變的特性。在此基礎上,我優化了程序的輸入和輸出格式,使其更加簡單明了。
總結
- 上一篇: 嘉庆帝膝下五子,选择平庸的道光继位,道光
- 下一篇: php计算用户实际付的金额,复盘微信支付