一、实验要求

二、代码实现

以下C语言代码实现了多项式的加减法、乘法、求导和顶点求值的功能。

(水平有限,代码存在不规范之处)

编程环境Window11 + Visual Studio

#define _CRT_SECURE_NO_WARNINGS 1# include # include # include # include # define Error -1# define OK 1//一个节点记录多项式中的一项typedef struct Polynode{float coef; //系数int exp;//指数struct Polynode* next;}Polynode, * Polypointer;void Menu(Polypointer a, Polypointer b);Polypointer InitialNode(void);int CreatePolynomial(Polypointer a, char* filename);void PrintPoly(Polypointer a);Polypointer CopyPoly(Polypointer a);Polynode* AttachNode(float ceof, int e, Polynode* pre);void AddPoly(Polypointer a, Polypointer b, Polypointer c);void MinusPoly(Polypointer a, Polypointer b, Polypointer c);void MultiPoly(Polypointer a, Polypointer b, Polypointer c);void MultiPoly_2(Polypointer a, Polypointer b, Polypointer c);Polypointer DiffPoly(Polypointer a, int k);double GetValue(Polypointer a, double x);int Write(Polypointer a, char* outfile);void ClearList(Polypointer a);//int ReadFromOnefile(Polypointer a,Polypointer b,char*file);int main(void){Polypointer a = InitialNode();Polypointer b = InitialNode();Polypointer c = InitialNode();Polypointer d = InitialNode();Polypointer e = InitialNode();Polypointer f = InitialNode();char* file1 = "Polynomial01.txt";char* file2 = "Polynomial02.txt";char* outfile = "OutPolynomial.txt";CreatePolynomial(a, file1);CreatePolynomial(b, file2);int order;do{Menu(a, b);printf("\n请输入指令:\t");scanf("%d", &order);switch (order){case 0:printf("退出\n");break;case 1:{printf("\nf1+f2=");AddPoly(a, b, c);PrintPoly(c);Write(c, outfile);break;}case 2:{printf("\nf1-f2=");MinusPoly(a, b, d);PrintPoly(d);Write(d, outfile);break;}case 3:{printf("\nf1*f2=");MultiPoly_2(a, b, e);PrintPoly(e);Write(e, outfile);break;}case 4:{int k;do{printf("请输入求导的阶数\n");scanf("%d", &k);} while (k next) PrintPoly(f);elseprintf("0\n");Write(f, outfile);break;}case 5:{printf("请输入x来求值f1(x)\n");double x;scanf("%lf", &x);double value = GetValue(a, x);printf("\nf1(%.2lf) = %.3lf", x, value);break;}default:printf("指令不存在\n");break;}} while (order);return 0;}void Menu(Polypointer a, Polypointer b){printf("\n-----------------------------------\n");printf("链表实现多项式的运算\n");printf("f1 = ");PrintPoly(a);printf("f2 = ");PrintPoly(b);printf("1:加法\n");printf("2:减法 f1-f2\n");printf("3:乘法\n");printf("4:对f1求k阶导\n");printf("5:对f1求值\n");printf("0:退出\n");printf("-----------------------------------\n");return;}//创建链表的头节点,初始化链表Polypointer InitialNode(void){Polynode* p = (Polynode*)malloc(sizeof(Polynode));if (p == NULL) return NULL;p->coef = 0;p->exp = 0;p->next = NULL;return p;}//从文件中读取多项式信息,并创建降序排列的多项式int CreatePolynomial(Polypointer a, char* filename){FILE* fp;fp = fopen(filename, "r");if (fp == NULL){printf("file open failure\n");return Error;}Polynode* q = NULL;while (feof(fp) == 0)//feof非0表示未到文件末尾{q = (Polynode*)malloc(sizeof(Polynode));//申请新的节点,把读到的数据放到q指向的节点中if (q == NULL) return Error;q->next = NULL;fscanf(fp, "%f %d", &q->coef, &q->exp);if (q->coef == 0)//若读到的系数为0,释放该节点{free(q);continue;}Polynode* pre = a;Polynode* cur = a->next;while (cur && q->exp exp) //找比q中指数小的节点{pre = cur;cur = pre->next;}if (cur && cur->exp == q->exp) //若链表中已经存在指数相等节点,系数相加即可{cur->coef = cur->coef + q->coef;free(q);if (cur->coef == 0){pre->next = cur->next;free(cur);}continue;}pre->next = q;//把q节点接入到链表中q->next = cur;}fclose(fp);return OK;}//将多项式打印到屏幕上void PrintPoly(Polypointer a){Polynode* p = a->next;while (p){if (p->coef > 0){printf("+");}printf("%.2fx^%d", p->coef, p->exp);p = p->next;}printf("\n");return;}//为申请的节点赋值,并且链接到pre后面Polynode* AttachNode(float c, int e, Polynode* pre){Polynode* temp = (Polynode*)malloc(sizeof(Polynode));if (temp == NULL)return NULL;temp->next = NULL;temp->coef = c;temp->exp = e;pre->next = temp;return temp;}//两个一元多项式相加void AddPoly(Polypointer a, Polypointer b, Polypointer c){Polynode* p1 = a; //p1指向第一个多项式Polynode* p2 = b; //p2指向第二个多项式Polynode* cur = c;while (p1 && p2){if (p1->exp > p2->exp){cur = AttachNode(p1->coef, p1->exp, cur);p1 = p1->next;}else if (p2->exp > p1->exp){cur = AttachNode(p2->coef, p2->exp, cur);p2 = p2->next;}else if (p1->exp == p2->exp){float sum = p1->coef + p2->coef;if (fabs(sum) next;p2 = p2->next;}else{cur = AttachNode(sum, p1->exp, cur);p1 = p1->next;p2 = p2->next;}}}while (p1){cur = AttachNode(p1->coef, p1->exp, cur);p1 = p1->next;}while (p2){cur = AttachNode(p2->coef, p2->exp, cur);p2 = p2->next;}}//多项式减法 多项式a减多项式bvoid MinusPoly(Polypointer a, Polypointer b, Polypointer c){Polypointer copyb;copyb = CopyPoly(b);Polynode* p = copyb->next;while (p){p->coef = p->coef * (-1);p = p->next;}AddPoly(a, copyb, c);return;}//多项式乘法乘法通过多项式的累加实现void MultiPoly(Polypointer a, Polypointer b, Polypointer c){Polynode* p1 = a->next;Polynode* p2 = b->next;Polynode* p3 = c;//每次用a中的一项乘b中的每一项生成一个临时多项式//将临时多项式与现有的c相加Polypointer headtemp = InitialNode();//每次生成的多项式的头节点Polynode* ptemp = headtemp; //ptemp是指向临时多项式当前操作节点的指针while (p1){ClearList(headtemp);ptemp = headtemp;while (p2){Polynode* temp = (Polynode*)malloc(sizeof(Polynode));if (temp == NULL)return;temp->next = NULL;temp->coef = p1->coef * p2->coef;temp->exp = p1->exp + p2->exp;AttachNode(temp->coef, temp->exp, ptemp);ptemp = ptemp->next;p2 = p2->next;}AddPoly(c, headtemp, c);//把生成的多项式累加p1 = p1->next;//p1指向下一项p2 = b->next; //p2指向b的起始位置}}//对乘法进行优化,减少频繁的节点分配//因为每次生成的多项式是相同长度的,所以临时多项式的节点可以反复利用void MultiPoly_2(Polypointer a, Polypointer b, Polypointer c){Polynode* p1 = a->next;Polynode* p2 = b->next;Polynode* p3 = c;Polypointer headtemp = InitialNode();//临时多项式的头节点Polynode* ptemp = headtemp; //ptemp是指向临时多项式当前操作节点的指针//先对a中的第一项,生成临时链表if (p1){while (p2){Polynode* temp = (Polynode*)malloc(sizeof(Polynode));if (temp == NULL)return;temp->next = NULL;temp->coef = p1->coef * p2->coef;temp->exp = p1->exp + p2->exp;AttachNode(temp->coef, temp->exp, ptemp);ptemp = ptemp->next;p2 = p2->next;}AddPoly(c, headtemp, c);//把生成的多项式累加p1 = p1->next;//p1指向下一项p2 = b->next; //p2指向b的第一项}//对临时链表反复利用while (p1){ptemp = headtemp->next;while (p2){ptemp->coef = p1->coef * p2->coef;ptemp->exp = p1->exp + p2->exp;ptemp = ptemp->next;p2 = p2->next;}AddPoly(c, headtemp, c);p1 = p1->next;p2 = b->next;}}//拷贝给定的多项式Polypointer CopyPoly(Polypointer a){Polypointer b;b = InitialNode();Polynode* p1 = a->next;Polynode* p2 = b;while (p1){Polynode* t = (Polynode*)malloc(sizeof(Polynode));if (t == NULL) return NULL;t->next = NULL;t->coef = p1->coef;t->exp = p1->exp;p2->next = t;p1 = p1->next;p2 = p2->next;}return b;}//对多项式求k阶导Polypointer DiffPoly(Polypointer a, int k){Polypointer c = CopyPoly(a);//将多项式a拷贝一份Polynode* p1 = c; //p1记录着p2的前一个节点Polynode* p2 = c->next;for (int i = 0; i next;while (p2){p2->coef = p2->coef * p2->exp;p2->exp--;if (p2->exp coef = 0;p1->next = p2->next;free(p2);p2 = p1->next;}else{p1 = p1->next;p2 = p2->next;}}}return c;}//求多项式的值double GetValue(Polypointer a, double x){double sum = 0;Polynode* p = a->next;while (p){sum += p->coef * pow(x, p->exp);p = p->next;}return sum;}//把多项式写入指定文件int Write(Polypointer a, char* outfile){FILE* fp = fopen(outfile, "a");if (fp == NULL){printf("file open failure\n");return Error;}Polynode* p = a->next;while (p){if (p->coef > 0){fprintf(fp, "+");}fprintf(fp, "%.2fx^%d", p->coef, p->exp);p = p->next;}fprintf(fp, "\n");fclose(fp);return OK;}//清空链表,保存头节点void ClearList(Polypointer a){Polynode* p1 = a->next;Polynode* p2;while (p1){p2 = p1->next;free(p1);p1 = p2;}a->next = NULL;}