多项式相加实验代码和报告

一.算法模块分析:
    将整个项目可分为四部分:
        1.将输入字符串链表分析到单链表
        2.单链表化简
        3.链表值运算
        4.输出
二.模块分块实现:
    1.将输入字符串链表分析到单链表
        分析:
        一元稀疏多项式,包含字符有数字(系数和指数)
        系数中小数点,指数符号,变量字母(以x为例)
        运算符(+和-,其中加减也可以表示正负数)
        通过以上分析可以构建如下结构体以用于存储每个单项
        并完成相应标志任务
        struct Record{
            double factor;//记录系数 -
            int power;//记录次方
            int flt;//记录后面有多少小 数,用复数表示
            bool flag;//记录正或负
            Record *next; //指向下一个节点的指针
        };
        并根据实际运算可将每个节点初始化函数写成如下
        Record *InitRecord()
        {
            Record *nr=new Record();
            nr->power=0;//初始化次方为0
            nr->factor=1;//初始化系数为1
            nr->flag=true;//初始化为正数
            nr->next=NULL;
            nr->flt=0;
            return nr;
        }

        实现算法:
        利用栈,将每个项的数字压入栈中,遇符号判断其作用(加减or正负)
        if 加减作用
            已完成一项的处理工作,通知归纳函数将分析出的数据运算成
            具体系数和指数并建立新节点加入到单链表后面
        if 正负作用
            +不必处理
            -通知标志正负的符号(flag),使其标志负
        遇到x作为系数运算结束的标志,并用相关变量进行标记
        遇到^作为指数开始计数的标志,并通知power=1标记并记录指数位数
        遇到.作为小数出现的标志,通知flt=-1,标志记录小数位数 

        将分析到栈中的数据进行处理(归纳函数):
            从栈中依次读出每个数字,先算指数,后算系数。利用幂次方依次
            加一的算法, 并作细节处理;
            处理完毕 即保存到新节点并添加到链表中,此时栈中应已清空
            (系数处理结束的标志) 。
    2.单链表化简
        先根据链表中各项指数大小进行从小到大排序,其中遇到指数相同的直接相加。
        再做循环,将为零的项删除
    3.链表值运算
        取运算链表A,B;
        先取两者头节点A->next,B->next;
        比较指数大小,若指数同样大小,则运算后赋值到新节点,
        若指数不同,取指数较小的,复制到新节点,并将它添加到结果链表后面
        until  A==NULL or B==NULL
        将剩余链表中未运算的各节点依次添加到结果链表后面,形成结果
    4.输出函数
        输出应该按照输入格式进行输出,保持多项式的完整性和简洁性
        对于系数为正的项(非第一项)应该在它输出之前加上‘+’,遇到负系数直接输出。
        在输出系数后应该输出x(指数大于0),在指数大于1的x后面应输出^,并输出指数
三.验证代码功能实现情况
测试一:
5x^12+6x^3+x-23x^3+12.6+61x^3+13+21x-11-x^12+0
52x+61-11+73x^3+45.12-112x+34x
多项式1和2最简结果:
加法运算
14.6+22x+44x^3+4x^12
+
95.12-26x+73x^3
=
109.72-4x+117x^3+4x^12
减法运算
14.6+22x+44x^3+4x^12
-
95.12-26x+73x^3
=
-80.52+48x-29x^3+4x^12

测试二:
5x+3x^2-15+21.45x^21+57.34-12x^2+20x
67x^3+51x-67x+123.456-81x+99x^21+41^2
多项式1和2最简结果:
加法运算
42.34+25x-9x^2+21.45x^21
+
123.456-97x+41x^2+67x^3+99x^21
=
165.796-72x+32x^2+67x^3+120.45x^21
减法运算
42.34+25x-9x^2+21.45x^21
-
123.456-97x+41x^2+67x^3+99x^21
=
-81.116+122x-50x^2-67x^3-77.55x^21
四。总结
    根据代码运行实例结果分析,其可以正确运算各种符合预定规则的输入。
    代码健壮性良好。代码实现中,做到了不写重复代码的要求,将运算代码
    合为一个。并符合代码模块化规则,将各模块分块实现,并完美的结合在
    一起。 
  1 /*
  2 实现多项式计算
  3 */
  4 #include<windows.h>
  5 #include<cmath>
  6 #include<iostream>
  7 #include<cstring>
  8 #include<stack>
  9 using namespace std;
 10 struct Record{
 11     double factor;//记录系数
 12     int power;//记录次方
 13     int flt;//记录后面有多少小数,用复数表示
 14     bool flag;//记录正或者
 15     Record *next;
 16 };
 17 Record *InitRecord()
 18 {
 19     Record *nr=new Record();
 20     nr->power=0;//初始化次方为0
 21     nr->factor=1;//初始化系数为1
 22     nr->flag=true;//初始化为正数
 23     nr->next=NULL;
 24     nr->flt=0;
 25     return nr;
 26 }
 27 class Polynomial{
 28     public:
 29         //初始化链表头,多项式字符串,进行分析
 30         Polynomial(char *str=NULL);
 31         //重载构造函数,直接利用多项式进行给予对象
 32         Polynomial(Record *h);
 33         void Analsis(char* str);//分析多项式
 34         void OutputPolynomial(); //按规则输出多项式
 35         Record* GetHead(){//得到头节点
 36             return head;
 37         }
 38     private:
 39         void RemoveRepeatedAndZero();
 40         //处理栈中存储的数据,将一项处理到节点中
 41         void InsertToListTail(Record* node);
 42         Record *head;//记录头节点
 43         Record *tail;//记录尾节点
 44         stack<int> Q;
 45 };
 46 Polynomial::Polynomial(char* str)
 47 {
 48     head=InitRecord();//初始化头节点
 49     tail=head;
 50     if(str!=NULL)
 51     Analsis(str);
 52 }
 53 Polynomial::Polynomial(Record *h)
 54 {
 55     head=h;
 56 }
 57 void Polynomial::Analsis(char* str)
 58 {
 59     int n=strlen(str);
 60     int i=0;
 61     Record *temp;
 62     bool flag=false;
 63     while(i<n)
 64     {
 65         if(!flag){
 66         temp=InitRecord();
 67         flag=true;
 68         }
 69         switch(str[i])//‘-‘ . + x
 70         {
 71             case ‘-‘:{
 72                 if(!Q.empty())
 73                 {
 74                 //已经记录了数据就可以插入了
 75                 InsertToListTail(temp);
 76                 i--;
 77                 flag=false;
 78                 }
 79                 else
 80                 {
 81                     temp->flag=!temp->flag;
 82                 }
 83                 break;
 84             }
 85             case ‘.‘:{
 86                 temp->flt=-1;
 87                 break;
 88             }
 89             case ‘+‘:{
 90                 if(!Q.empty())
 91                 {
 92                 //已经记录了数据就可以插入了
 93                 InsertToListTail(temp);
 94                 flag=false;
 95                 }
 96                 break;
 97             }
 98             case ‘ ‘:break;
 99             case ‘^‘:{
100                 temp->power=1;
101                 break;
102             }
103             case ‘x‘:{
104                 temp->power=1;
105                 if(Q.empty())Q.push(1);
106                 break;
107             }
108             default:{
109                 if(!(str[i]>=‘0‘&&str[i]<=‘9‘))
110                 {
111                     cout<<"多项式中有其它不可识别字符: "<<str[i];break;
112                 }
113                 //如果此时判断的是小数点后面的数字
114                 if(temp->flt&&!temp->power)temp->flt--;
115                 else if(temp->power)temp->power++;//多一个次方
116                 Q.push(str[i]-‘0‘);
117                 break;
118             }
119         }
120             i++;
121     }
122     this->InsertToListTail(temp);
123     this->RemoveRepeatedAndZero();
124 }
125 //完成插入到链表后新的数据,同时将factor计算出来
126 void Polynomial::InsertToListTail(Record* node)
127 {
128     double fr=0.0;
129     int p=0;
130     int temp=0;
131     int i=0;
132     //统计平方值
133     if(node->power>1)//如果power大于1才计算
134     {
135     while(--node->power>0)
136     {
137         temp=Q.top();
138         Q.pop();
139         p+=temp*powl(10,i++);
140     }
141     node->power=p;
142     }
143     if(node->flt==0)node->flt--;
144     while(!Q.empty())
145     {
146         temp=Q.top();
147         Q.pop();
148         fr+=temp*powl(10,++node->flt);
149     }
150     node->factor=fr;
151
152     if(node->flag==false)//负数标志
153     {
154     node->factor=-node->factor;//使系数变符号
155     }
156     if(node->factor!=0){
157     tail->next=node;//接入新节点
158     tail=node;}
159 }
160 void Polynomial::OutputPolynomial()
161 {
162     Record* p=head;
163     if(p->next==NULL){
164         cout<<0<<endl;
165         return;
166     }
167     int flag=0;
168     while(p->next!=NULL)
169     {
170         //负数输出是会带有负号,不需要加入或验证
171         p=p->next;
172         //如果系数为正,且不是头项,就应该输出‘+’
173         if(p->factor>0&&flag)cout<<‘+‘;
174         flag=1;//标志此时不是输出第一项
175         if(p->factor==-1&&p->power)cout<<‘-‘;
176         //如果系数不等于1 或者没有x,就输出系数
177         else if(p->factor!=1||!p->power)
178         cout<<p->factor;
179         if(p->power)//如果有x就要暑输出
180         cout<<‘x‘;
181         if(p->power>1)//次方大于1,要输出
182         cout<<‘^‘<<p->power;
183     }
184     cout<<endl;
185 }
186 //去掉重复幂方项或者零系数项
187 void Polynomial::RemoveRepeatedAndZero()
188 {
189     Record* h,*p,*temp,*pre;
190     if(head->next==NULL)return;
191     h=head->next->next;
192     p=head->next;
193     pre=head;
194     int flag=true;
195     while(flag)
196     {
197         flag=false;
198         while(p!=NULL&&h!=NULL)
199         {
200             if(p->power==h->power)
201             {
202                 p->factor+=h->factor;
203                 p->next=h->next;
204                 temp=h;
205                 h=h->next;
206                 delete temp;
207                 flag=true;
208                 continue;
209             }
210             if(p->power>h->power)
211             {
212                 temp=h;
213                 p->next=temp->next;
214                 temp->next=p;
215                 pre->next=temp;
216                 p=pre->next;
217                 h=p->next;
218                 flag=true;
219                 continue;
220             }
221             h=h->next;
222             pre=pre->next;
223             p=p->next;
224         }
225         if(p!=NULL)
226         p->next=NULL;
227         h=head->next->next;
228         p=head->next;
229         pre=head;
230     }
231     p=head->next;
232     pre=head;
233     while(p!=NULL)//去除系数为零的项
234     {
235         if(p->factor==0)
236         {
237             temp=p;
238             p=p->next;
239             pre->next=p;
240             delete temp;
241         }
242         if(p!=NULL){
243         p=p->next;
244         pre=pre->next;}
245     }
246     pre->next=NULL;
247 }
248 //将一个节点复制到一个新空间
249 Record* CopyTo(Record* h)
250 {
251     Record* nd=InitRecord();
252     nd->factor=h->factor;
253     nd->flag=h->flag;
254     nd->flt=h->flt;
255     nd->next=NULL;
256     nd->power=h->power;
257     return nd;
258 }
259 //多项式相加过程
260 Record* PolyAdd(Record* a,Record *b,int flag)//flag=1=>+else-
261 {
262     Record* result=InitRecord();
263     Record* p=result;
264     Record* temp;
265     a=a->next;
266     b=b->next;
267     while(a!=NULL&&b!=NULL)
268     {
269
270          if(a->power<b->power)
271          {
272              temp=CopyTo(a);
273              a=a->next;
274          }
275          else if(b->power<a->power)
276          {
277              temp=CopyTo(b);
278             if(!flag)temp->factor*=-1;
279              b=b->next;
280          }
281          else{
282              temp=CopyTo(a);
283             if(flag)
284              temp->factor+=b->factor;
285             else
286                 temp->factor-=b->factor;
287              b=b->next;
288              a=a->next;
289          }
290          p->next=temp;
291          p=temp;
292     }
293     if(!a)a=b;
294     while(a!=NULL)
295     {
296         p->next=CopyTo(a);
297         p=p->next;
298         a=a->next;
299     }
300     p->next=NULL;
301     return result;
302 }
303 int main()
304 {
305     char str[50];
306     char st2[50];
307     Record *p,*q,*re,*m;
308     cin>>str;
309     cin>>st2;
310     Polynomial exp(str);
311     Polynomial e2(st2);
312     p=exp.GetHead();
313     q=e2.GetHead();
314     re=PolyAdd(p,q,1);
315     Polynomial res(re);
316     cout<<"多项式1和2最简结果:\n" ;
317     cout<<"加法运算"<<endl;
318     exp.OutputPolynomial();
319     cout<<‘+‘<<endl;
320     e2.OutputPolynomial();
321     cout<<‘=‘<<endl;
322     res.OutputPolynomial();
323
324     m=PolyAdd(p,q,0);
325     cout<<"减法运算"<<endl;
326     Polynomial minus(m);
327     exp.OutputPolynomial();
328     cout<<‘-‘<<endl;
329     e2.OutputPolynomial();
330     cout<<‘=‘<<endl;
331     minus.OutputPolynomial();
332     system("pause");
333     return 0;
334 }
335 /*
336 5x^12+6x^3+x-23x^3+12.6+61x^3+13+21x-11-x^12+0
337 2+x+5+x^2+2x
338 4x+6+x^3+3x^2
339 13+7x+4x^2+x^3
340 7+3x+x^2
341 6+4x+3x^2+x^3
342 */
343 /*
344 5x^12+6x^3+x-23x^3+12.6+61x^3+13+21x-11-x^12+0
345 52x+61-11+73x^3+45.12-112x+34x
346 131.12+108x+140x^3+5x^12
347 25+22x+67x^3+5x^12
348 106.12+86x+73x^3
349 */ 
时间: 2024-10-14 08:06:28

多项式相加实验代码和报告的相关文章

(java描述)关于链表的代码-----单双、循环链表、约瑟夫环、多项式相加

将链表头尾倒置 将几个链表合并成一个新的链表,将链表中重复的节点去掉,并按大小排序 双向循环链表 单向循环链表(约瑟夫循环) 多项式相加 程序源代码 单链表.单向循环链表结点类 package javab; public class Node { int data; Node next; public Node(int data){ this.data=data; } } 第一题代码: package javab; import java.util.Scanner; public class I

多项式相加运算

 多项式相加运算,使用链表实现,代码仍需要改善,这里先初步做个记录 //实现多项式的表示及相加 by Denis #include <stdio.h> #include <malloc.h> #define ture 1 #define false 0 typedef int ElemType; typedef struct LNode{ ElemType coef; //系数 int expn; //指数 struct LNode *next; }polynomia; pol

JAVA将数字字符串强制转换成整型变量----求参数之和实验代码

实验代码: package demo; public class CommandParameter {  /**  * @param args  */  public static void main(String[] args) {   // TODO Auto-generated method stub    int sum=0;                                                                             //设数值

多项式相加&mdash;&mdash;C++和racket

  多项式相加是一个简单到爆的算法练习,学习链表之后一般会波拉波拉讨论稀疏的.稠密的用什么来表示,最后一般都作为链表的练习题出现.其实用数组表示多项式显然是不合理的,大多数的多项式必然没有如此紧密,链表几乎是唯一的选择. 放在C++这样的语言中,直接构建一个poly结点类,然后构建一个poly类(包含一个头节点),基本就是一个单链表的实现,对于多项式的加法,和有序链表的连接比较像,乘法就更简单了,逐一乘过去就行了. 导致这个过程很简单的原因是类的封装(C 用结构体加一些函数对于这个简单的问题也基

链表_多项式相加相乘

加法部分运行成功.乘法仍存在问题,找机会解决,欢迎大家指正. 还有一个问题,C语言函数传地址如何传,是否不需要我这样多次申请内存空间?欢迎交流. 代码如下: 1 #include<stdio.h> 2 #include<malloc.h> 3 4 typedef struct PolyNode *Poly;//定义多项式结构体类型 5 struct PolyNode{ 6 int coef; 7 int expon; 8 struct PolyNode *next; 9 }; 10

20172304 《程序设计与数据结构》实验三总结报告

20172304 <程序设计与数据结构>实验三总结报告 课程:<程序设计与数据结构> 班级:1723 姓名:段志轩 学号:20172306 实验教师:王志强 助教:刘伟康和张旭升 实验日期:2018年5月28日 必修/选修: 必修 实验内容 实验一代码规范(http://www.cnblogs.com/rocedu/p/4795776.html), Eclipse的内容替换成IDEA 参考 (http://www.cnblogs.com/rocedu/p/6371315.html#

双链表&amp;链表合并&amp;多项式相加算法

//单链表的合并 //链表合并 //两个链表必须是有序的 #define Maxsize 5 typedef  int elemtype; typedef struct linklist { elemtype data; struct linklist *next; }Linklist; //建立链表1 Linklist *CreateList1 () { int i,data ; Linklist *head, *p, *q; head=p=(Linklist  *)malloc(sizeof

[nRF51822] 10、基础实验代码解析大全 &#183; 实验15 - RTC

一.实验内容: 配置NRF51822 的RTC0 的TICK 频率为8Hz,COMPARE0 匹配事件触发周期为3 秒,并使能了TICK 和COMPARE0 中断. TICK 中断中驱动指示灯D1 翻转状态, 即指示灯D1 以8Hz 的速率翻转状态 COMPARE0 中断中点亮指示灯D2 二.nRF51822的内部RTC结构: NRF51822 有两个RTC 时钟:RTC0,RTC1.两个RTC 均为24 位,使用LFCLK 低频时钟,并带有12 位分频器,可产生TICK.compare 和溢出

多项式链表多项式相加

//多项式相加 LinkList* add2Link(LinkList*L1, LinkList*L2) { LinkList*p1, *p2; LinkList*head , *pre, *p; head = new LinkList; head->next = NULL; pre = head; p1 = L1->next; p2 = L2->next; while (p1&&p2) { if (p1->exp == p2->exp) { p = new