#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
typedef struct linklist{
double coef; //系数
int expn; //指数
struct linklist *next;//指针域
}linklist,*Link;
Link L1,L2,L3; //多项式
int n1,n2; //多项式长度
//函数声明
void menu();//菜单模式
void creatlist(Link &L,int N); //创建多项式
int cmp(Link L1, Link L2);
int LocateElem(Link p, Link s, Link &q);
Link PolyAdd(Link pa, Link pb); //多项式相加
Link PolySub(Link pa, Link pb); //多项式相减
Link Reverse(Link L); //多项式逆置
Link PolyMulti(Link pa,Link pb); //多项式相乘
void Calculate(Link L, double x); //多项式求值
void Print(Link L); //打印多项式
void menu(){
printf("|------------------------------------------------------------------------------------|\n");
printf("|\t\t\t临沂大学2019计科一班一组多项式的表示及操作\t |\n");
printf("|\t 团队成员 * 操作菜单 * |\n");
printf("| 学号\t姓名\t * * |\n");
printf("|201909150101 田树林 * + : ->多项式相加 * |\n");
printf("|201909150105 高天 * - : ->多项式相减 * |\n");
printf("|201909150115 王得玉 * * : ->多项式相乘 * |\n");
printf("|201909150123 刘一萱 * / : ->多项式相除(该功能还未开放)* |\n");
printf("|201909150130 孙凯民 * ' : ->多项式求导(该功能还未开放)* |\n");
printf("|------------------------------------------------------------------------------------|\n");
printf("请您根据以下指令进行操作\n\n");
printf("请输入第一个多项式的项数: \n");
scanf("%d",&n1);
creatlist(L1,n1);
printf("第一个多项式为: P1(X)=");
Print(L1);
printf("请输入第二个多项式的项数: \n");
scanf("%d",&n2);
creatlist(L2,n2);
printf("第二个多项式为: P2(X)=");
Print(L2);
}
void creatlist(Link &L,int n){
Link s,q;
L=(Link)malloc(sizeof(linklist));
L->next=NULL;
for(int i=0;i<n;i++)
{
s=(Link)malloc(sizeof(linklist));
printf("请输入多项式的系数和指数:\n");
scanf("%lf %d", &s->coef, &s->expn);
if(!LocateElem(L, s, q)){ //若没有相同指数项,则链入
s->next = q->next;
q->next = s;
}
else{ //若有相同指数项,则系数相加
q->coef += s->coef;
}
}
}
void Print(Link L){
Link s;
s = L->next;
while(s)
{
printf(" %.2lf X^%d", s->coef, s->expn);
s = s->next;
if(s!=NULL)
if(s->coef>=0) printf(" +");
//若下一项系数为正,则打印'+',否则不打印
}
printf("\n");
}
int cmp(Link L1, Link L2)
{
if (L1->expn<L2->expn) return -1;
else if(L2->expn == L1->expn) return 0;
else return 1;
}
int LocateElem(Link p, Link s, Link &q){
Link p1 = p->next;
Link p2 = p;
while(p1){
if(s->expn > p1->expn){
p1 = p1->next;
p2 = p2->next;
}
else if(s->expn == p1->expn){
q = p1;
return 1;
}
else{
q = p2;
return 0;
}
}
if(!p1){
q = p2;
return 0;
}
}
Link PolyAdd(Link pa, Link pb){
Link head, L1, L2, s, p;
double sum;
L1 = pa->next;
L2 = pb->next;
head=(Link)malloc(sizeof(linklist)); //新多项式的头结点
p = head; //p指向新多项式的头结点
while(L1&&L2){
switch(cmp(L1, L2))
{
case -1:// //若指数:L1<L2,则将p所指结点链入头结点为head的链表中,且L1向后遍历
s = (Link)malloc(sizeof(linklist));
s->coef = L1->coef;
s->expn = L1->expn;
p->next = s;
p = s;
L1 = L1->next;
break;
case 0://若比较两项的指数相等,则将两项系数相加后得到的项放入头结点为head的链表中 ,且L1,L2同时向后遍历
sum = L1->coef+L2->coef;
if(sum!=0.0)//若两项系数相加为0,则不放入头结点为head的链表中
{
s = (Link)malloc(sizeof(linklist));
s->coef = sum;
s->expn = L1->expn;
p->next = s;
p = s;
}
L1 = L1->next;
L2 = L2->next;
break;
case 1://若指数:L2<L1,则将L2所指结点链入头结点为head的链表中,且L2向后遍历
s = (Link)malloc(sizeof(linklist));
s->coef = L2->coef;
s->expn = L2->expn;
p->next = s;
p = s;
L2 = L2->next;
break;
}
}
p->next=L1?L1:L2;//链入pa或pb的剩余项
return head;//返回新多项式的头指针
}
Link PolySub(Link pa, Link pb)
{
Link head, L1, L2, s, p;
double sum;
head=(Link)malloc(sizeof(linklist));
p = head;
L1 = pa->next;
L2 = pb->next;
while(L2){// 将pb中每一项的系数变为负
L2->coef=0-L2->coef;
L2=L2->next;
}
L2=pb->next;
while(L1&&L2){
switch(cmp(L1, L2))
{
case -1:
s = (Link)malloc(sizeof(linklist));
s->coef = L1->coef;
s->expn = L1->expn;
p->next = s;
p = s;
L1 = L1->next;
break;
case 0:
sum = L1->coef-L2->coef;
if(sum!=0.0)
{
s = (Link)malloc(sizeof(linklist));
s->coef = sum;
s->expn = L1->expn;
p->next = s;
p = s;
}
L1 = L1->next;
L2 = L2->next;
break;
case 1:
s = (Link)malloc(sizeof(linklist));
s->coef = L2->coef;
s->expn = L2->expn;
p->next = s;
p = s;
L2 =L2->next;
break;
}
}
p->next=L1?L1:L2;
return head;
}
Link Reverse(Link L)
{
Link head=L;
Link q1,q2;
q2=head->next;
head->next=NULL;//断开头结点与第一个结点
while(q2)
{
q1=q2;
q2=q2->next;
q1->next=head->next; //头插
head->next=q1;
}
return head;//返回链表逆置后的头结点
}
Link PolyMulti(Link pa,Link pb){
Link L1,L2,L3,s,head;
int k,maxExpn,minExpn;
double coef;
head=(Link)malloc(sizeof(linklist));//头结点
head->next=NULL;
if(pa->next!=NULL&&pb->next!=NULL){
minExpn=pa->next->expn+pb->next->expn; //minExpn为两个多项式中指数和的最小值
pa=Reverse(pa);//将A降幂排列
pb=Reverse(pb);//将B降幂排列
maxExpn=pa->next->expn+pb->next->expn; //maxExpn为两个多项式中指数和的最大值
}
else{
return head;
}
L3=head;
pb=Reverse(pb);//将B升幂排列
for(k = maxExpn;k>=minExpn;k--){ //多项式的乘积指数范围为:minExpn~maxExpn
//根据两项的指数和使每一次循环都得到新多项式中一项
L1 = pa->next;
while(L1 !=NULL&&L1->expn>k){ //找到pa的位置
L1 = L1->next;
}
L2 = pb->next;
while(L2!=NULL&&L1!=NULL&&L1->expn+L2->expn<k){//如果指数和和小于k,pb后移结点
L2 = L2->next;
}
coef=0.0;
while(L1!=NULL&&L2!=NULL){
if(L1->expn+L2->expn==k){ //如果指数和等于k,系数和累加,且pa,pb均后移结点
coef+=L1->coef*L2->coef;
L1=L1->next;
L2=L2->next;
}
else if(L1->expn+L2->expn>k){//如果指数和大于k,pb后移结点
L1 = L1->next;
}
else{//如果指数和和小于k,pb后移结点
L2 = L2->next;
}
}
if(coef!=0.0){
//如果系数和不为0,则生成新结点,将系数和指数赋给新结点后插入到新多项式中
s=(Link)malloc(sizeof(linklist));
s->coef=coef;
s->expn=k;
s->next=L3->next;
L3->next=s;
L3=s;
}
}
pb = Reverse(pb);
head=Reverse(head);
return head; //返回新多项式的头结点
}
void Calculate(Link L, double x){
Link q=L->next;
double sum;
double result=0;//求的结果
while(q){
sum=1.0;
for(int i=1;i<=q->expn;i++){//先求每一项的 X^expn 的值
sum=sum*x;
}
result+=sum*q->coef; //再使系数与sum相乘后求每一项的值,最后累加
q=q->next;
}
printf("将X的值代入多项式中计算的结果为:%.4f\n",result);
}
int main()
{
system("color 2F");
menu() ;//实现系统桌面模拟化;
//以下是对多项式的操作命令
printf("请输入要选择的运算{+ , - , * , / , dy/dx }\n");
char ch1;
getchar();
scanf("%c",&ch1);
getchar();
switch(ch1){
case '+':{
printf("两个一元多项式相加: P1(X)+P2(X) = ");
L3=PolyAdd(L1, L2);
Print(L3);
}break;
case '-':{
printf("两个一元多项式相减: P1(X)-P2(X) = ");
L3=PolySub(L1, L2);
Print(L3);
}break;
case '*':{
printf("两个一元多项式相乘: P1(X)*P2(X) = ");
L3=PolyMulti(L1, L2);
Print(L3);
}break;
case '/':{
printf("该功能还在升级;未开放!");
}return 0;
case 'dy/dx':{
printf("该功能还在升级;未开放!");
}return 0;
default:printf("You entered the wrong command %c !",ch1);return 0;
}
//对多项式的带入求值
char ch2;
printf("\n是否代入X进行求值(Y/N): ");
ch2=getchar();
getchar();
switch(ch2){
case 'Y':{
double x;
printf("\n请输入多项式中X的值:");
scanf("%lf",&x);
Calculate(L3,x);
break;
}
case 'N':break;
default:printf("You entered the wrong command %c !",ch2);
}
return 0;
}
2020-4月数据结构课设--一元多项式的表示及其运算
最新推荐文章于 2023-03-27 19:31:04 发布