一、需求分析:包含题目要求,程序功能,运行方式,测试数据等
输入并建立多项式:建立一个多项式并保证输入和输出正确。
以类数学表达式的形式输出多项式:这里要注意输出形式,遇到常数项时不能输出x,第一项不能输出+号,系数值为1的非零次项的输出形式中略去系数1。
多项式a和b相加:建立多项式a+b。要把两个链表中对应相同指数相加,同时输出要正确,不能改变多项式顺序。
多项式a和b相减,建立多项式a-b:同多项式a和b相加,要把加法转变为减法,可以通过把每一项的系数换为相反数,再运行相加的函数去输出结果,这样不容易报错,同时让程序变得简单高效。
计算多项式在x=x0处的值:要把x0的值带入多项式的每一位,要注意计算的法则和常数项等特殊情况。
求多项式a的导数函数a’:通过把每一项的系数与指数相乘,再把指数减一完成,但也要注意常数项求导等于0时候,要把节点跳过。
通过主函数设计switch函数和dowhile循环多次运行对应函数,一次运行代码可以做到多次输出1-5的不同结果。
二、概要设计:包含抽象数据类型定义,程序模块等
把结构体定义float系数,int指数,对应程序要求,命名为PNode,*Polynomial指针。
typedef struct PNode{
float coef;//系数
int expn;//指数
struct PNode *next;
}PNode,*Polynomial;
创建CreatePolyn函数作为多项式链表初始化函数,定义输入语句while循环输入不同节点对应数据。并将数据按指数大小排序。
创建display函数作为输出函数,输出每一个结点对应系数和指数并加上x,同时注意不要错误输出特殊项,如首项,指数为0常数项,负系数项。
创建AddPolyn作加法函数,设对应指针辅助,在正确条件时对节点系数进行相加,并赋值对应要输出的链表,同时定义SubPolyn作减法函数,将每一项系数赋值为其相反数,再作加法函数,达到对应目标。
创建CalPolyn函数作求对应x0的值,要同时做到求和与对应值正确。把每一项求值再求和,当x0=0时候要正确输出0或者常数项的和。
创建DerPolyn函数作求导函数,将指数与系数相乘得到节点的系数,指数再减1,然后循环这个方法直到每项都求导,并要注意指数为0时常数项求导等于0,应该跳过,并正确赋值,然后显示求导后多项式链表。
三、测试结果
测试数据1,结果正确:
测试数据2,结果正确:
测试数据3,结果正确:
测试数据2改为多项式相减,结果正确:
X=x0求值,x为2,但多项式系数改为负数,结果正确:
对正的多项式求导,结果正确:
对负的多项式求导,结果正确:
四、完整代码
#include <iostream>
#include <stdlib.h>
#include <math.h>
using namespace std;
typedef struct PNode{
float coef;//系数
int expn;//指数
struct PNode *next;
}PNode,*Polynomial;
void CreatePolyn(Polynomial &P,int n){
P = new PNode;
P->next = NULL;//建立头结点单链表
for(int i = 0;i<n;++i){//依次输入n个非0项
Polynomial s = new PNode;//初始化节点
cout<<"请输入第"<<i+1<<"个项系数和指数:";
cin>>s->coef>>s->expn;//输入系数和指数
Polynomial pre = P;//pre保存q的前驱,初始值为头结点
Polynomial q = P->next;//q初始化,指向首元结点
while (q&&q->expn<s->expn) {//通过比较指数找到第一个大于输入项指数的q
pre = q;//pre指向q
q = q->next;//q指向下一位
}
s->next = q;//输入项插入到q和前驱节点之间
pre->next = s;
}
}
void display(Polynomial &P){
PNode *p = P->next;//建立头结点单链表
cout<<"多项式为:";
if(p == NULL)//当为空节点时直接输出0
cout<<"0";
if(p->expn == 0&&p->coef == 0){//指数系数为0时候直接跳向下一个节点
p = p->next;
}
if(p->expn == 0)//指数为0输出系数,即常数项
cout<<p->coef;
else if (p->expn == 1) {//讨论指数为1时
if(p->coef == 1){//指数系数同时为1时首项直接输出x
cout<<"x";
}
else if (p->coef == -1) {//系数为-1时直接输出-x
cout<<"-x";
}
else if (p->coef < 0) {//系数小于1时,输出系数并加上x
cout<<p->coef<<"x";
}
else {
cout<<p->coef<<"x";//系数大于0时,同理
}
}
else {//讨论指数非0且非1的其他情况
if(p->coef == 1){//系数为1直接输出x^
cout<<"x^"<<p->expn;
}
else if (p->coef == -1) {//为-1直接输出-x^
cout<<"-x^"<<p->expn;
}
else if (p->coef < 0) {//小于0正常输出系数指数并加上系数指数
cout<<p->coef<<"x^"<<p->expn;
}
else {//其他情况同理
cout<<p->coef<<"x^"<<p->expn;
}
}
p = p->next;//指向下一个节点
/*处理完首项特殊情况,再输出后面项的常规情况,
* 只需要讨论将x前面加上+号或数前面加上加号,其余情况相同*/
while(p){
if(p->expn == 0&&p->coef == 0)
p = p->next;
if(p->expn == 0)
cout<<p->coef;
else if (p->expn == 1) {
if(p->coef == 1){
cout<<"+x";
}
else if (p->coef == -1) {
cout<<"-x";
}
else if (p->coef < 0) {
cout<<p->coef<<"x";
}
else {
cout<<"+"<<p->coef<<"x";
}
}
else {
if(p->coef == 1){
cout<<"+x^"<<p->expn;
}
else if (p->coef == -1) {
cout<<"-x^"<<p->expn;
}
else if (p->coef < 0) {
cout<<p->coef<<"x^"<<p->expn;
}
else {
cout<<"+"<<p->coef<<"x^"<<p->expn;
}
}
p = p->next;
}
}
void AddPolyn(Polynomial &Pa,Polynomial &Pb){
Polynomial p1,p2,p3,r;//初始化
p1 = Pa->next;p2 = Pb->next;//指向首元结点
p3 = Pa;//指向当前结点,初始值为pa
while (p1&&p2) {//p2,p1非空时
if(p1->expn == p2->expn){//指数相等
float sum = p1->coef+p2->coef;//保存系数和
if(sum != 0){//系数和不为0
p1->coef = sum;//修改当前结点的系数值为和
p3->next = p1; p3=p1;//修改后的pa当前结点连接在p3之后,p3指向p1
p1 = p1->next;//p1指向后一项
r = p2; p2 = p2->next; delete r;//删除pb当前结点,p2指向后一项
}
else {//系数和为0
r = p1; p1 = p1->next; delete r;//删除pa前结点,p2指向后一项
r = p2; p2 = p2->next; delete r;//删除pb当前结点,p2指向后一项
}
}
else if (p1->expn<p2->expn) {//pa当前结点指数小
p3->next = p1;//p3链在p1之后
p3 = p1;//p3指向p1
p1 = p1->next;//p1指向后一项
}
else {//pb当前结点小
p3->next = p2;//p3链在p2之后
p3 = p2;//p3指向p2
p2 = p2->next;//p2指向后一项
}
}
p3->next = p1?p1:p2;//插入非空多项式的剩余段
delete Pb;//释放头结点
display(Pa);
}
void SubPolyn(Polynomial &Pa,Polynomial &Pb){
Polynomial p2;//初始化
p2 = Pb->next;//指向首元结点
while (p2) {//将减数每一项系数等于其相反数
p2->coef = -(p2->coef);
p2 = p2->next;
}
AddPolyn(Pa,Pb);//再运行加法函数。
}
void CalPolyn(Polynomial &Pa){
Polynomial p1;//初始化
p1 = Pa->next;//指向首元结点
float x,sum = 0,sumAll = 0;//创建x0,结点和sum,总和sumAll
cout<<"请输入x:";
cin>>x;
while (p1) {//链表非空时
sum = pow(x,p1->expn);//通过使用pow函数求x的次方
sum = p1->coef*sum;//结点x0结果等于次方后再乘以系数
sumAll = sum+sumAll;//把结果累加进总和
p1 = p1->next;//指向下一个结点
}
display(Pa);//显示多项式
cout<<"结果为:"<<sumAll;
}
void DerPolyn(Polynomial &Pa){
Polynomial p1;//初始化
p1 = Pa->next;//指向首元结点
cout<<"求导前:";
display(Pa);
while (p1) {//链表非空时
if(p1->expn == 0){//指数为0时候,即是常数求导
p1->coef = 0;//常数求导等于0,系数等于0
p1 = p1->next;//指向下一个结点
}
p1->coef = p1->coef*p1->expn;//系数等于指数乘以系数
p1->expn = p1->expn-1;//系数减一
p1 = p1->next;//指向下一个结点
}
cout<<"求导后:";
display(Pa);
}
void userGuide(){
cout<<"输入1,多项式相加"<<endl;
cout<<"输入2,多项式相减"<<endl;
cout<<"输入3,计算多项式在x=x0处的值"<<endl;
cout<<"输入4,求多项式a的导数函数a’"<<endl;
cout<<"输入5,输出一个多项式"<<endl;
cout<<"输入你要做的操作:";
}
int main()
{
int t,type,n1,n2;
Polynomial p1,p2;
do{
userGuide();
cin>>type;
if(type>5||type<0){
cout<<"输入错误!";
exit(0);
}
switch (type) {
case 1:
cout<<"输入多项式1的项数:";
cin>>n1;
cout<<"输入多项式2的项数:";
cin>>n2;
CreatePolyn(p1,n1);
CreatePolyn(p2,n2);
AddPolyn(p1,p2);
break;
case 2:
cout<<"输入多项式1的项数:";
cin>>n1;
cout<<"输入多项式2的项数:";
cin>>n2;
CreatePolyn(p1,n1);
CreatePolyn(p2,n2);
SubPolyn(p1,p2);
break;
case 3:
cout<<"输入多项式1的项数:";
cin>>n1;
CreatePolyn(p1,n1);
CalPolyn(p1);
break;
case 4:
cout<<"输入多项式1的项数:";
cin>>n1;
CreatePolyn(p1,n1);
DerPolyn(p1);
break;
case 5:
cout<<"输入多项式1的项数:";
cin>>n1;
CreatePolyn(p1,n1);
display(p1);
break;
}
cout<<endl;
cout<<"如需进行其他操作,请输入1:";
cin>>t;
}while (t == 1);
return 0;
}