数据结构与算法实验题 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;
}