1. 程式人生 > 實用技巧 >簡單實係數一元多項式問題

簡單實係數一元多項式問題

資料結構與演算法實驗題 2.2 簡單實係數一元多項式問題

★問題描述:

★資料輸入:

第一行有一個正整數 k,表示有 k 個一元實係數多項式。接下來有 k(k<=20)個數據塊,每個資料塊的第 1行是 1 個正整數 s,表示該資料塊共有 s行。接下來的 s 行中,每行由實數 a和整數 b組成,表示多項式中的項 axbaxb 。緊接著 k 個數據塊的是長度為 k-1 的字串,每個字元是“+”,“-”,“*”這 3 個字元之一。

★資料輸出:

檔案的第一行是計算得到的多項式 g(x),輸出多項式時,xkxk 用 x^k 表示。例如,5xk5xk 應表示為 5x^5。注意輸出的結果應該符合數學中手寫習慣。例如,x不應輸出為 1x^1,實係數 保留 6位有效數字。(資料保證多項式項數不大於 500)

★補充說明

整數 b 滿足 b 為非負整數

輸出的多項式結果,按項的冪次從高到低排序,參見樣例

★Hint

c++中可以使用 setprecision 操作符來控制顯示浮點數值的有效數的數量

該題主要使用陣列模擬運算,詳細註釋如下

#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
double a[22][51000];
//構建二維陣列,如a[m][n]=j代表第m個多項式的第n次方項(冪次(指數)為n的項)的係數為j;(即次冪為n的項為 j*x^n)
//比如第2個多項式的5*x^6就應該表示為a[2][6]=5;
double b[51000];//陣列b用來存乘法運算的結果
//陣列下標代表指數(次冪),b[m]=n 代表指數為m的項的係數為n;

int main() {
	int k, t, y, ymax = 0;
	double x;

	//資料輸入
	scanf("%d", &k);//代表具有k個多項式,k個數據塊
	for (int i = 1; i <= k; i++) {
		cin >> t;//表明該資料塊共有t行
		while (t--) {//輸入t次
			cin >> x >> y;
			a[i][y] = x;//代表第i個多項式的y次方項的係數為x;
			if (y > ymax) ymax = y;//ymax用來記錄最高的指數,即最高次冪
		}
	}
	char temp[510];
	for (int i = 1; i <= k - 1; i++) {
		cin >> temp[i];//輸入運算子
	}

	//多項式運算
	for (int i = 1; i <= k - 1; i++) {
		if (temp[i] == '+') {
			for (int j = 0; j <= ymax; j++) {
				a[i + 1][j] += a[i][j];//指數從零到ymax,將兩個多項式指數相同的項相加,並將結果存在後一個多項式中
				//將結果存在後一個多項式,是因為運算後的結果可能還要與下一個多項式進行下一次運算
			}
		}
		if (temp[i] == '-') {
			for (int j = 0; j <= ymax; j++) {
				a[i + 1][j] = a[i][j] - a[i + 1][j];
				//和運算‘+’相似,只不過把“相加” 變為 “相減”
			}
		}
		if (temp[i] == '*') {
			int t = ymax;
			memset(b, 0, sizeof(b));//將陣列b清零,因為乘法運算可能不止一次,所以每一次都要將陣列b清零
			for (int j = 0; j <= t; j++) {
				for (int m = 0; m <= t; m++) {
					b[j + m] += a[i][j] * a[i + 1][m];//由於  x^j * x^m=x^(j+m),所以將係數的運算結果存到b[j+m]
					if (j + m > ymax && b[j + m]) ymax = j + m;//如果運算結果產生的新項的指數大於ymax,就更新ymax
				}
			}
			for (int j = 0; j <= ymax; j++) {
				a[i + 1][j] = b[j];//將運算結果放回參與運算的兩個多項式中的第二個多項式
				//cout << b[j] << " ";
			}
		}
	}


	//資料輸出
	//資料輸出需要考慮最高項的輸出(即首先輸出的項)和其他項的輸出
	//還需要考慮係數和指數為“+1、-1”時輸出的情況,還有係數為大於0時要輸出“+”


	//最高項輸出的分類討論
	while (a[k][ymax] == 0 && ymax) {//如果最高項為0的話就跳過
		ymax--;
	}
	if (ymax != 1 && ymax != 0) {//但次冪為1和0的時候需要特判
		if (a[k][ymax] == 1) {//如果係數為1不輸出係數
			cout << "x^" << ymax;
		}
		else if (a[k][ymax] == -1) {//係數為-1只輸出負號
			cout << "-x^" << ymax;
		}
		else {
			cout << a[k][ymax] << "x^" << ymax;//其他情況正常輸出
		}
	}
	else if (ymax == 1) {//只輸出x,不輸出指數
		if (a[k][ymax] == 1) {//當係數為1時不輸出係數
			cout << "x";
		}
		else if (a[k][ymax] == -1) {//係數為-1時只輸出負號
			cout << "-x";
		}
		else {
			cout << a[k][ymax] << "x";//其他情況正常輸出
		}
	}
	else {
		cout << a[k][ymax];//當最高次冪為0時直接輸出係數
	}

	//除最高項的輸出
	for (int i = ymax - 1; i >= 0; i--) {
		if (a[k][i] > 0) cout << '+';//如果係數為正,需要輸出‘+’
		if (fabs(a[k][i] - 0) > 0.000001) {//即當a[k][i]!=0時
			if (a[k][i] != 1 && a[k][i] != -1) {
				cout << a[k][i];//係數不為正負一時直接輸出
			}
			else {
				if (i == 0) {
					cout << a[k][i];//指數為0時只輸出係數
				}
			}
			if (a[k][i] == -1) cout << '-';//係數為-1的特判
			if (i > 1) {
				cout << "x^" << i;
			}
			if (i == 1) {
				cout << 'x';//指數為1的特判
			}
		}
	}
	return 0;
}