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