1. 程式人生 > >02-線性結構2 一元多項式的乘法與加法運算 (java)

02-線性結構2 一元多項式的乘法與加法運算 (java)

02-線性結構2 一元多項式的乘法與加法運算 (20 分)

設計函式分別求兩個一元多項式的乘積與和。

輸入格式:

輸入分2行,每行分別先給出多項式非零項的個數,再以指數遞降方式輸入一個多項式非零項係數和指數(絕對值均為不超過1000的整數)。數字間以空格分隔。

輸出格式:

輸出分2行,分別以指數遞降方式輸出乘積多項式以及和多項式非零項的係數和指數。數字間以空格分隔,但結尾不能有多餘空格。零多項式應輸出0 0

輸入樣例:

4 3 4 -5 2  6 1  -2 0
3 5 20  -7 4  3 1

輸出樣例:

15 24 -25 22 30 21 -10 20 -21 8 35 6 -33 5 14 4 -15 3 18 2 -6 1
5 20 -4 4 -5 2 9 1 -2 0

 思路:

1.使用單鏈表,設定結點Node,成員變數為係數和指數以及下一個指向的物件

2.先來說一下多項式加法(比較簡單)

   1)若指數相同則係數相加,新增到連結串列c中(不要忘記特判係數相加為0的情況這時候不相加)

   2)因為要有序,所以比較指數時,若該a連結串列當前結點的指數比b連結串列當前結點的指數大時,則把a連結串列當前結點新增到連結串列c中,然後讓a連結串列當前結點往後移,連結串列c當前位置也往後移,同理連結串列b當前結點比連結串列a當前結點指數大的時候是一樣的道理

   3)把剩餘的結點加入到連結串列c中(pc.next=(pa!=null?pa:pb))

3.多項式乘法(可能我寫的比較麻煩了)

    1)先將多項式a的第一項與多項式b的每一項相乘,把每一項都新增到新建的連結串列c中

    2)將多項式a餘下的項與多項式b進行相乘,把相乘的項與連結串列c中每一項進行比較,若該項的指數與連結串列c中某一項的指數相同,則進行係數相加(這裡需要特判,如果係數相加為0則去掉連結串列c中的該項),若該項係數要大於連結串列c中的某一項,則新增進去,若該項係數比連結串列c每一項的係數都要小的話,則新增到連結串列c的末位

其中需要特別注意的是:

當特判如果係數相加為0則去掉連結串列c中的該項時,若該項是連結串列c中的尾結點,去掉該尾結點之後會讓當前結點的指向下一結點為空,程式認為是該項係數比連結串列c每一項係數都要小,會新增到連結串列c的末位,這個BUG我找了好久,哭嘰嘰,所以只需要新增一個布林型別的變數來進行判斷就行,初始值設為true,若是合併後下一結點為空,則把該變數設為false就行

if(curPc.next==null && is) {
	curPc.next = new Node(xs, zs);
}

4. 實現了多項式的乘法與加法計算後別以為就完事了,輸出的時候還需要判別一下零多項式,若係數全是0的話就輸出0 0就行

下面是AcCode:

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int lengthA = in.nextInt();
		int[][] numA = new int[lengthA][2];
		for (int i = 0; i < numA.length; i++) {
			for (int j = 0; j < numA[i].length; j++) {
				numA[i][j] = in.nextInt();
			}
		}
		LinkList linkListA = new LinkList(numA);
		int lengthB = in.nextInt();
		int[][] numB = new int[lengthB][2];
		for (int i = 0; i < numB.length; i++) {
			for (int j = 0; j < numB[i].length; j++) {
				numB[i][j] = in.nextInt();
			}
		}
		LinkList linkListB = new LinkList(numB);
		Node mutiply = linkListA.hbMutiplly(linkListA, linkListB);
		Node sum = linkListA.hbSum(linkListA, linkListB);
		
		mutiply = mutiply.next;
		boolean is = true;//是不是第一個元素
		boolean isZero = true;
		while(mutiply!=null) {
			if(is) {
				if(mutiply.xs!=0) {
					System.out.print(mutiply.xs+" "+mutiply.zs);
					is = false;
					isZero = false;
				}
			}else {
				if(mutiply.xs!=0) {
					System.out.print(" "+mutiply.xs+" "+mutiply.zs);
					isZero = false;
				}		
			}
			mutiply = mutiply.next;
		}
		if(isZero) {
			System.out.print(0+" "+0);
		}
		System.out.println();
		is = true;
		isZero = true;
		sum = sum.next;
		while(sum!=null) {
			if(is) {
				if(sum.xs!=0) {
					System.out.print(sum.xs+" "+sum.zs);
					is = false;
					isZero = false;
				}
			}else {
				if(sum.xs!=0) {
					System.out.print(" "+sum.xs+" "+sum.zs);
					isZero = false;
				}		
			}
			sum = sum.next;
		}
		if(isZero) {
			System.out.print("0 0");
		}
		System.out.println();
	}
}

class LinkList {
	Node head;// 頭結點
	/**
	 * 多項式乘積
	 * @param linkListA
	 * @param linkListB
	 * @return
	 */
	public Node hbMutiplly(LinkList linkListA,LinkList linkListB) {
		Node pa = linkListA.head.next;
		Node pb = linkListB.head.next;
		Node pc = new Node();
		Node curPc = pc;
		//初始化
		if(pa!=null) {
			while(pb!=null) {
				curPc.next = new Node(pa.xs*pb.xs, pa.zs+pb.zs); 
				curPc = curPc.next;
				pb = pb.next;	
			}
			pa = pa.next;
		}
		
		while(pa!=null) {
			pb = linkListB.head.next;
			curPc = pc;
			while(pb!=null) {
				int xs = pa.xs*pb.xs;
				int zs = pa.zs+pb.zs;
				boolean is = true;
				while(curPc.next!=null) {
					if(curPc.next.zs==zs) {
						if((curPc.next.xs+xs)!=0) {
							curPc.next.xs = curPc.next.xs+xs;
						}else {
							curPc.next = curPc.next.next;
							is = false;
						}
						break;
					}else if(curPc.next.zs<zs) {
						curPc.next = new Node(xs, zs, curPc.next);
						break;
					}
					curPc = curPc.next;
				}
				if(curPc.next==null && is) {
					curPc.next = new Node(xs, zs);
				}
				
//				Node c = pc.next;
//				while (c!= null) {
//					System.out.print(c.xs + " " + c.zs + " ");
//					c = c.next;
//				}
//				System.out.println();
				
				pb = pb.next;
			}
			pa = pa.next;	
		}
		return pc;
	}
	
	/**
	 * 多項式加法
	 * @param linkListA
	 * @param linkListB
	 * @return
	 */
	public Node hbSum(LinkList linkListA, LinkList linkListB) {
		Node pa = linkListA.head.next;
		Node pb = linkListB.head.next;
		Node NodeCHead = new Node();// 存放多項式的和
		Node pc = NodeCHead;

		while (pa != null && pb != null) {
			if (pa.zs == pb.zs) {
				if ((pa.xs + pb.xs) != 0) {
					pc.next = new Node(pa.xs + pb.xs, pa.zs);
					pc = pc.next;
				}
				pa = pa.next;
				pb = pb.next;
			} else if (pa.zs > pb.zs) {
				pc.next = pa;
				pc = pc.next;
				pa = pa.next;
			} else {
				pc.next = pb;
				pc = pc.next;
				pb = pb.next;
			}
		}
		pc.next = (pa != null) ? pa : pb;
		return NodeCHead;
	}

	public void display() {
		Node p = head.next;
		while (p != null) {
			System.out.print(p.xs + " " + p.zs + " ");
			p = p.next;
		}
		System.out.println();
	}

	public LinkList() {
		this.head = new Node();
	}

	public LinkList(int[][] num) {
		this();
		Node p = head;
		for (int i = 0; i < num.length; i++) {
			p.next = new Node(num[i][0],num[i][1], p.next);
			p = p.next;
		}
	}

}

class Node {
	int xs;
	int zs;
	Node next;

	/**
	 * 初始化頭結點
	 */
	public Node() {
		this.next = null;
	}

	public Node(int xs, int zs, Node next) {
		this(xs, zs);
		this.next = next;
	}

	/**
	 * 尾結點
	 * 
	 * @param xs
	 * @param zs
	 */
	public Node(int xs, int zs) {
		this();
		this.xs = xs;
		this.zs = zs;
	}
}

最後偷偷附上測試資料:

序號 輸入 輸出
1 4 3 4 -5 2 6 1 -2 0 
3 5 20 -7 4 3 1
15 24 -25 22 30 21 -10 20 -21 8 35 6 -33 5 14 4 -15 3 18 2 -6 1 
5 20 -4 4 -5 2 9 1 -2 0
2 2 1 2 1 0
2 1 2 -1 0
1 4 -1 0
2 2
3 2 -1000 1000 1000 0
2 1000 1000 -1000 0
-1000000 2000 2000000 1000 -1000000 0
0 0
4 0
1 999 1000
0 0
999 1000

新人初學資料結構QAQ,不足跪求神犇指點