java實現多項式的加減乘除
阿新 • • 發佈:2018-12-26
package polynomial; public class Polynomial { Polynomial next; double data; // 係數值 int power; // 冪值 public Polynomial(){ this(0.0, -1); } public Polynomial(double data, int power){ this.data = data; this.power = power; this.next = null; } public Polynomial(double data, int power, Polynomial next){ this.data = data; this.power = power; this.next = next; } public String toString(){ return "data = "+data+",power = "+power; } }
package polynomial; // import java.util.InputMismatchException; import java.util.Scanner; public class Util { // Polynomial p; Scanner input = new Scanner(System.in); public Util() { // p = new Polynomial(); } /** * 1. 判斷多項式中是否存在該冪數的項數 * @param power 冪數 * @param p 連結串列 * @return 是否存在power相同的項數 * * complete */ private boolean locateElem(int power, Polynomial p) { Polynomial current = p.next; /* // 不需要判斷power是否小於0 if(power<0) return false; */ while(current!=null) { if(current.power == power) return true; current = current.next; } return false; } /** * 2.做相加的操作 * @param data * @param power * @param current * @param previous * @return */ private boolean addElem(double data, int power, Polynomial current, Polynomial previous) { if(power == current.power) { current.data = current.data + data; if(0 == current.data && previous != null) previous.next = current.next; if(0 == current.data && previous == null) current = current.next; return true; } return false; } private void addAllElem(double data, int power, Polynomial p) { Polynomial current; Polynomial previous; current = p; previous = p; while(current!=null && power!=current.power) { previous = current; current = current.next; } current.data = current.data + data; if(0 == current.data && current!=previous) // 當current的next為0的時候和current為頭節點 previous.next = current.next; else p = current.next; } private boolean subElem(double data, int power, Polynomial current, Polynomial previous) { if(power == current.power) { current.data = current.data - data; if(0 == current.data && previous != null) previous.next = current.next; else current = current.next; return true; } return false; } // 4. 多項式的相乘操作 這裡的p應該存放的是b中的多項式節點 private void mulElem(double data1, int power1, double data2, int power2, Polynomial p) { p.data = data1*data2; p.power = power1+power2; } /** 5. 在不存在相同冪數的情況下進行插入的操作 * 特殊的插入 可以在連結串列只有頭結點的時候在第一個位置進行插入 * @param data * @param power * @param p * @return * * complete */ private boolean insertElem(double data, int power, Polynomial p) { Polynomial current; Polynomial temp = new Polynomial(data, power, null); Polynomial previous; current = p; // 1.首先判斷不存在首元節點的情況 if(current.next == null) { current.next = temp; return true; } previous = p; current = p.next; while( current!=null && current.power<power) { previous = current; current = current.next; } previous.next = temp; temp.next=current; return true; } /** * 6. 比較當前兩個節點誰的power更大 前者大返回 1; 後者大返回-1;一樣大返回0; * * @param a 連結串列的一個節點 * @param b 連結串列的一個節點 * @return 1、0或者-1 * * complete */ private int getCurElem(Polynomial a, Polynomial b) { if( a.power>b.power ) return 1; else if( a.power<b.power ) return -1; else return 0; } // ----------------------------------- /** * 1. 輸入m項的data和power建立一元多項式 * @param m * @param p * * complete */ public void createPolyn(int m, Polynomial p) { double data; int power; // 正序 for(int i=0; i<m; i++) { System.out.print("請輸入第"+(i+1)+"係數:"); data = input.nextDouble(); if( 0==data ) { System.out.println("係數不能為0"); continue; } System.out.print("請輸入第"+(i+1)+"冪數:"); power = input.nextInt(); if(locateElem(power, p)) // 如果存在power相同的 { addAllElem(data, power, p); } else { insertElem(data, power, p); } } } /** * 2. 銷燬一元多項式 * @param p * * complete */ public void destroyPolyn(Polynomial p) { p.next = null; p = null; } /** * 3. 列印輸出一元多項式 * @param p * * complete */ public void printPolyn(Polynomial p) { Polynomial current; current = p.next; int count = 0; while(current!=null) { if( current.data>0 ) { if(0 == count) { System.out.print(current.data+"x^"+current.power); count++; } else { System.out.print("+"+current.data+"x^"+current.power); } } if( current.data<0 ) { if(0 == count) { System.out.print(current.data+"x^"+current.power); count++; } else { System.out.print(current.data+"x^"+current.power); } } current = current.next; } System.out.println(); } /** * 4. 返回一元多項式的項數 * @param p * @return * * complete */ public int polynLength(Polynomial p) { Polynomial current = p.next; int count = 0; while(current!=null) { count++; current = current.next; } return count; } /* * Polynomial a = ...; * h = a; * 後面修改h a中會改變 * * Polynomial a = ...; * h = a; * 後面修改a h中會改變 * * 在計算力不夠的時候,牢記引用變數的名字都代表地址,地址直接操作的改變 * 會對所有指向這個地址的引用型別的變數都造成修改。 * 引用型別變數(名字)的值可以修改(修改裝的物件:即地址) * */ /** * * @param a * @param b * * complete */ public void addPolyn(Polynomial a, Polynomial b) { Polynomial currenta = a.next; Polynomial currentb = b.next; Polynomial previousa = a; // 儲存a的前驅 /* * 在將當前(currentb)插入到a連結串列中之後 * 當前的currentb中的後繼就被連結到了a連結串列之後了 * 所以在操作currentb之前我們需要將currentb的後繼儲存到一個後繼節點物件中去 * 在每次迴圈的時候,再將後繼(subsequenctb)賦給currentb * */ Polynomial subsequentb = currentb.next; while(currentb != null) { if(getCurElem(currenta, currentb)<0) // 如果currenta小於當前的currentb { // 將currenta移向next previousa = currenta; currenta = currenta.next; /* * 當currenta.next為空的時候,說明currentb比currenta中的所有元素都要大 * 將currentb插入到currenta的後面 */ // if(getCurElem(currenta, currentb)>0) continue; // 當currenta.next 為null 但是currenta大於currentb的時候 if(currenta.next == null && getCurElem(currenta, currentb)<0) // 在a的最後一個元素都比b的第一個元素小的時候 { insertElem(currentb.data, currentb.power, currenta); currentb = currentb.next; currentb = subsequentb; // 插入之後currentb本身沒有從連結串列上斷開 if(currentb!=null) { subsequentb = currentb.next; } } // 第一次currenta移向next的操作結束之後,currenta依舊可能比currentb小 } /* * 這裡的currenta大於currentb處於剛好的臨界條件 * 所以必然此刻的currentb處於previousa和currenta之間 */ else if(getCurElem(currenta, currentb)>0) // 如果currenta大於當前的currentb { /* * 將currentb連線到previousa和currenta之間 */ previousa.next = currentb; currentb.next = currenta; /* * 因為已經將currentb插入到了previousa和currenta之間了 * 所以此刻的previousa不是等於currenta 應該等於此刻的currentb * * 最後將currentb的指向重新賦值為b的後繼 subsequentb */ previousa = currentb; currentb = subsequentb; // 做currentb的後繼的賦值的操作必須先判斷currentb是否為空,為空的話取後繼為造成空指標 if(currentb != null) subsequentb = currentb.next; } else { addElem(currentb.data, currentb.power, currenta, previousa); currentb = currentb.next; } } b.next = null; }// 5. 將兩個一元多項式相加 Pa = Pa + Pb; 並且銷燬Pb public void subPolyn(Polynomial a, Polynomial b) { Polynomial currenta = a.next; Polynomial currentb = b.next; Polynomial previousa = a; // 儲存a的前驅 /* * 在將當前(currentb)插入到a連結串列中之後 * 當前的currentb中的後繼就被連結到了a連結串列之後了 * 所以在操作currentb之前我們需要將currentb的後繼儲存到一個後繼節點物件中去 * 在每次迴圈的時候,再將後繼(subsequenctb)賦給currentb * */ Polynomial subsequentb = currentb.next; while(currentb != null) { if(getCurElem(currenta, currentb)<0) // 如果currenta小於當前的currentb { // 將currenta移向next previousa = currenta; currenta = currenta.next; /* * 當currenta.next為空的時候,說明currentb比currenta中的所有元素都要大 * 將currentb插入到currenta的後面 */ // if(getCurElem(currenta, currentb)>0) continue; // 當currenta.next 為null 但是currenta大於currentb的時候 if(currenta.next == null && getCurElem(currenta, currentb)<0) // 在a的最後一個元素都比b的第一個元素小的時候 { insertElem(-currentb.data, currentb.power, currenta); currentb = currentb.next; currentb = subsequentb; // 插入之後currentb本身沒有從連結串列上斷開 if(currentb!=null) { subsequentb = currentb.next; } } // 第一次currenta移向next的操作結束之後,currenta依舊可能比currentb小 } /* * 這裡的currenta大於currentb處於剛好的臨界條件 * 所以必然此刻的currentb處於previousa和currenta之間 */ else if(getCurElem(currenta, currentb)>0) // 如果currenta大於當前的currentb { /* * 將currentb連線到previousa和currenta之間 */ currentb.data = -currentb.data; previousa.next = currentb; currentb.next = currenta; /* * 因為已經將currentb插入到了previousa和currenta之間了 * 所以此刻的previousa不是等於currenta 應該等於此刻的currentb * * 最後將currentb的指向重新賦值為b的後繼 subsequentb */ previousa = currentb; currentb = subsequentb; // 做currentb的後繼的賦值的操作必須先判斷currentb是否為空,為空的話取後繼為造成空指標 if(currentb != null) subsequentb = currentb.next; } else { subElem(currentb.data, currentb.power, currenta, previousa); currentb = currentb.next; } } b.next = null; }// 6. 將兩個一元多項式相減 Pa = Pa - Pb; 並且銷燬Pb /* Polynomial a 引用型別的變數相當於C語言中的指標,a代表的是對應的地址 a的地址不能被修改,只能修改a對應的地址的值, 所以下面的a被我們修改了 所以必須重新返回一個Polynomial型別的a。 */ // public Polynomial multiplyPolyn(Polynomial a, Polynomial b) public void multiplyPolyn(Polynomial a, Polynomial b) { Polynomial currenta = a.next; Polynomial currentb = b.next; Polynomial current = new Polynomial(); Polynomial subsequentb = currentb.next; Polynomial temp = new Polynomial(); temp = current; a.next = null; while(currenta != null) { while(currentb != null) { current.next = new Polynomial(); mulElem(currenta.data, currenta.power, currentb.data, currentb.power, current.next); currentb = currentb.next; current = current.next; } currentb = subsequentb; currenta = currenta.next; if(currentb != null) subsequentb = subsequentb.next; } /* a = temp; temp = null; b.next = null; return a; */ temp = temp.next; a.next = temp; b.next = null; // b也不能直接被修改,b也相當於指標 }// 7. 將兩個一元多項式相乘 Pa = Pa * Pb; 並且銷燬Pb }
package polynomial; public class Test { public static void main(String[] args) { Util u = new Util(); /* Polynomial p = new Polynomial(); u.createPolyn(3,p); System.out.println(u.polynLength(p)); u.printPolyn(p); u.destroyPolyn(p); u.printPolyn(p); */ Polynomial a = new Polynomial(); u.createPolyn(3, a); Polynomial b = new Polynomial(); u.createPolyn(3, b); // u.addPolyn(a, b); // u.subPolyn(a, b); u.multiplyPolyn(a, b); u.printPolyn(a); // u.printPolyn(b); } }