一元稀疏多项式计算器 【 数据结构课设 】 仿真界面 + 代码详解

if (a&&b) // 多项式a和b均不为空

{

if (a->expn > b->expn) return 1;// a的指数大于b的指数

else if (a->expn < b->expn) return -1;

else return 0;

}

else if (!a&&b) return -1; //a为空,b不为空

else if (a&&!b) return 1; //b为空,a不为空

else if (!a&&!b)return 0; //a,b均为空

}

Polyn addPolyn(Polyn a, Polyn b) //求解a+b,并返回头结点head

{

Polyn head ,qc;

Polyn qa = a->next;

Polyn qb = b->next;

Polyn hc=(Polyn)malloc(sizeof(Polynomial));

hc->next = NULL;

head = hc;

while (qa || qb)

{

qc= (Polyn)malloc(sizeof(Polynomial));

if (compare(qa, qb) == 1)

{

qc->coef = qa->coef;

qc->expn = qa->expn;

qa = qa->next;

}

else if (compare(qa, qb) == 0) //指数相同,直接相加

{

qc->coef = qa->coef + qb->coef;

qc->expn = qa->expn ;

qa = qa->next;

qb = qb->next;

}

else

{

qc->coef = qb->coef;

qc->expn = qb->expn;

qb = qb->next;

}

if (qc->coef != 0) //将该节点插入链表中

{

qc->next = hc->next;

hc->next = qc;

hc = qc;

}

else free(qc);

}

return head;

}

Polyn subPolyn(Polyn a, Polyn b)

{

Polyn h = b;

Polyn p = b->next;

while§

{

p->coef *= -1;

p = p->next;

}

Polyn head = addPolyn(a, h);

for (Polyn i = h->next; i != 0; i = i->next)

{

i->coef *= -1;

}

return head;

}

double value(Polyn head, int x) //计算x的值

{

double sum = 0;

for (Polyn p = head->next; p != 0; p = p->next)

{

int tmp = 1;

int expn = p->expn;

while(expn != 0) //指数不为0

{

if (expn < 0) tmp /= x, expn++;

else if(expn>0) tmp *= x, expn–;

}

sum += p->coef*tmp;

}

return sum;

}

int main()

{

int m;

Polyn a = 0, b = 0;

printf(“请输入a的项数:”);

scanf(“%d”, &m);

a = CreatPolyn(a, m);

printPoLlyn(a);

printf(“请输入b的项数:”);

scanf(“%d”, &m);

b = CreatPolyn(b, m);

printPoLlyn(b);

printf(“输出 a+b:”);

printPoLlyn(addPolyn(a, b));

printf(“输出 a-b:”);

printPoLlyn(subPolyn(a, b));

printf(“请输入x的值:”);

int x;

scanf(“%d”, &x);

printf(“输出a的多项式的值为:%.2lf”, value(a,x));

return 0;

}

/*

测试数据:

3

2 1

5 8

-3.1 11

3

7 0

-5 8

11 9

1

*/

设计详解

1、一元稀疏多项式的建立

结构体的定义

typedef struct Polynomial //多项式

{

float coef; //系数

int expn; //指数

struct Polynomial *next;//指针

} Polynomial, *Polyn;

使用带头结点的单链表存贮多项式,插入查找和删除较为方便。数据域中存贮系数和指数,指针域指向下一个节点的位置。

在这里插入图片描述

如果所示的存贮结构:

在这里插入图片描述

设计思想:

首先确定好多项式的项数m,新建立一个节点p,用来存贮读入的系数coef和项数expn。然后再定义两个指针q1q2,一前一后,分别指向多项式的两个相邻节点。为了实现多项式的降序排列,这里我们利用插入排序的思想,如果pq2的指数相同,即p->expn == q2->expn,则进行两个节点的合并。如果p的指数小于q2的指数,即p->expn < q2->expn,继续后移两个指针。否则,p的指数小于q1的指数,大于q2的指数,我们找到了插入的位置,将p节点插入两个节点中。执行m次插入操作,就将一元稀疏多项式的建立好了。最后注意要将系数coef==0的节点释放。

定义两个指针:

在这里插入图片描述

找到了插入位置,将节点p插入

在这里插入图片描述

代码

//创建一个头指针为head,项数为m的一元稀疏多项式

void CreatPolyn(Polyn head, int m)

{

for (int i = 1; i <= m; i++)

{

Polyn p = (Polyn)malloc(sizeof(struct Polynomial)); //新建节点p

printf(“请输入第%d项的系数与指数:”, i);

scanf(“%f%d”, &p->coef, &p->expn);

if (p->coef == 0) free§; //将系数为0的节点释放

else

{

Polyn q1, q2; //两个指针一前一后

q1 = head;

q2 = head->next;

while (q2 != NULL && p->expn < q2->expn) //p的指数小于q2的指数

{

q1 = q2; //继续后移两个指针

q2 = q2->next;

}

if (q2 != NULL && p->expn == q2->expn) //将相同指数的项进行合并

{

q2->coef += p->coef; //合并两项

if (q2->coef == 0)

{

q1->next = q2->next;

free(q2); //将系数为0的节点释放

}

free§; //将节点p释放

}

else

{

p->next = q2; //将节点p插入到q1和q2之间

q1->next = p;

}

}

}

}

2.一元稀疏多项式的加法和减法运算

设计思想:

关于多项式的加法运算。首先要定义一个比较函数compare,来比较两个多项式的每项指数大小。

我们从头到尾处理两个多项式的每一项。如果两项中,多项式a的项的指数大于多项式b的项的指数,那么将a的此项直接作为多项式c的一项。如果多项式a的指数等于多项式b的指数,将两项合并作为多项式c的一项。如果多项式a的指数小于多项式b的指数,那么将b的此项直接作为多项式c的一项。

因为多项式a和多项b的都是按照指数降序建立的,因此,指数大的项会被先计算出来,使用尾插法插入多项式c中,这样多项式c也是按照指数降序排列的。而减法就是将a-b改为a+(-b)。我们将b的每一项系数都取相反数,最后按照加法计算。

图示过程:

在这里插入图片描述

c = a+b

将计算出来的qc节点使用尾插法插入多项式c中,然后再将hc=qchc指针后移一位,指向新插入的节点qc

在这里插入图片描述

使用尾插法,qc是最后一个包含数据域的节点,因此hc->next==NULL。多项式c仍按照指数降序排列。

代码

int compare(Polyn a, Polyn b)//比较两个多项式每项的大小

{

if (a&&b) // 多项式a和b均不为空

{

if (a->expn > b->expn) return 1; // a的指数大于b的指数,返回1

else if (a->expn < b->expn) return -1; //a的指数小于b的指数,返回-1

else return 0; //a的指数等于b的指数,返回0

}

else if (!a&&b) return -1; //a为空,b不为空

else if (a&&!b) return 1; //b为空,a不为空

else if (!a&&!b)return 0; //a,b均为空

}

//一元稀疏多项式的加法和减法运算

Polyn addPolyn(Polyn a, Polyn b)

Polyn head ,qc;

Polyn qa = a->next;

Polyn qb = b->next;

Polyn hc=(Polyn)malloc(sizeof(Polynomial)); //新建节点 hc

hc->next = NULL;

head = hc; //头结点head指向 hc

while (qa || qb)

{

qc= (Polyn)malloc(sizeof(Polynomial)); //用来存贮计算出来的多项式c的每一项

if (compare(qa, qb) == 1) //多项式a的项的指数大于多项式b的项的指数

{

qc->coef = qa->coef; //a的该项直接作为c的一项

qc->expn = qa->expn;

qa = qa->next;

}

else if (compare(qa, qb) == 0) //指数相同,两项相加作为c的一项

{

qc->coef = qa->coef + qb->coef;

qc->expn = qa->expn ;

qa = qa->next;

qb = qb->next;

}

else //多项式a的项的指数小于多项式b的项的指数

{

qc->coef = qb->coef; //b的该项直接作为c的一项

qc->expn = qb->expn;

qb = qb->next;

}

if (qc->coef != 0) //将qc节点插入链表中

{

qc->next = hc->next;

hc->next = qc;

hc = qc; //hc后移一位,指向新插入的节点qc

}

else free(qc);

}

return head;

}

Polyn subPolyn(Polyn a, Polyn b) //多项式减法运算

{

Polyn h = b;

Polyn p = b->next;

while§ //将b的每一项系数都取相反数

{

p->coef *= -1;

p = p->next;

}

Polyn head = addPolyn(a, h); //计算 a + (-b)

for (Polyn i = h->next; i != 0; i = i->next) //最后再将b的每项系数还原

{

i->coef *= -1;

}

return head;

}

3.一元稀疏多项式的打印和计算在x处的值

打印输出

按照这种格式 5x^8-3.1x^11+2x 进行打印输出。从头到尾遍历多项式,特殊处理系数为1-1。系数为1时,输出'x',为-1时,输出'-x',为其他时输出x^,或者 -x^。然后在'x'的后边将每项的指数格式输出。通过对系数和指数的情况分类讨论,正确输出+号和-号。具体思路见代码。

在这里插入图片描述

代码

void printPoLlyn(Polyn head)

{

Polyn q = head->next;

int flag = 0; //记录是否为第一项

if (!q)

{

puts(“NULL(0)\t”);

return;

}

while (q) //coef是系数,expn是指数

{

if (q->coef > 0 && flag == 1) //系数为正,且不为第一项

{

printf(“+”); //输出加号

}

flag = 1;

if (q->coef != 1 && q->coef != -1) //系数不为-1或者1

{

printf(“%g”, q->coef); //输出系数

if (q->expn == 1) printf(“x”); //指数为1,输出x

else if (q->expn != 0) printf(“x^%d”, q->expn);

}

else

{

if (q->coef == 1) //系数为1

{

if (q->expn == 0) printf(“1”); //指数为0,按照常数1输出

else if (q->expn == 1) printf(“x”); //指数为1,输出x

else printf(“x^%d”, q->expn);

}

if (q->coef == -1) //系数为-1

{

if (q->expn == 0) printf(“-1”);

else if (q->expn == 1) printf(“-x”);

else printf(“-x^%d”, q->expn);

}

}

q = q->next; //将q指针后移

}

printf(“\t\t”);

}

计算多项式在x的值

遍历要计算的多项式的每一项,定义一个临时变量tmp。当该项的指数expn不为0时,如果为负数,我们进行tmp /= x, expn++。如果为正数,我们进行tmp *= x, expn--。重复上述操作,直到expn==0时停止。最后将每一项的值累加起来,记录到sum中,执行sum += p->coef*tmp 操作,便得到了多项式在x处的值。

在这里插入图片描述

代码

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

Ending

Tip:由于文章篇幅有限制,下面还有20个关于MySQL的问题,我都复盘整理成一份pdf文档了,后面的内容我就把剩下的问题的目录展示给大家看一下

如果觉得有帮助不妨【转发+点赞+关注】支持我,后续会为大家带来更多的技术类文章以及学习类文章!(阿里对MySQL底层实现以及索引实现问的很多)

吃透后这份pdf,你同样可以跟面试官侃侃而谈MySQL。其实像阿里p7岗位的需求也没那么难(但也不简单),扎实的Java基础+无短板知识面+对某几个开源技术有深度学习+阅读过源码+算法刷题,这一套下来p7岗差不多没什么问题,还是希望大家都能拿到高薪offer吧。

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!**

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

Ending

Tip:由于文章篇幅有限制,下面还有20个关于MySQL的问题,我都复盘整理成一份pdf文档了,后面的内容我就把剩下的问题的目录展示给大家看一下

如果觉得有帮助不妨【转发+点赞+关注】支持我,后续会为大家带来更多的技术类文章以及学习类文章!(阿里对MySQL底层实现以及索引实现问的很多)

[外链图片转存中…(img-Ux1qFTP7-1713561120936)]

[外链图片转存中…(img-E74Feuhh-1713561120937)]

吃透后这份pdf,你同样可以跟面试官侃侃而谈MySQL。其实像阿里p7岗位的需求也没那么难(但也不简单),扎实的Java基础+无短板知识面+对某几个开源技术有深度学习+阅读过源码+算法刷题,这一套下来p7岗差不多没什么问题,还是希望大家都能拿到高薪offer吧。

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 16
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值