• 简单实系数一元多项式问题


    数据结构与算法实验题 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;
    }
    
  • 相关阅读:
    粘包现象
    SOCKET的简单介绍
    jQuery基本语法
    Bet(The 2016 ACM-ICPC Asia China-Final Contest 思路题)
    World Cup(The 2016 ACM-ICPC Asia China-Final Contest dfs搜索)
    Number Theory Problem(The 2016 ACM-ICPC Asia China-Final Contest 找规律)
    HDU
    Yin and Yang Stones(思路题)
    在线数学公式编译器
    HDU
  • 原文地址:https://www.cnblogs.com/xiao-qingjiang/p/13695159.html
Copyright © 2020-2023  润新知