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

一.算法模块分析:
    将整个项目可分为四部分:
        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最简结果:
" ;
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 */ 
原文地址:https://www.cnblogs.com/sytu/p/4414918.html