c++用模板实现稀疏多项式_用线性表实现一元多项式及相加运算
“?本文主要討論線性表在多項(xiàng)式計(jì)算中的應(yīng)用,討論內(nèi)容涉及到一元n次多項(xiàng)式在計(jì)算機(jī)中的表示,及多項(xiàng)式相加運(yùn)算。”
01
在數(shù)學(xué)上,一個(gè)一元n次多項(xiàng)式可以按照升冪寫成
Pn(x)= p0 + p1x + p2x2 + …… + pnxn
它由n+1個(gè)系數(shù)唯一確定。因此,一個(gè)一元n次多項(xiàng)式可以用一個(gè)線性表P來表示:
P = (p0,p1,p2,……,pn)
多項(xiàng)式每一項(xiàng)的指數(shù)隱含在線性表的序號(hào)里。假設(shè)Q是另外一個(gè)一元m次多項(xiàng)式,同樣也可以用線性表Q來表示
Q = (q0,q1,q2,q2,……,qm)
如果m
因此,多項(xiàng)式P和Q相加的結(jié)果可以用線性表R表示
R =(p0+ q0,p1+ q1,p2+ q2,……,pm+ qm,pm+1,……,pn)
由此可以看出,一元n次多項(xiàng)式在計(jì)算機(jī)中可以用線性表來表示,其加法運(yùn)算也可以在線性表的基礎(chǔ)上進(jìn)行。但在實(shí)際應(yīng)用中,多項(xiàng)式的次數(shù)可能很高并且變化很大時(shí),使得線性表最大長度很難確定,特別是在處理類似如下多項(xiàng)式時(shí)
T(x)= 12x2 + 2x12000+3x30000
雖然多項(xiàng)式只有3項(xiàng)非零元素,但仍然需要一個(gè)長度為30000的線性表來表示,造成對(duì)內(nèi)存空間的浪費(fèi)。在程序設(shè)計(jì)中,這種浪費(fèi)是應(yīng)當(dāng)避免的。可以考慮用線性表存儲(chǔ)多項(xiàng)式每項(xiàng)系數(shù)的同時(shí),也存儲(chǔ)相應(yīng)的指數(shù),這樣就可以不用存儲(chǔ)多項(xiàng)式的非零項(xiàng)了。
一般情況下,一元n次多項(xiàng)式也可以寫成
Pn(x)= p1xe1+ p2xe2 + …… + pmxem
其中,pi是指數(shù)為ei項(xiàng)的非零系數(shù),并且滿足
0<=e1< e2
因此,若用一個(gè)長度為m,且每個(gè)元素有兩個(gè)數(shù)據(jù)項(xiàng)(系數(shù)項(xiàng)和指數(shù)項(xiàng))的線性表,便可唯一確定多項(xiàng)式P(x)
P = ((p1,e1),(p1,e2),……,(pm,em))
上面的式子在每項(xiàng)都不為零的情況下,僅只比存儲(chǔ)每項(xiàng)系數(shù)的方案多存儲(chǔ)一倍的數(shù)據(jù)。但是對(duì)于T(x)類的多項(xiàng)式,這種表示將極大節(jié)省存儲(chǔ)空間。
用線性表存儲(chǔ)多項(xiàng)式可以采用兩種存儲(chǔ)結(jié)構(gòu),一種是順序存儲(chǔ)結(jié)構(gòu),一種是鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)。在實(shí)際應(yīng)用中,具體采用什么存儲(chǔ)結(jié)構(gòu),則要視作什么運(yùn)算而定。一般來說如果僅是求多項(xiàng)式值的運(yùn)算,宜采用順序存儲(chǔ)結(jié)構(gòu),當(dāng)需要修改多項(xiàng)式的系數(shù)和值時(shí)宜采用鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)。
例如??多項(xiàng)式
P(x)= 12 + 2x3+8x5+11x6
線性表的表示為
P = ((12,0),(2,3),(8,5),(11,6))
一元多項(xiàng)式相加的運(yùn)算規(guī)則非常簡單,兩個(gè)多項(xiàng)式中指數(shù)相同的項(xiàng)對(duì)應(yīng)系數(shù)相加,若相加的和不為零,則構(gòu)成相加結(jié)果多項(xiàng)式中的一項(xiàng),所有指數(shù)不相同的項(xiàng)均復(fù)制到相加結(jié)果多項(xiàng)式中。
02
下面用Java語言給出一元多項(xiàng)式表示及加法運(yùn)算案例。前面討論過,用線性表存儲(chǔ)多項(xiàng)式時(shí),宜采用系數(shù)項(xiàng)和指數(shù)項(xiàng)同時(shí)存儲(chǔ)的結(jié)構(gòu)。因此在案例中定義了PolyData類,用于存儲(chǔ)多項(xiàng)式的項(xiàng)數(shù)據(jù)。
package com.milihua.algorithm.lineartable;public class PolyData { /** * 多項(xiàng)式系數(shù)項(xiàng) */ public int coef; /** * 多項(xiàng)式指數(shù)項(xiàng) */ public int expn; /** * 多項(xiàng)式項(xiàng)構(gòu)造函數(shù) */ PolyData(int coef,int expn){ this.coef = coef; this.expn = expn; } public int getCoef() { return coef; } public void setCoef(int coef) { this.coef = coef; } public int getExpn() { return expn; } public void setExpn(int expn) { this.expn = expn; }}多項(xiàng)式存儲(chǔ)采用LinkedList類,LinkedList是一個(gè)雙向鏈表,當(dāng)數(shù)據(jù)量很大或者操作很頻繁的情況下,添加和刪除元素時(shí)具有比ArrayList更好的性能。
package com.milihua.algorithm.lineartable;import java.util.Iterator;import java.util.LinkedList;import java.util.Scanner;public class Polynomial { /** * 存儲(chǔ)第一個(gè)多項(xiàng)式的鏈表 */ LinkedList polyListOne = new LinkedList(); /** * 存儲(chǔ)第二個(gè)多項(xiàng)式的鏈表 */ LinkedList polyListTwo = new LinkedList(); /** * 存儲(chǔ)運(yùn)算結(jié)果的多項(xiàng)式鏈表 */ LinkedList polyListResult = new LinkedList(); /** * 添加數(shù)據(jù)到鏈表尾部 * * @param inPolyData * @return */ public void addLastPol(LinkedList list, PolyData inPolyData) { list.addLast(inPolyData); } /** * 添加數(shù)據(jù)到鏈表 * * @param inPolyData * @return */ public void addPol(LinkedList list, PolyData inPolyData) { list.add(inPolyData); } /** * 比較每項(xiàng)的指數(shù)大小 * * @param aExpen * @param bExpn * @return 0兩個(gè)指數(shù)相等,1第一個(gè)鏈表的指數(shù)大,-1第二個(gè)鏈表的指數(shù)大 */ public int compExpn(int aExpen, int bExpn) { if (aExpen == bExpn) { return 0; } else if (aExpen > bExpn) { return 1; } else { return -1; } } /** * 兩個(gè)多項(xiàng)式鏈表相加 * * @return */ public void addPol() { for (Iterator iter = polyListOne.iterator(); iter.hasNext();) { PolyData poly = iter.next(); for (Iterator iterTwo = polyListTwo.iterator(); iterTwo.hasNext();) { PolyData polyTwo = iterTwo.next(); switch (compExpn(poly.expn, polyTwo.expn)) { case 0: PolyData newPolyData = new PolyData(poly.coef + polyTwo.coef, poly.expn); polyListResult.add(newPolyData); polyListTwo.remove(polyTwo); break; case 1: polyListResult.add(polyTwo); polyListResult.add(poly); polyListTwo.remove(polyTwo); break; case -1: polyListResult.add(poly); polyListResult.add(polyTwo); polyListTwo.remove(polyTwo); break; } break; } } } /** * 遍歷鏈表并顯示出來 * * @param list */ public void display(LinkedList list) { for (Iterator iter = list.iterator(); iter.hasNext();) { PolyData poly = iter.next(); System.out.print(poly.getCoef() + "x^" + poly.getExpn() + "+"); } System.out.println(); } public LinkedList getPolyListOne() { return polyListOne; } public void setPolyListOne(LinkedList polyListOne) { this.polyListOne = polyListOne; } public LinkedList getPolyListTwo() { return polyListTwo; } public void setPolyListTwo(LinkedList polyListTwo) { this.polyListTwo = polyListTwo; } public LinkedList getPolyListResult() { return polyListResult; } public void setPolyListResult(LinkedList polyListResult) { this.polyListResult = polyListResult; }}Polynomial類是案例文件的主要處理類,在類中聲明了三個(gè)LinkedList類,分別存儲(chǔ)第一個(gè)多項(xiàng)式、第二個(gè)多項(xiàng)式以及兩個(gè)多項(xiàng)式相加運(yùn)算的結(jié)果。
Polynomial類的addPol()方法用于執(zhí)行兩個(gè)多項(xiàng)式的相加運(yùn)算,具體算法過程是:
(1)遍歷第一個(gè)多項(xiàng)式;
(2)在遍歷過程中,處理每一個(gè)單項(xiàng);
遍歷第二個(gè)多項(xiàng)式;
比較兩個(gè)單項(xiàng)式的指數(shù);
若指數(shù)相同,則兩個(gè)單項(xiàng)式的系數(shù)相加,并形成新的單項(xiàng)式添加到運(yùn)算結(jié)果列表中;若指數(shù)不相同,則兩個(gè)單項(xiàng)式都添加到運(yùn)算結(jié)果列表中。
addPol算法的執(zhí)行頻率為n*m,n為第一個(gè)多項(xiàng)式的單項(xiàng)式個(gè)數(shù),m為第二個(gè)多項(xiàng)式的單項(xiàng)式個(gè)數(shù),其算法復(fù)雜度為O(n^2)。
PolynomialTest類為測(cè)試類,代碼如下:package unittest;import java.util.Scanner;import com.milihua.algorithm.lineartable.PolyData;import com.milihua.algorithm.lineartable.Polynomial;public class PolynomialTest { public static void main(String[] args) { Polynomial poly = new Polynomial(); //聲明Scanner變量,并用new運(yùn)算符實(shí)例化Scanner Scanner sc = new Scanner(System.in); System.out.println("----請(qǐng)輸入第一個(gè)多項(xiàng)式\r\n輸入方式為“系數(shù)," + "指數(shù)”\r\n結(jié)束請(qǐng)輸入0----"); while(true) { String str = sc.next(); if( str.equals("0") ) { System.out.println("----第一個(gè)多項(xiàng)式輸入結(jié)束----"); break; } String[] strArray = str.split(","); if( strArray.length < 2 ) { System.out.println("----輸入的數(shù)據(jù)格式錯(cuò)誤----"); break; } int coef = Integer.parseInt(strArray[0]); int expn = Integer.parseInt(strArray[1]); PolyData polyData = new PolyData(coef,expn); poly.addPol(poly.getPolyListOne(),polyData); } poly.display(poly.getPolyListOne()); System.out.println("----請(qǐng)輸入第二個(gè)多項(xiàng)式\r\n輸入方式為“系數(shù)," + "指數(shù)”\r\n結(jié)束請(qǐng)輸入0----"); while(true) { String str = sc.next(); if( str.equals("0") ) { System.out.println("----第二個(gè)多項(xiàng)式輸入結(jié)束----"); break; } String[] strArray = str.split(","); if( strArray.length < 2 ) { System.out.println("----輸入的數(shù)據(jù)格式錯(cuò)誤----"); break; } int coef = Integer.parseInt(strArray[0]); int expn = Integer.parseInt(strArray[1]); PolyData polyData = new PolyData(coef,expn); poly.addPol(poly.getPolyListTwo(),polyData); } poly.display(poly.getPolyListTwo()); poly.addPol(); poly.display(poly.getPolyListResult()); }}用線性表存儲(chǔ)一元多項(xiàng)式時(shí),線性表的元素由兩部分組成,一部分用于存儲(chǔ)多項(xiàng)式的系數(shù)項(xiàng),一部分用于存儲(chǔ)多項(xiàng)式的指數(shù)項(xiàng)。這種存儲(chǔ)結(jié)構(gòu)對(duì)指數(shù)項(xiàng)很高且變化很大的多項(xiàng)式特別有用。在存儲(chǔ)多項(xiàng)式時(shí),線性表的存儲(chǔ)結(jié)構(gòu)可以采用順序存儲(chǔ)結(jié)構(gòu),也可以采用鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu),推薦使用鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu),存儲(chǔ)空間靈活其運(yùn)算方便。
一元多項(xiàng)式相加的運(yùn)算規(guī)則非常簡單,兩個(gè)多項(xiàng)式中指數(shù)相同的項(xiàng)對(duì)應(yīng)系數(shù)相加,若相加的和不為零,則構(gòu)成相加結(jié)果多項(xiàng)式中的一項(xiàng),所有指數(shù)不相同的項(xiàng)均復(fù)制到相加結(jié)果多項(xiàng)式中。多項(xiàng)式加法運(yùn)算的時(shí)間復(fù)雜度為O(n)或O(n^2),算法不同,其時(shí)間復(fù)雜度也不同。本文給出的案例時(shí)間復(fù)雜度為O(n^2),時(shí)間復(fù)雜度為O(n)的算法,請(qǐng)自行給出。
—END—編程訓(xùn)練營APP創(chuàng)新在線學(xué)習(xí)模式,學(xué)習(xí)編程不再半途而廢安卓手機(jī)應(yīng)用商店搜索編程訓(xùn)練營下載總結(jié)
以上是生活随笔為你收集整理的c++用模板实现稀疏多项式_用线性表实现一元多项式及相加运算的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php mysql随机记录_php随机取
- 下一篇: c++ 函数返回空_Python all