一.算法模块分析: 将整个项目可分为四部分: 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