数据结构与算法&线性表工具使用&多项式

本篇文章建立在数据结构与算法&线性表工具上,有些结论直接使用了。

一、多项式

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 家

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值