一元多项式的运算
一、实验目的
1.熟练掌握C/C++语言中指针的操作。
2.掌握链表的常用算法。
二、问题描述
一元多项式可以表示为线性表,相应地一元多项式的运算可以用线性表的基本运算来实现。本实验要求以链表为存储结构,设计一个一元多项式运算器,实现一元多项式的创建、销毁、复制、打印显示、四则运算等功能。
三、实验内容
实现一元多项式运算器的基本功能:
(1)创建多项式;
(2)打印显示多项式;
(3)销毁多项式;
(4)复制多项式;
(5)求两个多项式的和;
(6)求两个多项式的差;
(7)求两个多项式的积;
(8)求一个多项式的n次幂;
(9)计算一个多项式在x=a处的值。
四、实现提示
- 由于程序有多项功能,可采用菜单选项的方式来分别调用各项功能。
- 销毁多项式时,要注意释放所有结点的存储空间。
- 求两个多项式的积可分解为一系列多项式求和运算。
```c
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
typedef struct {
float coef;
int expn;
}Datatype;
typedef struct Node {
Datatype data;
struct Node* next;
}Listnode, * Linklist;
//查找定位算法
int LocateNode(Linklist L, Datatype e, int& q) {
Listnode* p = L->next;
q = 0;//记录节点位置序号
while (p && e.expn < p->data.expn) {
p = p->next; q++;
}
if (p == NULL || e.expn != p->data.expn)
return(0);//查找失败
else
return 1;
}
//在有序表中插入一个数据后仍保持表的有序性
void InsertNode(Linklist& L, Datatype e, int q) {
Listnode* s, * p;
int i = 0;
p = L;
while (p->next && i < q) {
p = p->next;
i++;
}//查找插入位置
s = (Listnode*)malloc(sizeof(Listnode));
s->data.coef = e.coef;
s->data.expn = e.expn;
s->next = p->next;
p->next = s;
}
//多项式复制,将多项式La复制到Lc中
void CopyPolyn(Linklist La, Linklist& Lc) {
Listnode* p, * q, * pc;
p = La->next;
Lc = (Linklist)malloc(sizeof(Listnode));
q = Lc;
pc = Lc;
while (p) {
pc = (Linklist)malloc(sizeof(Listnode));
pc->next = NULL;
q->next = pc;
pc->data.coef = p->data.coef;
pc->data.expn = p->data.expn;
q = q->next;
p = p->next;
}
}
//创建多项式
void CreatPolyn(Linklist& L, int n) {
Linklist pa; int i, q;
Datatype e;
pa = (Listnode*)malloc(sizeof(Listnode));//生成链表的头节点
pa->next = NULL;
for (i = 0; i < n; i++) {
scanf("%f,%d", &e.coef, &e.expn);
if (!LocateNode(pa, e, q))//当前列表中不存在该指数项
InsertNode(pa, e, q);
}
L = pa;
}
//多项式链表的打印
void PrintList(Linklist L) {
Listnode* p;
p = L->next;
while (p) {
printf("%c %.3fX^%d", (p->data.coef > 0 ? '+' : ' '), p->data.coef, p->data.expn);
p = p->next;
}
printf("\n");
}
//多项式链表的相加
void AddPolyn(Linklist La, Linklist Lb, Linklist& Lc) {
//两个有序多项式La Lb得到Lc
Listnode* pa, * pb, * pc, * s;
Linklist w, v;
CopyPolyn(Lb, w);
CopyPolyn(La, v);
float sum;
pa = v->next;
pb = w->next;
Lc = pc = v;
while (pa && pb) {
if (pa->data.expn > pb->data.expn) {
pc->next = pa;
pc = pa;
pa = pa->next;
}
else if (pa->data.expn < pb->data.expn) {
pc->next = pb;
pc = pb;
pb = pb->next;
}
else {
sum = pa->data.coef + pb->data.coef;
if (fabs(sum) > 1e-6) {//系数之和不为零
pa->data.coef = sum;
pc->next = pa; pc = pa; pa = pa->next;
s = pb; pb = pb->next; free(s);
}
else {
s = pa; pa = pa->next; free(s);
s = pb; pb = pb->next; free(s);
}
}
}
pc->next = pa ? pa : pb;
free(w);
}
//多项式链表的相减
void SubPolyn(Linklist La, Linklist Lb, Linklist& Lc) {
Listnode* p;
Linklist w, v;
CopyPolyn(Lb, w);
CopyPolyn(La, v);
p = w->next;
while (p) {
p->data.coef = -p->data.coef;
p = p->next;
}
AddPolyn(v, w, Lc);
}
//销毁多项式
void DesPolyn(Linklist La) {
Listnode* p;
p = La->next;
while (p) {
La->next = p->next;
free(p);
p = La->next;
}
free(La);
La ->next= NULL;
}
void Attach(float c, int e, Linklist* r) {
Linklist p;
p = (Linklist)malloc(sizeof(Listnode));
p->data.coef = c; p->data.expn = e;
p->next = NULL;
(*r)->next = p;
*r = p;
}
//多项式的乘积
Linklist MultiPolyn(Linklist La, Linklist Lb) {
Linklist front, rear, t1, t2;
front = (Linklist)malloc(sizeof(Listnode));
front->next = NULL;
rear = front;
if (!La->next || !Lb->next)
return front;
t1 = La->next; t2 = Lb->next;
while (t2) {
Attach(t1->data.coef * t2->data.coef, t1->data.expn + t2->data.expn, &rear);
t2 = t2->next;
}
t1 = t1->next;
while (t1) {
t2 = Lb->next;
rear = front;
while (t2) {
int e;
float c;
c = t1->data.coef * t2->data.coef;
e = t1->data.expn + t2->data.expn;
while (rear->next && rear->next->data.expn > e)
rear = rear->next;
if (rear->next && rear->next->data.expn == e) {
if (rear->next->data.coef + c)
rear->next->data.coef += c;
else {
rear->next->data.coef = 0;
rear->next->data.expn = 0;
}
}
else {
Linklist t = (Linklist)malloc(sizeof(Listnode));
t->data.coef = c;
t->data.expn = e;
t->next = rear->next;
rear->next = t;
rear = t;
}
t2 = t2->next;
}
t1 = t1->next;
}
return front;
}
//多项式的n次幂
Linklist ExpnPolyn(int n, Linklist L) {
int i;
Linklist p[n];
p[0] = L;
if (n == 1)
return L;
else {
for (i = 1; i < n; i++) {
p[i] = MultiPolyn(p[i - 1], L);
}
}
return p[n - 1];
}
//求多项式的值
float Calculate(Linklist La, int n) {
Listnode* p;
float sum = 0.0;
p = La->next;
while (p) {
sum = sum + p->data.coef * pow(n, p->data.expn);
p = p->next;
}
return(sum);
}
//主函数
int main() {//相加,相减 ,复制 ,相乘
Linklist La, Lb, Lc;
int n, e, flag, p, opt;
float m;
printf("\n_________________________________________\n");
printf("| menu |\n");
printf("| 1)输入,建立并打印多项式 |\n");
printf("| 2)多项式相加 |\n");
printf("| 3)多项式相减 |\n");
printf("| 4)复制多项式 |\n");
printf("| 5)多项式相乘 |\n");
printf("| 6)多项式的n次幂 |\n");
printf("| 7)多项式求x=a的值 |\n");
printf("| 8)销毁多项式 |\n");
printf("| 0)退出 |\n");
printf("|_________________________________________|\n");
while (1) {
printf("选择要进行的操作:");
scanf("%d", &opt);
switch (opt) {
case 0:
exit;
break;
case 1:
printf("输入第一个多项式的项数:");
scanf("%d", &n);
printf("输入第一个多项式的每一项的系数,指数:\n");
CreatPolyn(La, n);
printf("第一个多项式为:");
PrintList(La);
printf("输入第二个多项式的项数:");
scanf("%d", &n);
printf("输入第二个多项式的每一项的系数,指数:\n");
CreatPolyn(Lb, n);
printf("第二个多项式为:");
PrintList(Lb);
break;
case 2:
AddPolyn(La, Lb, Lc);
printf("\n相加后的多项式为:");
PrintList(Lc);
printf("\n");
break;
case 3:
SubPolyn(La, Lb, Lc);
printf("相减后的多项式为:");
PrintList(Lc);
break;
case 4:
CopyPolyn(La, Lc);
printf("\n复制后得到的多项式为:");
PrintList(Lc);
break;
case 5:
Lc = MultiPolyn(La, Lb);
printf("\n相乘后的多项式为:");
PrintList(Lc);
break;
case 6:
printf("输入幂次:");
scanf("%d", &n);
printf("第1个或是第2个求幂次?");
scanf("%d", &p);
Lc = ExpnPolyn(n, p == 1 ? La : Lb);
printf("\n求幂次后的多项式为:");
PrintList(Lc);
break;
case 7:
printf("输入一个值如2进行运算:\n");
scanf("%d", &e);
printf("你要用哪个算?1还是2?:");
scanf("%d", &flag);
m = Calculate(flag == 1 ? La : Lb, e);
printf("%f", m);
break;
case 8:
printf("要销毁第1个还是第2个?");
scanf("%d", &opt);
if (opt == 1)
DesPolyn(La);
if (opt == 2)
DesPolyn(Lb);
printf("剩余的多项式为:");
PrintList(La); printf("\n");
PrintList(Lb);
break;
}
}
return 0;
}
(小声,乘法部分我有借鉴,只是期末了发着玩,难免有人需要,不图啥好处,如果原作者纠结的话请让我删除