本篇文章建立在数据结构与算法&线性表工具上,有些结论直接使用了。
一、多项式
1.定义:
在数学中,多项式(polynomial)是指由变量、系数以及它们之间的加、减、乘、幂运算(非负整数次方)得到的表达式。
例如:-465X^3+ 0.485X^2 +74.25
2.多项式特征及实现
1)系数 (coefficient)
2) 指数 (exponent)
系数 * x ^ 指数就是多项式的一个项。所以多项式就是一个一个项的组成。
定义项:
typedef struct POLY_ITEM {
double coefficient;// 系数
int exponent; //指数
}POLY_ITEM, USER_TYPE;
此时将用户自定义类型变成了多项式一个项的类型。
3.线性表的使用
linear.h代码:
#ifndef _STICK_LINEAR_H_
#define _STICK_LINEAR_H_
#include "userType.h"
typedef struct LINEAR {
USER_TYPE *data;//用户需要的数据类型
int capacity; //最大空间
int count;//有效使用空间
}LINEAR;
typedef unsigned char boolean;
#define TRUE 1
#define FALSE 0
#define NOT_FOUND -1
boolean initLinear(LINEAR **head, int capacity);
void destoryLinear(LINEAR **head);
//还有一些其他功能
#endif
使用线性表工具:
#ifndef _STICK_POLYNOMIAL_H_
#define _STICK_POLYNOMIAL_H_
#include "userType.h"
#include "linear.h"
typedef LINEAR POLYNOMIAL;// 将多项式的数据类型变成线性表类型
#endif
4.多项式简单功能实现
1)初始化:
注意:由于linear和polynomial数据类型一样,直接调用。
//初始化多项式
boolean initPolynomial(POLYNOMIAL **poly, int capacity) {
return initLinear(poly ,capacity);//直接调用
}
2)销毁:
//销毁多项式
void destoryPolynomial(POLYNOMIAL **poly) {
destoryLinear(poly);//直接调用
}
3)录入
//录入多现式
boolean enterPoly(POLYNOMIAL *poly) {
double cofficient;//系数
int exponent;//指数
POLY_ITEM item;//多项式每一个部分
int capacity = getCapacity(poly);
if (NULL == ploy) {
return FALSE;
}
if (poly->count > 0) {
printf("录入只能对空多项式进行操作!");
return FALSE;
}
printf("多项式按幂指数降序排列,这一点由录入者自己保证,本程序概不负责!\n");
printf("录入多项式各项,若系数为0,则,停止录入!\n");
printf("请输入系数和幂指数:");
scanf("%lf %d", &coefficient, &exponent);
while (fabs(coefficient) > 1e-6 && !isLinearFull(poly)) {
item.coefficient = coefficient;
item.exponent = exponent;
appendElement(poly, item);
printf("请输入系数和幂指数:");
scanf("%lf %d", &coefficient, &exponent);
}
return TRUE; //输入成功
}
ps:采用的是强制要求输入者按照规定来,如果输入者不按照这个规定,那么这个程序毫无作用。不符合鲁棒性的要求。当然这里只是初步简单实现。
4)显示
注意:多项式每个项直接的链接是通过下一项的系数决定,如果是负数直接输出该负数。
如果是正数,那么好的考虑是否是第一个项,第一项其系数是正数是不需要输出“+”号
//显示多项式一部分
void showPolyItem(POLY_ITEM item, boolean isFirst) {
if (!isFirst && item.coefficient > 1e-6) {
printf("+");
//如果系数大于0且不是第一个系数,输出加号,
}
printf(".2lf", item.coefficient);//输出系数
if (item.exponent != 0) {
printf("x");
}
if (item.exponent != 0 && item.exponent != 1) {
printf("^%d\n", item.exponent);
}
}
//显示多项式
void showPoly(const POLYNOMIAL *poly) {
int i;
int count = getCount(poly);
POLY_ITEM item;
for (i = 0; i < count; i ++) {
getElement(poly, i, &item);
showPolyItem(item, i == 0);// i!=0时 ,isFirst为假
}
printf("\n");
}
5)多项式相加
由于个人采用的是多项式幂指数降序排列。所以基本思路如下:
(1)两个多项式都从第一项开始,各自的幂指数比较,如果其幂指数大,那么直接写入结果,接着该多项式继续扫描第二项,再将其幂指数比较。
按照规定,指数大的直接写入结果,扫描下一项,指数小的等待下一次比较。
如果指数相同,系数相加。但要判断结果结果系数是否为0
(2)当一个多项式扫描结束后,直接将另一个多项式剩余的项直接写入多项式。
POLYNOMIAL *addPoly(const POLYNOMIAL *polyOne, const POLYNOMIAL *polyOther) {
POLYNOMIAL *result = NULL;//结果
int polyOneIndex = 0;
int polyOtherIndex = 0;
int polyOneCount = getCount(polyOne);
int polyOtherCount = getCount(polyOther);
POLY_ITEM itemOne;//临时通过index得到的每一项
POLY_ITEM itemOther;
double newCoefficient;
initPolynomial(&result, getCapacity(polyOne) + getCapacity(polyOther));
getElementAt(polyOne, polyOneIndex, &itemOne);
getElementAt(polyOther, polyOtherIndex, &itemOther);
while (polyOtherIndex < polyOneCount && polyOtherIndex < polyOtherCount) {
if (itemOne.exponent > itemOther.exponent) {
//One的指数高,写入结果值,index++
appendElement(result, itemOne);
getElementAt(polyOne, ++polyOneIndex, &itemOne);
}
if (itemOne.exponent < itemOther.exponent) {
//Other的指数高,写入结果值,index++
appendElement(result, itemOther);
getElementAt(polyOther, ++polyOtherIndex, &itemOther);
}
//指数相同时,系数相加
newCoefficient = itemOne.coefficient + itemOther.coefficient;
if (fabs(newCoefficient) > 1e-6) {
itemOne.coefficient = newCoefficient;
appendElement(result, itemOne);
}
getElementAt(polyOne, ++polyOneIndex, &itemOne);
getElementAt(polyOther, ++polyOtherIndex, &itemOther);
}
while (polyOneIndex < polyOneCount) {
//任意一个项数扫描结束,另一个的剩余项直接写入结果值
appendElement(result, itemOne);
getElementAt(polyOne, ++polyOneIndex, &itemOne);
}
while (polyOtherIndex < polyOtherCount) {
appendElement(result, itemOther);
getElementAt(polyOther, ++polyOtherIndex, &itemOther);
}
return result;
}
调用代码:
#include <stdio.h>
#include "polynomial.h"
// C = A + B
int main()
{
POLYNOMIAL *polyA = NULL;
POLYNOMIAL *polyB = NULL;
POLYNOMIAL *polyC = NULL;
initPolynomial(&polyA, 30);
enterPoly(polyA);
initPolynomial(&polyB, 30);
enterPoly(polyB);
printf("输入的第一个多项式如下:\n");
showPoly(polyA);
printf("输入的第二个多项式如下:\n");
showPoly(polyB);
polyC = addPoly(polyA, polyB);
printf("两个多项式之和如下:\n");
showPoly(polyC);
destoryPolynomial(&polyA);
destoryPolynomial(&polyB);
destoryPolynomial(&polyC);
return 0;
}
二、总结
1.工具功能越基本,越实用。那么使用工具时越方便。
2.显示的越人性化,考虑到用户体验,那么越符合使用者。
笔者水平有限,目前只能描述以上问题,如果有其他情况,可以留言,有错误,请指教,有继续优化的,请分享,谢谢!
完整代码如下:
linear.c 和linear.h都在数据结构与算法&线性表工具中,不在复制一遍了。
userType.h
#ifndef _STICK_USERTYPE_H_
#define _STICK_USERTYPE_H_
typedef struct POLY_ITEM {
double coefficient;// 系数
int exponent; //指数
}POLY_ITEM, USER_TYPE;
#endif
polynomials.h
#ifndef _STICK_POLYNOMIAL_H_
#define _STICK_POLYNOMIAL_H_
#include "userType.h"
#include "linear.h"
typedef LINEAR POLYNOMIAL;
boolean initPolynomial(POLYNOMIAL **poly, int capacity);
void destoryPolynomial(POLYNOMIAL **poly);
boolean enterPoly(POLYNOMIAL *poly);
void showPolyItem(POLY_ITEM item, boolean isFirst);
void showPoly(const POLYNOMIAL *poly);
POLYNOMIAL *addPoly(const POLYNOMIAL *polyOne, const POLYNOMIAL *polyOther);
#endif
polynomials.c
#include <stdio.h>
#include <math.h>
#include "linear.h"
#include "polynomials.h"
//初始化多项式
boolean initPolynomial(POLYNOMIAL **poly, int capacity) {
return initLinear(poly ,capacity);//直接调用
}
//销毁多项式
void destoryPolynomial(POLYNOMIAL **poly) {
destoryLinear(poly);//直接调用
}
//录入多现式
boolean enterPoly(POLYNOMIAL *poly) {
double cofficient;//系数
int exponent;//指数
POLY_ITEM item;//多项式每一个部分
int capacity = getCapacity(poly);
if (NULL == ploy) {
return FALSE;
}
if (poly->count > 0) {
printf("录入只能对空多项式进行操作!");
return FALSE;
}
printf("多项式按幂指数升序排列,这一点由录入者自己保证,本程序概不负责!\n");
printf("录入多项式各项,若系数为0,则,停止录入!\n");
printf("请输入系数和幂指数:");
scanf("%lf %d", &coefficient, &exponent);
while (fabs(coefficient) > 1e-6 && !isLinearFull(poly)) {
item.coefficient = coefficient;
item.exponent = exponent;
appendElement(poly, item);
printf("请输入系数和幂指数:");
scanf("%lf %d", &coefficient, &exponent);
}
return TRUE; //输入成功
}
//显示多项式一部分
void showPolyItem(POLY_ITEM item, boolean isFirst) {
if (!isFirst && item.coefficient > 1e-6) {
printf("+");
//如果系数大于0且不是第一个系数,输出加号,
}
printf(".2lf", item.coefficient);//输出系数
if (item.exponent != 0) {
printf("x");
}
if (item.exponent != 0 && item.exponent != 1) {
printf("^%d\n", item.exponent);
}
}
//显示多项式
void showPoly(const POLYNOMIAL *poly) {
int i;
int count = getCount(poly);
POLY_ITEM item;
for (i = 0; i < count; i ++) {
getElement(poly, i, &item);
showPolyItem(item, i == 0);// i!=0时 ,isFirst为假
}
printf("\n");
}
//多项式相加
POLYNOMIAL *addPoly(const POLYNOMIAL *polyOne, const POLYNOMIAL *polyOther) {
POLYNOMIAL *result = NULL;//结果
int polyOneIndex = 0;
int polyOtherIndex = 0;
int polyOneCount = getCount(polyOne);
int polyOtherCount = getCount(polyOther);
POLY_ITEM itemOne;//临时通过index得到的每一项
POLY_ITEM itemOther;
double newCoefficient;
initPolynomial(&result, getCapacity(polyOne) + getCapacity(polyOther));
getElementAt(polyOne, polyOneIndex, &itemOne);
getElementAt(polyOther, polyOtherIndex, &itemOther);
while (polyOtherIndex < polyOneCount && polyOtherIndex < polyOtherCount) {
if (itemOne.exponent > itemOther.exponent) {
//One的指数高,写入结果值,index++
appendElement(result, itemOne);
getElementAt(polyOne, ++polyOneIndex, &itemOne);
}
if (itemOne.exponent < itemOther.exponent) {
//Other的指数高,写入结果值,index++
appendElement(result, itemOther);
getElementAt(polyOther, ++polyOtherIndex, &itemOther);
}
//指数相同时,系数相加
newCoefficient = itemOne.coefficient + itemOther.coefficient;
if (fabs(newCoefficient) > 1e-6) {
itemOne.coefficient = newCoefficient;
appendElement(result, itemOne);
}
getElementAt(polyOne, ++polyOneIndex, &itemOne);
getElementAt(polyOther, ++polyOtherIndex, &itemOther);
}
while (polyOneIndex < polyOneCount) {
//任意一个项数扫描结束,另一个的剩余项直接写入结果值
appendElement(result, itemOne);
getElementAt(polyOne, ++polyOneIndex, &itemOne);
}
while (polyOtherIndex < polyOtherCount) {
appendElement(result, itemOther);
getElementAt(polyOther, ++polyOtherIndex, &itemOther);
}
return result;
}
2020年02.24 家