【链表实现一元多项式的求积、求和】

您所在的位置:网站首页 怎么整列求积 【链表实现一元多项式的求积、求和】

【链表实现一元多项式的求积、求和】

2023-01-05 02:26| 来源: 网络整理| 查看: 265

如何使用

在这里插入图片描述 顺序链表没有实现求积只有求和,单向链表实现了求和以及求积。所以建议用单向链表的实现代码。 代码里面封装了两个一元多项式求和和求积的函数,调用编译运行就行。 先输入非常数项,再输入常数项,比如上面的输入就代表了 2x^3 + 3x^5 + 6x^6 + 9这个一元多项式。暂时不支持系数为负数,指数可以是负数。

运行结果

在这里插入图片描述 上图就代表了两个一元多项式求积。

顺序链表实现 #include #include #include #define MAX 99 typedef struct list //顺序结构链表结构体 { double arr[MAX]; int first; //指向了一元多项式的第一项的系数的下标 int last; //指向了下一个要增加的项的系数的下标 int constsub; //指向了常数项元素的下标 } LIST; /************************************顺序结构链表函数声明***********************************/ LIST * create_polynomial_list();//创建一个一元多项式顺序链表 LIST * select_polynomial_data(LIST *str);//设置一个一元多项式的数据 LIST * polynomial_sum(LIST *str, LIST *ptr);//求和,结果保存在str int printf_list(LIST *str); //打印这个顺序链表 void display_polynomial(); //创建一个一元多项式并打印 void set_polynomial_sum(); //创建两个一元多项式顺序链表,并求和之后打印 /************************************顺序结构链表函数声明 end*******************************/ int main(void) { return 0; } /********************************顺序结构链表函数定义*********************************/ //创建一个一元多项式顺序链表 LIST * create_polynomial_list() { LIST *ptr = (LIST *)malloc(sizeof(LIST)); memset(ptr->arr, 0, sizeof(ptr->arr)); //将数组arr内的元素全部填充为0 ptr->first = 0; ptr->last = 0; ptr->constsub = MAX - 1; //常数项固定放在arr最后一个元素arr[MAX-1]中。 return ptr; } //设置一个一元多项式的数据 LIST * select_polynomial_data(LIST *str) { printf("请输入每个项的系数和指数\n"); printf("输入形式为:x y,输入指数为0则代表结束输入且进入常数项的输入\n"); double coefficient = 0; //系数 double index = 0; //指数 double constnum = 0; //常数项 while(1) { scanf("%lf%lf",&coefficient,&index); if(0 == index) //输入指数为0,则退出此循环并进去常数项输入 break; if(-1 == str->last) //除了常数项之外,已经存满了,强行进入常数项输入 break; str->arr[str->last] = coefficient; //赋值 str->arr[str->last + 1] = index; str->last += 2; //last后移,指向下一项增加的位置的下标 if(str->last == MAX-1) //指向了常数项元素的下标 str->last = -1; } printf("请输入常数项\n"); scanf("%lf",&constnum); str->arr[str->constsub] = constnum; return str; } //str和ptr指向的链表的一元多项式的求和 //最终结果会保存在str指向的那个链表中 LIST * polynomial_sum(LIST *str, LIST *ptr) { //先算常数项 str->constsub += ptr->constsub; int StrFirst = str->first; //辅助循环 int PtrFirst = ptr->first; //辅助循环 str->first 和 ptr->first 的值其实就是0 //PtrFirst代表准备相加项的系数的下标 while(0 != ptr->arr[PtrFirst]) { //等于0则代表相加完毕 while(StrFirst != ptr->last) { //查找完毕,退出 if(str->arr[StrFirst+1] == ptr->arr[PtrFirst+1]) { //找到了指数相等的项 str->arr[StrFirst] += ptr->arr[PtrFirst]; //系数相加 break; } StrFirst += 2; }/*内while*/ if(StrFirst == ptr->last) { //代表没有找到相等的项,那么就将此项加入str指向的一元多项式后面 if(str->last == MAX-1) { printf("已经保存不下多余的项,请增加MAX的值再次尝试\n"); exit(-1); } str->arr[ptr->last] = ptr->arr[PtrFirst]; str->arr[ptr->last + 1] = ptr->arr[PtrFirst+1]; str->last += 2; } StrFirst = 0;//置0,便于下次循环比较 PtrFirst += 2; //继续对ptr链表中的下一项进行相加 }/*外while*/ return str; } //打印这个链表,以一元多项式的方式 int printf_list(LIST *str) { int print = 0; //从第一项开始打印 int flag = 1;//一元多项式是否只有常数项的标志 int i = 0; //开始打印 while(print != str->last) { if(str->arr[print] > 0) { //系数大于0 flag = 0; //代表不止有常数项 if((0 == print) || (0 == i)) //第一项 printf("%.2lfx^%.2lf",str->arr[print],str->arr[print+1]); else printf(" + %.2lfx^%.2lf",str->arr[print],str->arr[print+1]); i = 1; } else if(str->arr[print] if(1 == flag) //只有常数项 printf("%.2lf\n",str->arr[str->constsub]); else printf(" + %.2lf\n",str->arr[str->constsub]); } return 0; } //创建一个一元多项式并打印 void display_polynomial() { LIST * p = create_polynomial_list();//创建一个一元多项式顺序链表 select_polynomial_data(p);//设置一个一元多项式的数据 printf_list(p); } //创建两个一元多项式顺序链表,并求和之后打印 void set_polynomial_sum() { LIST * p = create_polynomial_list();//创建一个一元多项式顺序链表 LIST * p2 = create_polynomial_list();//创建一个一元多项式顺序链表 select_polynomial_data(p);//设置一个一元多项式的数据 select_polynomial_data(p2);//设置一个一元多项式的数据 polynomial_sum(p, p2); //求和 printf_list(p); } /******************************顺序结构链表函数定义 end*********************************/ 单向链表实现 #include #include #include /*vvvvvvvvvvvvvvvvvvvvvvvvvvv链式结构单向链表vvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ /* 每一个结点保存了一元多项式每一项的系数和指数,且最后一个结点保存了常数项的值 功能:实现一元多项式的求和,求积 */ typedef struct list2 //链式结构单向链表结构体 { double Coeff; //系数 double Index; //指数 struct list2 * next;//指向下一个结点 } LIST_2; /********************************链式结构链表函数声明**********************************/ LIST_2 * CreateSelectPolyData(); //创建并设置数据 int PrintfList(LIST_2 *str); //打印这个链表 LIST_2 * PolynomialSum(LIST_2 *str, LIST_2 *ptr); //求和 LIST_2 * PolyMultiplicate(LIST_2 *str, LIST_2 *ptr); //求积 void DisplayPolynomial(); //创建一个链式链表并以一元多项式的方式打印 void SetPolynomialSum();//创建两个链式链表求和之后以一元多项式的方式打印 void SetPolynomialMult();//创建两个链式链表求积之后以一元多项式的方式打印 /********************************链式结构链表函数声明 end******************************/ int main(void) { system("chcp 65001"); return 0; } /******************************链式结构链表函数定义*************************************/ //创建并设置数据 LIST_2 * CreateSelectPolyData() { double coefficient = 0; //系数 double exponent = 0; //指数 LIST_2 *first = NULL; LIST_2 *last = NULL; printf("请输入系数和指数,以x(系数) y(指数)的形式,输入指数为0时则系数的值就是常数项的值\n"); while(1) { scanf("%lf%lf",&coefficient, &exponent); LIST_2 *p = (LIST_2 *)malloc(sizeof(LIST_2)); p->Coeff = coefficient; //赋值 p->Index = exponent; p->next = NULL; if(NULL == first) { //输入的还是第一个结点 first = p; last = p; } else { last->next = p; last = p; } if(0 == exponent) //如果指数为0,则代表这次输入的是常数项,退出循环 break; }/*while*/ return first; //返回头结点的指针 } //打印这个链表 int PrintfList(LIST_2 *str) { int i = 0; //特殊情况标志变量 LIST_2 *ptr = str; //代替str循环 int flag = 1; //一元多项式是否只有常数项的标志 while(ptr->next != NULL) { // ptr->next 等于NULL 即ptr指向最后一个结点的时候退出循环 if(ptr->Coeff > 0) {//系数大于0 flag = 0; if((ptr == str) || (0 == i)) //第一项 printf("%.2lfx^%.2lf",ptr->Coeff, ptr->Index); else printf(" + %.2lfx^%.2lf",ptr->Coeff, ptr->Index); i = 1; } else if(ptr->Index if(1 == flag) //有且只有常数项 printf("%.2lf\n",ptr->Coeff); else printf(" + %.2lf\n",ptr->Coeff); } else if(ptr->Coeff Coeff * -1)); //等于0则不打印常数项 return 0; } //求和,找到指数相等的就系数直接相加,否则就当成一个新项插入目标链表中 LIST_2 * PolynomialSum(LIST_2 *str, LIST_2 *ptr) { //先加其他项 LIST_2 *s = NULL; //代替str循环 while(ptr->next != NULL) { //当ptr指向了最后一个结点时,跳出循环开始常数项的相加 s = str; while(s->next != NULL) { //当s指向了链表最后一个结点(保存了常数项的结点)的时候会跳出循环 if(s->Index == ptr->Index) {//找到了指数相等的 s->Coeff += ptr->Coeff; //系数直接相加即可 break; } s = s->next; //比较下一项 }/*while*/ if(NULL == s->next) {//说明没找到指数相等的,此时s指向了str的最后一个结点 //为了方便,我们直接增加一个结点到str最后一个结点和倒数第二个结点之间 LIST_2 *p = (LIST_2 *)malloc(sizeof(LIST_2)); LIST_2 *t = str; p->Coeff = ptr->Coeff; p->Index = ptr->Index; p->next = NULL; while(t->next != s) //将t指向str倒数第二个结点 t = t->next; //开始连接 t->next = p; p->next = s; } ptr = ptr->next; //后移一位,继续判断相加 }/*while*/ //常数项相加 while(s->next != NULL) //将s指向str链表的最后一个结点 s = s->next; s->Coeff += ptr->Coeff; } //求积 /* 将ptr链表中的结点依次与str的结点相乘,每一个乘积项都放入一个新的链表, //然后对其化简(即合并同类项)得出最终结果 */ LIST_2 * PolyMultiplicate(LIST_2 *str, LIST_2 *ptr) { LIST_2 *nfirst = NULL; LIST_2 *nlast = NULL; LIST_2 *s = str; while(ptr != NULL) { s = str; //s重新指向str链表的第一个结点 while(s != NULL) { //将ptr指向的的一个结点和str链表中的所有结点依次相乘并且放入新链表中 LIST_2 *p = (LIST_2 *)malloc(sizeof(LIST_2)); p->next = NULL; if((0 == ptr->Index) && (0 != ptr->Coeff)) { //指数是0且系数不为0,代表ptr指向的结点是常数项 p->Coeff = s->Coeff * ptr->Coeff; //只需系数相乘 p->Index = s->Index; //指数无需乘,直接赋值即可,如果是两个常数项相乘,那么s->Index的值就是0 } else { //不是常数项该怎么乘就怎么乘 p->Coeff = s->Coeff * ptr->Coeff; //系数相乘 p->Index = s->Index + ptr->Index; //指数相加 } if(NULL == nfirst) { //新链表中还没有结点 nfirst = p; nlast = p; s = s->next; //s右移,继续相乘 continue; //所以无需判断是否需要化简 } LIST_2 *nfp = nfirst; //代替nfirst循环 //此时新链表中已经有结点,我们在插入新乘积项的时候就要先判断是否存在同类型,有则化简 //没有则放在新链表后面 while(nfp != NULL) { if(nfp->Index == p->Index) {//存在同类型 nfp->Coeff += p->Coeff; break; //跳出while循环 } nfp = nfp->next; } /*while*/ if(NULL == nfp) { //说明在新链表中没有找到同类项,需要插入在链表最后面 nlast->next = p; //开始连接结点 nlast = p; } s = s->next; //s指向下一个结点,继续相乘 }/*while*/ ptr = ptr->next; //ptr指向下一个结点,继续相乘 }/*while*/ return nfirst; //返回新链表的头节点的指针,答案保存在这个新链表中 } //创建一个链式链表并以一元多项式的方式打印 void DisplayPolynomial() { LIST_2 * p = CreateSelectPolyData(); PrintfList(p); } //创建两个链式链表求和之后以一元多项式的方式打印 void SetPolynomialSum() { LIST_2 * p = CreateSelectPolyData(); LIST_2 * p2 = CreateSelectPolyData(); PolynomialSum(p, p2); PrintfList(p); } //创建两个链式链表求积之后以一元多项式的方式打印 void SetPolynomialMult() { LIST_2 * p = CreateSelectPolyData(); LIST_2 * p2 = CreateSelectPolyData(); LIST_2 * nptr = PolyMultiplicate(p, p2); //求积,nptr用于指向新链表的头结点 PrintfList(nptr); } /******************************链式结构链表函数定义 end ********************************/


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3