zoukankan      html  css  js  c++  java
  • 多项式相加实验代码和报告

    一.算法模块分析:
        将整个项目可分为四部分:
            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 */ 
  • 相关阅读:
    Benelux Algorithm Programming Contest 2016 Preliminary K. Translators’ Dinner(思路)
    Benelux Algorithm Programming Contest 2016 Preliminary Target Practice
    Benelux Algorithm Programming Contest 2016 Preliminary I. Rock Band
    Benelux Algorithm Programming Contest 2016 Preliminary A. Block Game
    ICPC Northeastern European Regional Contest 2019 Apprentice Learning Trajectory
    ICPC Northeastern European Regional Contest 2019 Key Storage
    2018 ACM ICPC Asia Regional
    2018 ACM ICPC Asia Regional
    Mybatis入库出现异常后,如何捕捉异常
    优雅停止 SpringBoot 服务,拒绝 kill -9 暴力停止
  • 原文地址:https://www.cnblogs.com/sytu/p/4414918.html
Copyright © 2011-2022 走看看