数据结构实验一:多项式乘法问题
生活随笔
收集整理的這篇文章主要介紹了
数据结构实验一:多项式乘法问题
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Exp01 多項式乘法問題
Author: Maskros
實驗目的
設計一個一元稀疏多項式簡單計算器
實驗內容與要求
一元稀疏多項式簡單計算器的基本功能是:
(1)輸入并建立多項式。
(2)輸出多項式,輸出形式為整數序列:n,c1,e1,c2,e2,...,cn,enn,c_1,e_1,c_2,e_2,...,c_n,e_nn,c1?,e1?,c2?,e2?,...,cn?,en?, 其中 nnn 是多項式的項數,cic_ici? 和 eie_iei? 分別是第 iii 項的系數和指數,序列按指數 降序排列。
(3)多項式 aaa 與多項式 bbb 相乘,建立多項式。
實驗內容和實驗步驟
在這里我們分別通過順序表和鏈表兩種方法來實現實驗要求
- 大體思路:
- 鏈表 O(N2)O(N^2)O(N2):
- 結構體Pol存儲多項式每項的系數和指數
- CreatePol(Pol *&head)函數用于接收輸入的多項式元素,創建一個多項式
- PrintPol(Pol *&head)函數用于打印多項式
- MultiPol(Pol *&a, Pol *&b, Pol *&c)函數用于實現多項式的乘法,每次插入一項順序遍歷新鏈表 ,按指數升序插入或合并,最后得到以 *c為頭結點的鏈表,即所求結果
- Getlength(Pol &pol)函數遍歷鏈表返回多項式的項數,用于打印時使用
- ps:計算出來是空項的判斷依據為 pol->c=0 , 故在輸出和計算長度時將其直接忽略
- 順序表 O((logN)2)O((logN)^2)O((logN)2):
- 使用定義的map類型 typedef map<int, int> Pol存儲多項式每項的系數和指數, key為指數,value為系數,map.size()為多項式項數
- create()函數用于接收輸入的多項式元素,創建一個多項式
- print(Pol &pol)函數用于打印多項式
- multi(Pol &p1, Pol &p2)函數用于實現多項式的乘法,完成合并后,返回一個Pol類型的多項式
- 使用map的好處:由于map遍歷的特性,不用再次從小到大排序,并且易于查找和合并同類項
- 鏈表 O(N2)O(N^2)O(N2):
- 輸入形式:兩個多項式,兩個整數序列 n,c1,e1,c2,e2,...,cn,enn,c_1,e_1,c_2,e_2,...,c_n,e_nn,c1?,e1?,c2?,e2?,...,cn?,en?, 其中 nnn 是多項式的項數,cic_ici? 和 eie_iei? 分別是第 iii 項的系數和指數,序列按指數 降序排列
- 輸出形式:一個整數序列 n,c1,e1,c2,e2,...,cn,enn,c_1,e_1,c_2,e_2,...,c_n,e_nn,c1?,e1?,c2?,e2?,...,cn?,en?,標號規則同上
鏈表實現
//presented by Maskros - 2021/03/31 #include<bits/stdc++.h> using namespace std; struct Pol{int c; //coefficientint e; //exponentPol *next; }; int Getlength(Pol *&head){ //Calculate the number of terms in a polynomialif(head==NULL) {cout<<"NO_ELEM_ERROR"<<endl; return 0;}Pol *p=head;int cnt=0;while(p->next!=NULL){p=p->next;if(p->c==0) cnt--; //Empty items are not included in the countcnt++;}return cnt; }void CreatePol(Pol *&head){ //Create a polynomial//initializationhead=(Pol *) new Pol;head->c=0;head->e=0;head->next=NULL;Pol *pol=head;int n; cin>>n;for(int i=1;i<=n;i++){pol->next=(Pol *) new Pol; pol=pol->next;cin>>pol->c>>pol->e;pol->next=NULL;}return; } void PrintPol(Pol *&head){ //Print polynomial Pol *p=head;int n=Getlength(p);cout<<n<<" ";while(p->next!=NULL){p=p->next;if(p->c!=0) cout<<p->c<<" "<<p->e<<" "; //Do not print empty items}return; } void MultiPol(Pol *&a, Pol *&b, Pol *&c){ //Polynomial multiplicationPol *p1=a, *p2=b;int tmpc,tmpe;bool t; //Check if the item has been insertedc=(Pol *) new Pol;c->c=0; c->e=0; c->next=NULL; //initializationPol *p3,*pre; //$pre$ is the node before the current positionwhile(p1->next!=NULL){p1=p1->next;p2=b;while(p2->next!=NULL){p2=p2->next;t=false;tmpc=p1->c*p2->c;tmpe=p1->e+p2->e;p3=c;pre=c;while(p3->next!=NULL){ p3=p3->next;if(p3->e>tmpe){ //The insertion position is before the current positionpre->next=(Pol *)new Pol;pre=pre->next;pre->e=tmpe;pre->c=tmpc;pre->next=p3;t=true;}else if(p3->e==tmpe){ //Combine similar items at current locationp3->c+=tmpc;t=true;}else if(p3->next!=NULL && p3->e<tmpe && p3->next->e>tmpe){ //The insertion position is after the current positionpre=p3->next;p3->next=(Pol *)new Pol;p3=p3->next;p3->e=tmpe;p3->c=tmpc;p3->next=pre;t=true;}if(t==true) break;pre=p3;}if(t==false){ //Insertion position is at the end of the linked listp3->next=(Pol *)new Pol;p3=p3->next;p3->e=tmpe;p3->c=tmpc;p3->next=NULL;}}}return ; } int main(){Pol *p1,*p2,*p3;p1=NULL,p2=NULL,p3=NULL;CreatePol(p1);CreatePol(p2);MultiPol(p1,p2,p3);PrintPol(p3);return 0; }順序表實現
//presented by Maskros - 2021/03/31 #include<bits/stdc++.h> using namespace std; typedef map<int, int> Pol; Pol p1,p2,p3; void create(Pol &pol){ //Create a polynomialint co,ex,n;cin>>n;for(int i=1;i<=n;i++){cin>>co>>ex;pol[ex]+=co; } } void print(Pol &pol){ //Print polynomialmap<int,int>::iterator it;cout<<pol.size()<<" ";for(it=pol.begin();it!=pol.end();it++){cout<<it->second<<" "<<it->first<<" "; } } Pol multi(Pol &p1, Pol &p2){ //Polynomial multiplicationPol p3;map<int,int>::iterator it1,it2;for(it1=p1.begin();it1!=p1.end();it1++){for(it2=p2.begin();it2!=p2.end();it2++){p3[it1->first+it2->first]+=it1->second*it2->second; //Insert p3 after multiplying directlyif(p3[it1->first+it2->first]==0) p3.erase(it1->first+it2->first); //Delete extra items}}return p3; } int main(){create(p1);create(p2);p3=multi(p1,p2);print(p3);return 0; }實驗用測試數據和相關結果分析
INPUT1: 2 1 2 3 4 3 1 3 1 5 2 6 OUTPUT1: 5 1 5 4 7 2 8 3 9 6 10INPUT2: 3 2 0 3 2 4 3 3 -1 0 1 1 4 3 OUTPUT2: 7 -2 0 2 1 -3 2 7 3 4 4 12 5 16 6IUPUT3: 3 -1 -1 1 0 1 1 2 2 -2 3 2 OUTPUT3: 6 -2 -3 2 -2 2 -1 -3 1 3 2 3 3INPUT4: 2 1 0 1 1 2 -1 0 1 1 OUTPUT4: 2 -1 0 1 2- 結果分析:由此可見,無論是錯序合并,系數、項數取正、負、零,以及結果出現零項的處理均可實現,輸出正確答案
實驗總結
- 鏈表寫起來比較基礎,對于插入、遍歷、刪除等操作無法取巧,包括在計算多項式的長度時都需要遍歷,只能扎扎實實來寫,排序的工作在插入的時候直接就按照順序插入來完成,如果數據量比較大的話感覺時間復雜度有點高,所以有點小麻煩,但是感覺寫下來一趟,強化了我對于指針、地址、空間等方面的理解,寫起來也沒有之前那么生疏了
- 順序表一開始打算用 struct 型的 vector 來存,然后直接插入,最后再sort()一下方便排序,結果在相同項合并的操作上發現還是需要像鏈表一樣遍歷去查找位置,所以感覺有點麻煩,本來寫好了就全刪了,換了一種思路,用 map 來實現
式的長度時都需要遍歷,只能扎扎實實來寫,排序的工作在插入的時候直接就按照順序插入來完成,如果數據量比較大的話感覺時間復雜度有點高,所以有點小麻煩,但是感覺寫下來一趟,強化了我對于指針、地址、空間等方面的理解,寫起來也沒有之前那么生疏了 - 順序表一開始打算用 struct 型的 vector 來存,然后直接插入,最后再sort()一下方便排序,結果在相同項合并的操作上發現還是需要像鏈表一樣遍歷去查找位置,所以感覺有點麻煩,本來寫好了就全刪了,換了一種思路,用 map 來實現
- 用 map 太爽了,30來行就完事了,不用手動排序,查找合并也很方便,除了加了一個空項的erase()刪除工作,基本上沒什么坑,遍歷也很舒服,stl永遠滴神
總結
以上是生活随笔為你收集整理的数据结构实验一:多项式乘法问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用python做频数分析_Python统
- 下一篇: 反向题在测试问卷信效度_问卷信效度分析