功能:实现一元多项式的显示 加法,减法,乘法,求值以及求导
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <conio.h>
#include <ctype.h>
#include <math.h>
//宏定义
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
//#define OVERFLOW -2
typedef int Status;
//typedef char ElemType;
/* 结点类型* */
typedef struct LNode{
float coeff; //多项式的系数
int order; //多项式的阶数
struct LNode *next;
}LNode,*LinkType;
/* 链表类型 */
typedef struct{
LinkType head,tail;
int length;
}LinkList;
/*构建一个新结点 test OK*/
Status MakeNode(LinkType &p,float x,int j)
{
p=(LinkType)malloc(sizeof(LNode));
if(!p) return FALSE;
p->coeff=x;p->order=j;p->next=NULL;return TRUE;
}
/* 释放结点 */
void FreeNode(LinkType &p)
{
free(p);
}
LinkType Copy(LinkType p)
{
LinkType s;
s=(LinkType)malloc(sizeof(LNode));
if(!s) return NULL;
s->coeff=p->coeff;s->order=p->order;s->next=NULL;return s;
}
float Coeffient(LinkType p)
{
if(!p) return FALSE;
return (p->coeff);
}
int Order_multi(LinkType p)
{
if(!p) return FALSE;
return (p->order);
}
/* 结点的后继 */
LinkType SuccNode(LinkType p)
{
LinkType s;
if(!p) return NULL;
s=p->next;
return s;
}
/* 结点的前继 */
LinkType PreNode(LinkType p,LinkList L)
{
LinkType s;
if(!p||!L.head||L.length<1) return NULL;
s=L.head;
while(s!=L.tail&&s->next!=p) {
s=SuccNode(s);
}
if(s->next==p) return s;
return NULL;
}
Status InitList(LinkList &L); //初始化链表
void DestroyList(LinkList &L);//销毁链表
Status ListEmpty(LinkList L); //链表是否为空
int ListLength(LinkList L); //链表的长度
LinkType GetElemPos(LinkList L,int pos);// 查找第pos个元素的指针
Status LocateElem(LinkList L,int j,LinkType &q); //
void Append(LinkList &L,LinkType s); //在已存在的链表L末尾添加指针s指向的结点
void InsertAfter(LinkList &L,LinkType q,LinkType s); //在已存在的链表L中q所指示的结点之后插入指针s所指向的结点
void ListTraverse(LinkType p,Status (*visit)(LinkType));//从p(p!=NULL)指示的结点开始,依次对每个结点调用函数visit
/* 初始化链表 test OK */
Status InitList(LinkList &L)
{
if(MakeNode(L.head,0.0,0)) {
L.tail=L.head;L.length=0; return TRUE;
}
else {
L.head=NULL;return FALSE;
}
}
/* 销毁链表 */
void DestroyList(LinkList &L)
{
LinkType p,q;
p=L.head;
while(p) {q=p;p=SuccNode(p);FreeNode(q);}
L.head=L.tail=NULL;
}
/* 查找第pos个元素的指针 */
LinkType GetElemPos(LinkList L,int pos)
{
LinkType p;
int k;
if(!L.head||pos<0||pos>L.length) return NULL;
else if (pos==L.length) return L.tail;
else{
p=L.head->next;k=1;
while(p&&k<pos) {p=SuccNode(p);k++;}
return p;
}
}
//j 表示多项式的阶数
Status LocateElem(LinkList L,int j,LinkType &p)
{
LinkType pre;
if(L.head){
pre=L.head;p=pre->next;
while(p&&p->order<j) {pre=p;p=SuccNode(p);}
}
if(p&&p->order==j) return TRUE;
else {p=pre;return FALSE;}
}
//在表尾添加节点
void Append(LinkList &L,LinkType s)
{
if(L.head&&s){
if(L.tail!=L.head) L.tail->next=s;
else L.head->next=s;
L.tail=s;
L.length++;
}
}
//插入节点
void InsertAfter(LinkList &L,LinkType q,LinkType s)
{
if(L.head&&q&&s){
s->next=q->next;q->next=s;
if(L.tail==q) L.tail=s;
L.length++;
}
}
//遍历节点
void ListTraverse(LinkType p,Status (*visit)(LinkType))
{
while(p) {(*visit)(p);p=SuccNode(p);}
}
typedef LinkList MultiFormula;
/* 创建多项式 */
void CreatFormula(MultiFormula &T,float x[],int j[],int unit_num)
{
int i;
LinkType p,q,s;
if(!InitList(T)) {printf("error\n");T.head=NULL;}
else{
for(i=0;i<unit_num;i++){
if(x[i]==0.0) continue;
else if(!LocateElem(T,j[i],p)) {if(MakeNode(q,x[i],j[i])) InsertAfter(T,p,q);}
else {
p->coeff+=x[i];
//系数为0的情况 处理情况
if(p->coeff==0) {
s=PreNode(p,T);
s->next=p->next;free(p);
}
}
}
}
}
/* 销毁多项式 */
void DestroyFormula(MultiFormula &T)
{
DestroyList(T);
}
/* 两个一元多项式求和 beta2 */
void AddFormula(MultiFormula &T,MultiFormula S1,MultiFormula S2)
{
LinkType p1,p2,s;
int c1,c2;
float d1;
if(!InitList(T)) T.head=NULL;
else{
p1=GetElemPos(S1,1);p2=GetElemPos(S2,1);
while(p1&&p2){
c1=Order_multi(p1);c2=Order_multi(p2);
if(c1==c2) {
d1=Coeffient(p1)+Coeffient(p2);
if(d1!=0) {if(MakeNode(s,d1,c1)) Append(T,s);}
p1=SuccNode(p1);p2=SuccNode(p2);
}
else if (c1<c2) {Append(T,Copy(p1));p1=SuccNode(p1);}
else {Append(T,Copy(p2));p2=SuccNode(p2);}
}
while(p1) {Append(T,Copy(p1));p1=SuccNode(p1);}
while(p2) {Append(T,Copy(p2));p2=SuccNode(p2);}
}
}
/* 两个一元多项式之差 beta2 */
void MinusFormula(MultiFormula &T,MultiFormula S1,MultiFormula S2)
{
LinkType p1,p2,s;
int c1,c2;
float d1;
if(!InitList(T)) T.head=NULL;
else{
p1=GetElemPos(S1,1);p2=GetElemPos(S2,1);
while(p1&&p2){
c1=Order_multi(p1);c2=Order_multi(p2);
if(c1==c2) {
d1=Coeffient(p1)-Coeffient(p2);
if(d1!=0) {if(MakeNode(s,d1,c1)) Append(T,s);}
p1=SuccNode(p1);p2=SuccNode(p2);
}
else if (c1<c2) {Append(T,Copy(p1));p1=SuccNode(p1);}
else {
d1=0-Coeffient(p2);
if(MakeNode(s,d1,c2)){Append(T,s);p2=SuccNode(p2);}
}
}
while(p1) {Append(T,Copy(p1));p1=SuccNode(p1);}
while(p2) {
d1=0-Coeffient(p2);
if(MakeNode(s,d1,c2)) {Append(T,s);p2=SuccNode(p2);}
}
}
}
/* 两个一元多项式的乘积 */
void MultiplyFormula(MultiFormula &T,MultiFormula S1,MultiFormula S2)
{
int i;
LinkType p1,p2,p,r,q;
int c1,c2;
float a1,a2;
if(!InitList(T)) T.head=NULL;
else{
if(S1.length>S2.length) {p1=GetElemPos(S1,1);p2=GetElemPos(S2,1);}
else {p1=GetElemPos(S2,1);p2=GetElemPos(S1,1);}
r=p1;
while(p2){
c2=Order_multi(p2);a2=Coeffient(p2);
while(p1){
c1=Order_multi(p1);a1=Coeffient(p1);
c1=c1+c2;a1=a1*a2;
if(!LocateElem(T,c1,p)) {if(MakeNode(q,a1,c1)) InsertAfter(T,p,q);}
else {p->coeff+=a1;}// 已添加 系数相加肯能0的情况 个人认为应该在多项式生成后再处理;
p1=SuccNode(p1);
}
p1=r;
p2=SuccNode(p2);
}
//处理系数为零的情况
p1=GetElemPos(T,1);;p2=T.head;
while(p1) {
if(p1->coeff==0) {p2->next=p1->next;FreeNode(p1);p1=SuccNode(p2);T.length--;}
else {p2=p1;p1=SuccNode(p1);}
}
}
}
/* 多项式的求值 */
Status CalFormula(MultiFormula T,float &x,float &y)
{
char exe_cal;
LinkType p;
printf("\n请问是否给出x的取值,计算多项式的取值?\n");
printf("\t(Y/N)? ");
exe_cal=getche();
do{
switch(exe_cal){
case 'y':
case 'Y': printf("\n\t请输入x的取值: ");
scanf("%f",&x);
if(!T.head||T.length<1) return FALSE;
p=GetElemPos(T,1);
while(p) {
y=y+(p->coeff)*pow(x,p->order);
p=SuccNode(p);
}
break;
case 'n':
case 'N': printf("\n无输入 无输出\n");break;
default : break;
}
}while(exe_cal!='Y'&&exe_cal!='y'&&exe_cal!='N'&&exe_cal!='n');
return OK;
}
/* 多项式的求导 */
Status DerivativeFormula(MultiFormula &T,MultiFormula S1)
{
LinkType p,q;
int c;
float a;
if(!InitList(T)) T.head=NULL;
else{
p=GetElemPos(S1,1);
while(p){
if(p->order!=0) {
c=Order_multi(p);a=Coeffient(p);
a=a*c;
c--;
if(MakeNode(q,a,c)){Append(T,q);}
}
p=SuccNode(p);
}
}
}
void WriteElem(LinkType p)
{
if(p->order==0) {printf("%.2f",p->coeff);}
else if(p->order>0) {printf("%.2fx^%d",p->coeff,p->order);}
else {printf("%.2fx^(%d)",p->coeff,p->order);}
}
Status WriteSetElem(LinkType p)
{
if(p->coeff>0) printf("+");
WriteElem(p);
return OK;
}
void PrintSet(MultiFormula T)
{
LinkType p;
Status stat;
p=GetElemPos(T,1); //取第一个元素的地址
printf("f(x)=");
if(p) {
WriteElem(p);p=SuccNode(p);
}
else {printf("0");}
ListTraverse(p,WriteSetElem);
}
void ReadCommand(char &cmd)
{
printf("\n\n请输入选项:");
do{
cmd=getche();
}while(cmd!='1'&&cmd!='2'&&cmd!='a'&&cmd!='A'&&cmd!='p'&&cmd!='P'&&cmd!='m'&&cmd!='M'&&cmd!='q'&&cmd!='Q');
}
void Interpret(char cmd,MultiFormula &Set1,MultiFormula &Set2,MultiFormula &Set3)
{
int i,j,k;
float x=0,y=0;
MultiFormula Set4;
switch(cmd){
case '1':
printf("\n请输入多项式a的项数:");
scanf("%d",&i);
float c[i];
int dd[i];
printf("\n请输入多项式a的各项的系数与阶数:\n");
printf("格式如下: 1.2,6\n");
printf("其中1.2为系数,6为阶数\n");
for(k=0;k<i;k++)
{
printf("\t第%d项:",k+1);
scanf("%f,%d",&c[k],&dd[k]);
}
CreatFormula(Set1,c,dd,i);
printf("多项式a为\n\t");
PrintSet(Set1);
CalFormula(Set1,x,y);
printf("\tWhen x=%.2f,f(x)=%.2f\n",x,y);
printf("\n");
break;
case '2':
printf("\n请输入多项式b的项数:");
scanf("%d",&j);
float d[j];
int ee[j];
printf("请输入多项式b的各项的系数与阶数:\n");
printf("格式如下: 1.2,6\n");
printf("其中1.2为系数,6为阶数\n");
for(k=0;k<j;k++)
{
printf("\t第%d项:",k+1);
scanf("%f,%d",&d[k],&ee[k]);
}
CreatFormula(Set2,d,ee,j);
printf("多项式b为:\n\t");
PrintSet(Set2);
CalFormula(Set2,x,y);
printf("\tWhen x=%.2f,f(x)=%.2f\n",x,y);
printf("\n");
break;
case 'a':
case 'A': AddFormula(Set3,Set1,Set2);
printf("\n多项式a与多项式b的和c为:\n\t");
PrintSet(Set3);
CalFormula(Set3,x,y);
printf("\tWhen x=%.2f,f(x)=%.2f\n",x,y);
DestroyList(Set3);
printf("\n");
break;
case 'p':
case 'P': MinusFormula(Set3,Set1,Set2);
printf("\n多项式a与多项式b的差c为:\n\t");
PrintSet(Set3);
CalFormula(Set3,x,y);
printf("\tWhen x=%.2f,f(x)=%.2f\n",x,y);
DestroyList(Set3);
printf("\n");
break;
case 'm':
case 'M': MultiplyFormula(Set3,Set1,Set2);
printf("\n多项式a与多项式b的乘积c为:\n\t");
PrintSet(Set3);
CalFormula(Set1,x,y);
printf("\tWhen x=%.2f,f(x)=%.2f\n",x,y);
DestroyList(Set3);
printf("\n");
break;
}
}
void Initialization()
{
printf("\t\t\t一元多项式的求解\n");
printf("****************************************************************************\n");
printf("\t1.建立多项式a\t2.建立多项式b\ta(A).多项式相加\n");
printf("\tp(P).多项式相减 \tm(M).多项式相乘\n");
printf("****************************************************************************\n");
}
int main(int argc, char *argv[])
{
char cmd;
MultiFormula Set1,Set2,Set3;
Initialization();
do{
ReadCommand(cmd);
Interpret(cmd,Set1,Set2,Set3);
}while(cmd!='q'&&cmd!='Q');
system("cls");
system("PAUSE");
return 0;
}