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 */ 
  • 相关阅读:
    python的IDE(pycharm)安装以及简单配置
    python环境搭建(python2和python3共存)
    如何搭建samba服务?
    css 样式 文字过长 换行处理方法
    my97 日历控件
    myeclipse8.6 注册码
    (46) odoo核心文档分享
    (01-02) odoo8.0_Ubuntu14.04_nginx反代理设置
    (45) Manifest文件
    (44) odoo中的WebService
  • 原文地址:https://www.cnblogs.com/sytu/p/4414918.html
Copyright © 2011-2022 走看看