0%

C++第二次小项目——四则预算器

:::info

  1. 使用C完成代码,确保程序可由C编译器(如g++)编译。
  2. 采用面向对象的思想编写程序,将复杂结构抽象成类,并对必要的运算符进行重载,以使
    程序更为优雅可靠。
  3. 程序应以交互式方式运行,类似于Python的交互模式(思考一下,C++如何读取一
    行?)。空格不应影响输入。
  4. 可尝试支持对复杂表达式的混合计算,如
  5. 可尝试支持科学计数法的输入,尝试支持大浮点数(如1.0e200等)。
  6. 可尝试支持大数,支持高精度计算(可调用相关高精度运算库)。
  7. 可尝试多种方式对代码进行优化,包括执行速度、功能等(如在交互中支持++,+=,-
    -,-=,*=,/=等操作);可以尝试完善错误提示,让错误提示更加明确;尝试允许用户自
    选输出方式,如是否采用科学计数法等;可内嵌帮助文档,通过特定指令能够输出对应帮
    助文档。

8. 请勿直接采用他人的复数实现代码。

9. 项目报告需对需求进行分析,描述实现方案与项目特色。报告应包含核心代码并进行解

释。如果编译运行复杂,请提供编译运行代码的说明。提供运行结果的展示(如截图),

并尽量给出性能展示与分析。最后给出总结。同时,鼓励写上实现代码时遇到的困难以及

相应的解决思路/方案。

:::

先贴出结果,写出对应对的解析,然后写出总结

实验报告解析

写在前面

:::info
写在前面

:::

为了让实验报告看起来更加清晰,写出我的基本算法思想。

数据来源是字符串,我写的东西就是对字符串进行处理,利用操作符分割成每个字符串入栈,利用双栈来实现表达式。表达式再根据Complex类对操作符的重载,然后计算,存储结果。

思想很简单,但是不足的地方有很多,后面的总结再来啰嗦吧。

开始解析

:::info

  1. 使用C完成代码,确保程序可由C编译器(如g++)编译。
  2. 采用面向对象的思想编写程序,将复杂结构抽象成类,并对必要的运算符进行重载,以使
    程序更为优雅可靠。

:::

由于后面需要大数,因此引入gmpxx库,由于myms里面自带。我们之前通过VScode和mysm2搞了一下环境

因此我们的命令行参数设置如下即可,并且看到成功编译。

我们设计了一个Complex类,实部和虚部用两个高精度浮点类型mpf_t来表示。下面对一些运算符进行重载,包括对象是string类的和Complex类的,定义了一些方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class Complex{
public://也设立两个负数的flag
mpf_t realPart;//实
mpf_t imaginaryPart;//虚
Complex()
{
mpf_init2(imaginaryPart,333);
mpf_init2(realPart,333);
mpf_set_ui(realPart,0);
mpf_set_ui(imaginaryPart,0);
}
Complex(mpf_t initx,mpf_t inity)
{
mpf_init2(imaginaryPart,333);
mpf_init2(realPart,333);
mpf_set(realPart,initx);
mpf_set(imaginaryPart,inity);
}
char* getx(){
return mpf_get_str(nullptr,0,10,0,realPart);
}
char* gety(){
return mpf_get_str(nullptr,0,10,0,imaginaryPart);
}
Complex & operator=(Complex b)
Complex operator+(Complex b) const
Complex operator-(Complex b) const

Complex operator*(Complex b) const

Complex operator/(Complex b) const
Complex operator+(string buf) const
Complex operator-(string buf) const
Complex operator*(string buf) const
Complex operator/(string buf) const
string mod() const
string con() const
string alldata() const
string realdata() const
string imagdata() const
void print()const
};

:::info
3. 程序应以交互式方式运行,类似于Python的交互模式(思考一下,C++如何读取一

行?)。空格不应影响输入。

:::

如果用户输入复数,且复数有效,则用自行定义的统一格式打印该复数,若格式错

误,则打印错误信息(程序仍继续执行)。可参考如下(也可以自行统一格式):

对于赋值操作,程序应保存相应变量名和复数值,并支持变量覆盖操作(可以通过赋

值覆盖原来数值)(有效变量名可以参考C++有效变量名标准,如变量名只能是字母

A-Za-z)和数字(0-9)或者下划线(_)组成。第一个字母必须是字母或者下划

线开头。变量名区分大小写。变量名不能为“i”等预设名称。保存变量可以参考使用unordered_map 等容器)。若输入为已赋值变量,则输出该变量及相应复数值,若

未定义变量,则提示错误。

支持变量间的加减乘除法

在此前先说明,我创建的无序图键值对分别是,一个变量名对应一个字符串

然而因为我写的算法的原因并不支持复杂变量间的加减乘除运算,这是因为我在处理这些变量的时候等价于利用宏直接进行一个替换成一个字符串。

如果创建无序图的时候

支持模运算和赋值,

在这一点,对mod还算是比较成功的….

支持求共轭复数

con的话,因为代码算法的局限性,只完成了一点

选做)支持变量的连续的加减乘除法(同个运算),并可支持变量与数的混合运

算,括号解析(对于乘除法),和相应变量赋值

乘除法就算了,因为变量间都是宏替换的,实现不了….

但是加法肯定没问题,图中4.099999999999999999999我猜是因为mpf的局限,表示不了4.1,这里后面总结会说到这个东西。

这里展示一下常数的乘除法

:::info
4. 可尝试支持对复杂表达式的混合计算,如

:::

然而并不可以,因为程序残次,解析括号花费了挺多时间,也没有解决,我的评价是不如直接用mpf(或者其他高精度库)的栈,不用string的。

为什么这里a,b,c都有初始化,还会提示非法变量呢?

明显和我们的变量转换函数有关,我这里的思路是组部分解析buf,就是从0开始找,如果找到了就标记当前的下标,我们从当前下标开始找。这样有个问题,就是我们是abc顺序插入umap的,这里猜测umap存储是cba的一个链表,所以我们找到c的时候,就已经跳过了a和b

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void NameTraslate(string &buf){
string::const_iterator it = buf.begin();
string::const_iterator word_start;
string::const_iterator word_end;
string word;
int idx=0;
int next_idx=0;
for (const auto& it : umap) {
idx=buf.find(it.first,next_idx);
if(idx!= std::string::npos){//如果不等于,说明找到了
next_idx=idx+it.first.length();
buf.replace(idx,it.first.length(),it.second);//用值替换对应对的键
}
}
if(buf.find('_')!=std::string::npos){//如果还找到相对应对的标识符,输出,未定义对的变量.
cerr<<"未定义的变量"<<endl;
}
}

改进后,把idx=buf.find(it.first,next_idx);改为idx=buf.find(it.first,0),之后就可以随便加都可以了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void NameTraslate(string &buf){
string::const_iterator it = buf.begin();
string::const_iterator word_start;
string::const_iterator word_end;
string word;
int idx=0;
int next_idx=0;
for (const auto& it : umap) {
idx=buf.find(it.first,0);
if(idx!= std::string::npos){//如果不等于,说明找到了
next_idx=idx+it.first.length();
buf.replace(idx,it.first.length(),it.second);//用值替换对应对的键
}
}
if(buf.find('_')!=std::string::npos){//如果还找到相对应对的标识符,输出,未定义对的变量.
cerr<<"未定义的变量"<<endl;
}
}

:::info
5. 可尝试支持科学计数法的输入,尝试支持大浮点数(如1.0e200等)。

:::

格式肯定是支持的,但是小数点的处理真不太行。虽然说把它分成指数exp和基数base来处理的思想是没错的,但是对位数的处理,有挺大的问题,特别是字符串的数据有多种情况。

这里突然想到,如果我们一开始把科学技术法的处理或者传入的数据是一个mpf_t高精度格式,让其库的函数来处理,会不会更好?特别是mpf_get_str会返回exponent的位置,我们直接根据这个位置插入小数点会不会更好?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
void ETraslate(string &buf){
string s=buf;
int idx_e = s.find("E");
int idx_ch =s.find("#");
int idx_i=s.find("i");
bool flag_i=0;
if(idx_e!= std::string::npos){
if(idx_i!=std::string::npos){
buf.pop_back();//把i给pop掉
flag_i=1;
}
if(idx_ch!= std::string::npos){//如果存在的话{
buf[idx_ch]='-';
}
string base = s.substr(0, idx_e); //获取小数部分
int exp = stoi(s.substr(idx_e + 1)); //获取指数部分
buf=AdjustResult(exp,base);
if(flag_i){
buf.append("i");
}
}else {
return ;
}
}
string AdjustResult(int exp,string &buf){
string adjust_result;
if (exp < 0) {
// 计算小数点需要向左移动的位数
int move = -exp;
adjust_result = "0." + std::string(move, '0') + buf;
} else {
// 在整数部分后面拼接exp个"0"
adjust_result = buf + std::string(exp, '0');
}
return adjust_result;
}

:::info

  1. 可尝试支持大数,支持高精度计算(可调用相关高精度运算库)。

:::

只能说托mpf的福,没问题,但是表达式执行算法有大问题。

:::info
7. 可尝试多种方式对代码进行优化,包括执行速度、功能等(如在交互中支持+++=-

--=*=/=等操作);可以尝试完善错误提示,让错误提示更加明确;尝试允许用户自

选输出方式,如是否采用科学计数法等;可内嵌帮助文档,通过特定指令能够输出对应帮

助文档。

:::

由于上面的六种基本要求都没有完成,所以这一方面也没时间下手。

:::info
8. 请勿直接采用他人的复数实现代码。

9. 项目报告需对需求进行分析,描述实现方案与项目特色。报告应包含核心代码并进行解

释。如果编译运行复杂,请提供编译运行代码的说明。提供运行结果的展示(如截图),

并尽量给出性能展示与分析。最后给出总结。同时,鼓励写上实现代码时遇到的困难以及

相应的解决思路/方案。

:::

这里就贴出核心代码进行解释吧,既然是个残次品,其实效率真的低,代码也冗长

表达式拆分,操作数操作符分别入栈

在一开始我们将科学计数法E后面的符号换成另一个符号#来处理

对于mod(),con()的翻译选择在拆分之前,不然里面的符号会影响拆分

拆分主要是选择运算符号为分界线进行拆分。

操作符通常是操作数-1(除去括号)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
for(int i=0;i<buf.length();i++){
int idx_e=buf.find('E',i);//找到E的位置
if(idx_e!= std::string::npos){
if(buf[idx_e+1]=='-'){//如果e的下个字符是-号的话,换成不处理的符号
buf[idx_e+1]='#';
}
}
if(buf[i]=='+'||buf[i]=='-'||buf[i]=='*'||buf[i]=='/'||buf[i]=='('||buf[i]==')'){
idxoffset=i-idx_oper;
idx_oper=i;

if(pre_idx==0||idxoffset>1){// 1*(2+3) *和(下标差距为1 idx_oper=1, i=2 idxoffset=1
string temp;
if(pre_idx==0){
temp=buf.substr(pre_idx,idxoffset);
}
else if(pre_idx!=0){
temp=buf.substr(pre_idx,idxoffset-1);
}
ETraslate(temp);
bufstack1.push(temp);//2+3+6 则插入3
if(buf[idx_oper+1]=='('){
pre_idx=idx_oper+2;
}else{
pre_idx=idx_oper+1;
}

}
opstack1.push(buf[i]);
}
if(buf[i]!=')'&&i==buf.length()-1){//到字符串末尾 idx_op=3 i=4 idx_offset=1 buf.length=5
string temp;
if(pre_idx==0){
temp=buf.substr(idx_oper,buf.length()-idx_oper);
}else{
temp=buf.substr(idx_oper+1,buf.length()-idx_oper-1);
}
ETraslate(temp);
bufstack1.push(temp);//2+3-6 插入6
}
}

利用栈进行运算,以及优先级

对栈中操作数操作符进行运算的代码有点长。。。其实真不应该,如果用mpf类型的栈的话,大不了特例化一个

这里贴出部分代码。

下面是我选用的优先级

1
2
3
4
5
6
7
8
9
10
11
12
int WhoFirst(char op){
if(op=='(')
return 1;
else if(op=='+'||op=='-')
return 2;
else if(op=='*'||op=='/')
return 3;
if(op==')')
return 1;
else
cerr<<"错误的字符输入"<<endl;
}

对操作符栈1和栈2进行操作,栈1只是为了实现逆波兰表达式

如果栈1取出来的符号优先级比栈2高则继续从栈1取符号,同时取操作数

如果优先级低于栈2,则利用栈2顶部符号开始运算。

其实这里一开始栈就应该用mpf,这样也更好处理括号的问题,以及运算的问题,要用的时候进行重载就好了。

1
2
3
4
5
6
7
8
9
10
11
while(bufstack2.top()!="@"||bufstack2.size()>1||!opstack1.empty()||!opstack2.empty()){//依据操作符栈1是否为空判断是否结束
if((!opstack1.empty())){
if(!opstack1.empty()&&!opstack2.empty()&&(WhoFirst(opstack1.top())>=WhoFirst(opstack2.top()))){//来者的优先级比较大,就不管它
if(opstack1.top()=='('&&opstack2.top()==')'){
opstack1.pop();
opstack2.pop();
}
opstack2.push(opstack1.top());
opstack1.pop();
bufstack2.push(bufstack1.top());
bufstack1.pop();

这里是运算的步骤,只放出加法运算

对于三个数55+45+100,直接计算没问题,就是对100+45=145的结果放到栈2暂存,然后再从栈1读取55和+来继续运算

但是对于复数1+2i+3+4i,4i+3结果是一个字符串,如果放到栈2暂存,我们后面入栈2i和+的时候,计算就真不好算了,所以这里采用一个占位符@但是会产生一个问题,就是不知道该值是多少。

好像也可以用图来缓解这个问题,但是这个终究是算法的缺陷,终究是我考虑的不够全面,坑只会越填越多。

采用能够方便我们进行对象操作的算法和数据结构,类才是关键。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
else if(!opstack1.empty()&&!opstack2.empty()&&(WhoFirst(opstack1.top())<WhoFirst(opstack2.top()))){//来者的优先级比较小,我们就要进行
char op=opstack2.top();
opstack2.pop();
switch (op){
case '+':
//bufstack2.top()=bufstack2.top()+bufstack1.top();//进行运算
if(bufstack2.top() =="@" && mulsave.size()!=0){
result=result+mulsave.back();
mulsave.pop_back();
bufstack2.pop();
}else{
if(bufstack2.top()=="@")
result=result+"0";
else
result=result+bufstack2.top();
cout<<"2+1: "<<endl;
bufstack2.pop();//把0pop掉
}
if(bufstack2.top() =="@" && mulsave.size()!=0){
result=result+mulsave.back();
mulsave.pop_back();
bufstack2.pop();
}else{
if(bufstack2.top()=="@")
result=result+"0";
else
result=result+bufstack2.top();
bufstack2.pop();//把0pop掉
}
bufstack2.push("@");//推入0,是为了代替运算后的结构的数据,因为运算后的结果已经保存到COM中了
break;

mpf精度问题

mpf浮点数结构体

1
2
3
4
5
6
7
8
9
10
11
// gmp.h
typedef struct
{
int _mp_prec; // mp_limb_t 的最大精度。由 mpf_init 设置,
// 由 mpf_set_prec 修改。
// _mp_d字段指向的区域包含' prec' + 1个 limb(s)。
int _mp_size; // abs(_mp_size)是最后一个字段指向的 limb(s) 数。
// 如果 _mp_size 是负数,则这就是一个负数。
mp_exp_t _mp_exp; // 以 mp_limb_t 为底的指数。
mp_limb_t *_mp_d; // 指向 limb(s) 的指针。
} __mpf_struct;

mpf_t我们直接用init初始化的话是有问题的,因为这样返回的字符串,以及精度最多在21位就被截断了。

我们需要使用mpf_inits(a,333);后面的333能够让我们有100位的精度。参考

总结

总结就是,第二次项目可以说是另辟蹊径做出来的残次品,功能并不完全。。。所以我也挺不满意的,其实应该做到一半就大改结构和思路,不明白自己为什么那么固执,非要填那些填不上的坑,不如早点听别人意见。

填坑消耗的时间又多,做的又不理想…

这里说一下我这个残次品的思路和后面想到的理想中的思路吧,也就说出来我做了什么。

残次品的思路

对于大数字的处理,我们肯定要对字符串进行操作。

所以此程序以字符串为基础,设置相关的数据结构比如栈,我们的Complex类采用mpf_t,有一个函数mpf_get_str能够将mpf_t值转化为字符串(稍有差异)

所以这里的操作层面都是对字符串进行操作的,对从栈取出的字符串的处理和操作符的处理我的方式是有问题的,无法解析括号甚至无法处理复杂加减乘除的表达式。甚至对多个乘法的结果相加,借助了一个向量和一个无意义符号@,这也让我们的代码变成冗长难以理解

理想的思路

如果使用mpf_t的栈来运算,重载其运算符,mpf_t的栈进行特例化。

这样肯定会让我们的代码简洁很多。

优先级设置,以及括号的解析也能够更加容易得实现。我们对字符操作完后,填充其他符号了。

源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
#include <iostream>
#include <bits/stdc++.h>
#include <string>
#include <string.h>
#include <stdlib.h>
#include <gmpxx.h>
#include <unordered_map>
#include <stack>
#include <vector>
#include <queue>//运用到C++的栈和队列
using namespace std;
#define MAXSIZE 1024

void CountEr(string &buf);
void BlankFliter(string &buf);
void ModTraslate(string &buf);//转换模,转换科学计数法,转换共轭复数
void ConTraslate(string &buf);
void ETraslate(string &buf);
bool NameCheck(string &buf);
void NameTraslate(string &buf);
string AdjustResult(int exp,string &buf);
string MpfAdjustResult(int exp,string &buf);
bool CheckImga(string &buf);
int WhoFirst(char op);
bool Invalid=0;

unordered_map<string,string>umap{

};
int Out_State=0;

//Complex一个浮点类,一个整数类,可以用函数模板,对一些必要的操作进行重载.
class Complex{
public://也设立两个负数的flag
mpf_t realPart;//实
mpf_t imaginaryPart;//虚
Complex()
{
mpf_init2(imaginaryPart,333);
mpf_init2(realPart,333);
mpf_set_ui(realPart,0);
mpf_set_ui(imaginaryPart,0);
}
Complex(mpf_t initx,mpf_t inity)
{
mpf_init2(imaginaryPart,333);
mpf_init2(realPart,333);
mpf_set(realPart,initx);
mpf_set(imaginaryPart,inity);
}
char* getx(){
return mpf_get_str(nullptr,0,10,0,realPart);
}
char* gety(){
return mpf_get_str(nullptr,0,10,0,imaginaryPart);
}
Complex & operator=(Complex b)
{
mpf_set(this->realPart,b.realPart);
mpf_set(this->imaginaryPart,b.imaginaryPart);
return *this;
}
Complex operator+(Complex b) const
{
Complex result= Complex();
mpf_add(result.realPart,b.realPart,this->realPart);
mpf_add(result.imaginaryPart,b.imaginaryPart,this->imaginaryPart);
return result;
}
Complex operator-(Complex b) const
{
Complex result= Complex();
mpf_sub(result.realPart,b.realPart,this->realPart);
mpf_sub(result.imaginaryPart,b.imaginaryPart,this->imaginaryPart);
return result;
}
Complex operator*(Complex b) const
{
Complex result= Complex();
mpf_t ac,bd,bc,ad;
mpf_init2(ac,333);
mpf_init2(bd,333);
mpf_init2(bc,333);
mpf_init2(ad,333);

mpf_mul(ac,b.realPart,this->realPart);
mpf_mul(bd,b.imaginaryPart,this->imaginaryPart);
mpf_mul(bc,b.realPart,this->imaginaryPart);
mpf_mul(ad,b.imaginaryPart,this->realPart);
mpf_sub(result.realPart,ac,bd);
mpf_add(result.imaginaryPart,bc,ad);


return result;
}
Complex operator/(Complex b) const
{
Complex result= Complex();
mpf_t ac,bd,bc,ad;
mpf_t temp1,temp2;

mpf_init2(ac,333);
mpf_init2(bd,333);
mpf_init2(bc,333);
mpf_init2(ad,333);
mpf_init2(temp1,333);
mpf_init2(temp2,333);
mpf_mul(ac,b.realPart,this->realPart);
mpf_mul(bd,b.imaginaryPart,this->imaginaryPart);
mpf_mul(bc,b.realPart,this->imaginaryPart);
mpf_mul(ad,b.imaginaryPart,this->realPart);

//(a+bi)/(c+di)=(ac + bd)/(c^2 + d ^2) +((bc - ad)/(c ^2 + d ^2)) i
mpf_pow_ui(temp1,b.realPart,2);
mpf_pow_ui(temp2,b.imaginaryPart,2);
mpf_add(temp1,temp1,temp2);
mpf_add(result.realPart,ac,bd);
mpf_div(result.realPart,result.realPart,temp1);
mpf_sub(result.imaginaryPart,bc,ad);
mpf_div(result.imaginaryPart,result.imaginaryPart,temp1);

return result;
}
Complex operator+(string buf) const
{

Complex result= Complex();
result=(*this);
mpf_t temp;
mpf_init2(temp,333);

if(CheckImga(buf)){
if(buf.length()==1)//说明是纯虚数
buf="1";//将唯一的i,替换为数字1
else
buf.pop_back();//删除最后一个为 i
mpf_set_str(temp,buf.c_str(),10);
mpf_add(result.imaginaryPart,this->imaginaryPart,temp);
}else{
mpf_set_str(temp,buf.c_str(),10);
mpf_add(result.realPart,this->realPart,temp);
}

return result;
}
Complex operator-(string buf) const
{

Complex result= Complex();
result=(*this);
mpf_t temp;
mpf_init2(temp,333);

if(CheckImga(buf)){
if(buf.length()==1)//说明是纯虚数
buf="1";//将唯一的i,替换为数字1
else
buf.pop_back();//删除最后一个为 i
mpf_set_str(temp,buf.c_str(),10);
mpf_sub(result.imaginaryPart,this->imaginaryPart,temp);
}else{
mpf_set_str(temp,buf.c_str(),10);
mpf_sub(result.realPart,this->realPart,temp);
}

return result;
}
Complex operator*(string buf) const
{
Complex result= Complex();
result=(*this);
Complex temp=Complex();
if(CheckImga(buf)){
if(buf.length()==1)//说明是纯虚数
buf="1";//将唯一的i,替换为数字1
else
buf.pop_back();//删除最后一个为 i
mpf_set_str(temp.imaginaryPart,buf.c_str(),10);
}else{
mpf_set_str(temp.realPart,buf.c_str(),10);
}

result=(*this)*temp;
return result;
}
Complex operator/(string buf) const
{
Complex result= Complex();
result=(*this);
Complex temp=Complex();
if(CheckImga(buf)){
if(buf.length()==1)//说明是纯虚数
buf="1";//将唯一的i,替换为数字1
else
buf.pop_back();//删除最后一个为 i
mpf_set_str(temp.imaginaryPart,buf.c_str(),10);
}else{
mpf_set_str(temp.realPart,buf.c_str(),10);
}
result=(*this)/temp;
return result;
}
string mod() const
{
mpf_t a,b,c;
string result;
mp_exp_t exponent;
char* word;

mpf_init2(a,333);
mpf_init2(b,333);
mpf_init2(c,333);
mpf_pow_ui(a,this->realPart,2);
mpf_pow_ui(b,this->imaginaryPart,2);
mpf_add(a,a,b);
mpf_sqrt(c,a);

word=mpf_get_str(nullptr,&exponent,10,0,c);
result=word;
result=MpfAdjustResult(exponent,result);
return result;
}
string con() const
{
mpf_t a,b,c;
mp_exp_t exponent;//long
char* word;
string result1;
string result2;
int idx_neg;
bool flag_neg=0;

mpf_init2(a,333);
mpf_init2(b,333);
mpf_init2(c,333);
result1=this->realdata();
mpf_neg(b,this->imaginaryPart);//取反
word=mpf_get_str(nullptr,&exponent,10,0,b);
result2=word;
idx_neg=result2.find('-');
if(idx_neg!=std::string::npos){
result2.erase(idx_neg,1);
flag_neg=1;
}
result2=MpfAdjustResult(exponent,result2);
if(flag_neg){
result2.insert(idx_neg,"-");
}

if(!result2.empty()&&!result1.empty()){
result2.append("i");
return result1+"+"+result2;
}else if(result1.empty()){
result2.append("i");
return result2;
}else{
return result1;
}
}
string alldata() const
{
string str1=this->realdata();
string str2=this->imagdata();
return str1+str2;
}
string realdata() const
{
mp_exp_t exponent;
char* word;
string result;
char buffer[100];
bool neg_flag=0;

mpf_get_str(buffer,&exponent,10,0,this->realPart);
result=buffer;
if(result.find("-")!=std::string::npos){
neg_flag=true;
result.erase(result.find("-"),1);
}

result=MpfAdjustResult(exponent,result);
if(neg_flag){
result.insert(0,"-");
}
return result;
}
string imagdata() const
{
mp_exp_t exponent;
string result;
char buffer[100];
bool neg_flag=false;

mpf_get_str(buffer,&exponent,10,0,this->imaginaryPart);
result = buffer;
if(result.find("-")!=std::string::npos){
neg_flag=true;
result.erase(result.find("-"),1);
}
result=MpfAdjustResult(exponent,result);

if(!result.empty()){
result+="i";
if(neg_flag){
result.insert(0,"-");
}else{
result.insert(0,"+");
}
}
return result;
}
void print()const
{
gmp_printf("实部:%Ff\n",this->realPart);
gmp_printf("虚部:%Ff\n",this->imaginaryPart);
cout<<this->realdata()<<endl;
cout<<this->imagdata()<<endl;
}
};

int main()
{
// 为 a 赋值,a=0
Complex Com_Result=Complex();

string key;//变量名
string value;//存储的值
string buf;
int idx_equal=0;
int prec_set=0;
// cout<<"请输入你要的精度:";
// cin>>prec_set;
// getchar();
// mpf_set_default_prec(prec_set);

while(1){
cout<<">>> ";
Invalid=0;
getline(cin,buf);//从输入流中读取一行数据到buf
BlankFliter(buf);
if(buf.find("=")!= std::string::npos){
bool is_exist=0;
idx_equal=buf.find("=");
key=buf.substr(0,idx_equal);
value=buf.substr(idx_equal+1,buf.length()-idx_equal-1);//a=2+3 len=5 idx_equal=1 传入的大小是5-1-1
NameTraslate(value);
NameTraslate(value);
BlankFliter(value);
ModTraslate(value);
ConTraslate(value);
CountEr(value);
if(NameCheck(key)){
umap[key]=value;
}else{
cout<<"变量名格式错误!请重新命名..."<<endl;
}//这里要处理value的值
}//第二个是调用变量名
else if(umap.find(buf)!=umap.end()){//判断迭代器是否到尾部,到尾部说明没有这个变量
cout<<umap[buf]<<endl;
}
else{
NameTraslate(buf);
NameTraslate(buf);
ModTraslate(buf);
ConTraslate(buf);
BlankFliter(buf);
CountEr(buf);
if(!Invalid){
cout<<buf<<endl;
}
}
//表达式
}
return 0;
}

void CountEr(string &buf){//引用修改是直接修改变量 //当然对于一些特殊符号,要在前面进行语义解析和翻译工作. //比如mod运算,和++运算,还有共轭复数运算,甚至是变量
char oper;//操作符
Complex result= Complex();//最后的结果。
Complex temp_result=Complex();
Complex zero_com=Complex();
vector<Complex> mulsave(0);
int idx_i;//虚数i的下标//科学计数法e的下标
int idx_oper=0;
int idx_num2_end;
int idxoffset=0;
int pre_idx=0;
stack<char> opstack1;
stack<char> opstack2;
stack<string> bufstack1;
stack<string> bufstack2;

//去除空格之后,通过运算符 来筛选操作符和操作数。
for(int i=0;i<buf.length();i++){
int idx_e=buf.find('E',i);//找到E的位置
if(idx_e!= std::string::npos){
if(buf[idx_e+1]=='-'){//如果e的下个字符是-号的话,换成不处理的符号
buf[idx_e+1]='#';
}
}
if(buf[i]=='+'||buf[i]=='-'||buf[i]=='*'||buf[i]=='/'||buf[i]=='('||buf[i]==')'){
idxoffset=i-idx_oper;
idx_oper=i;

if(pre_idx==0||idxoffset>1){// 1*(2+3) *和(下标差距为1 idx_oper=1, i=2 idxoffset=1
string temp;
if(pre_idx==0){
temp=buf.substr(pre_idx,idxoffset);
}
else if(pre_idx!=0){
temp=buf.substr(pre_idx,idxoffset-1);
}
ETraslate(temp);
bufstack1.push(temp);//2+3+6 则插入3
if(buf[idx_oper+1]=='('){
pre_idx=idx_oper+2;
}else{
pre_idx=idx_oper+1;
}

}
opstack1.push(buf[i]);

}
if(buf[i]!=')'&&i==buf.length()-1){//到字符串末尾 idx_op=3 i=4 idx_offset=1 buf.length=5
string temp;
if(pre_idx==0){
temp=buf.substr(idx_oper,buf.length()-idx_oper);
}else{
temp=buf.substr(idx_oper+1,buf.length()-idx_oper-1);
}
ETraslate(temp);
bufstack1.push(temp);//2+3-6 插入6
}
}
//利用另外两个栈,实现后缀表达式
bufstack2.push(bufstack1.top());//先入栈一个操作数
bufstack1.pop();

//入栈第二个操作数,入栈第一个操作符,防止访问空栈
if(!opstack1.empty()&&opstack1.top()==')'){//第一个括号都是)先入栈
opstack2.push(opstack1.top());
opstack1.pop();
}

if(!opstack1.empty()){
opstack2.push(opstack1.top());
opstack1.pop();
}
if(!bufstack1.empty()){
bufstack2.push(bufstack1.top());
bufstack1.pop();
}

if(opstack2.empty()&&bufstack2.size()==1){
ETraslate(buf);
for(int i=0;i<buf.length();i++){
if(isalpha(buf[i])&&buf[i]!='i'){

cerr<<"存在非法变量"<<endl;
Invalid=1;
return ;
}
}
buf=bufstack2.top();
bufstack2.pop();
return;//只有一个值,就不管他,直接返回
}
while(bufstack2.top()!="@"||bufstack2.size()>1||!opstack1.empty()||!opstack2.empty()){//依据操作符栈1是否为空判断是否结束
if((!opstack1.empty())){
if(!opstack1.empty()&&!opstack2.empty()&&(WhoFirst(opstack1.top())>=WhoFirst(opstack2.top()))){//来者的优先级比较大,就不管它
if(opstack1.top()=='('&&opstack2.top()==')'){
opstack1.pop();
opstack2.pop();
}
opstack2.push(opstack1.top());
opstack1.pop();
bufstack2.push(bufstack1.top());
bufstack1.pop();
}else if(!opstack1.empty()&&!opstack2.empty()&&(WhoFirst(opstack1.top())<WhoFirst(opstack2.top()))){//来者的优先级比较小,我们就要进行运算。
//这里的运算也要判断是否为虚数i,先放进类
char op=opstack2.top();
opstack2.pop();
switch (op){
case '+':
//bufstack2.top()=bufstack2.top()+bufstack1.top();//进行运算
if(bufstack2.top() =="@" && mulsave.size()!=0){
result=result+mulsave.back();
mulsave.pop_back();
bufstack2.pop();
}else{
if(bufstack2.top()=="@")
result=result+"0";
else
result=result+bufstack2.top();
cout<<"2+1: "<<endl;
bufstack2.pop();//把0pop掉
}
if(bufstack2.top() =="@" && mulsave.size()!=0){
result=result+mulsave.back();
mulsave.pop_back();
bufstack2.pop();
}else{
if(bufstack2.top()=="@")
result=result+"0";
else
result=result+bufstack2.top();
bufstack2.pop();//把0pop掉
}
bufstack2.push("@");//推入0,是为了代替运算后的结构的数据,因为运算后的结果已经保存到COM中了
break;
case '-':
//bufstack2.top()=bufstack2.top()+bufstack1.top();//进行运算
if(bufstack2.top() =="@" && mulsave.size()!=0){
result=result+mulsave.back();
mulsave.pop_back();
bufstack2.pop();
}else{
if(bufstack2.top()=="@")
result=result+"0";
else
result=result+bufstack2.top();
bufstack2.pop();//把0pop掉
}
if(bufstack2.top() =="@" && mulsave.size()!=0){
result=result-mulsave.back();
mulsave.pop_back();
bufstack2.pop();
}else{
if(bufstack2.top()=="@")
result=result+"0";
else
result=result-bufstack2.top();
bufstack2.pop();//把0pop掉
}
bufstack2.push("@");//推入0,是为了代替运算后的结构的数据,因为运算后的结果已经保存到COM中了
break;
case '*':
//bufstack2.top()=bufstack2.top()+bufstack1.top();//进行运算
temp_result=zero_com;
if(bufstack2.top() =="@" && mulsave.size()!=0){
temp_result=mulsave.back();
mulsave.pop_back();
bufstack2.pop();
}else{
if(bufstack2.top()=="@")
temp_result=temp_result+"0";
else
temp_result=temp_result+bufstack2.top();
bufstack2.pop();//把0pop掉
}
if(bufstack2.top() =="@" && mulsave.size()!=0){
temp_result=temp_result*mulsave.back();
mulsave.pop_back();
bufstack2.pop();
}else{
if(bufstack2.top()=="@")
temp_result=temp_result+"0";
else
temp_result=temp_result*bufstack2.top();
bufstack2.pop();//把0pop掉
}
bufstack2.push("@");//推入0,是为了代替运算后的结构的数据,因为运算后的结果已经保存到COM中了
mulsave.push_back(temp_result);
break;
case '/':
//bufstack2.top()=bufstack2.top()+bufstack1.top();//进行运算
temp_result=zero_com;
if(bufstack2.top() =="@" && mulsave.size()!=0){
temp_result=mulsave.back();
mulsave.pop_back();
bufstack2.pop();
}else{
if(bufstack2.top()=="@")
temp_result=temp_result+"0";
else
temp_result=temp_result+bufstack2.top();
bufstack2.pop();//把0pop掉
}
if(bufstack2.top() =="@" && mulsave.size()!=0){
temp_result=temp_result/mulsave.back();
mulsave.pop_back();
bufstack2.pop();
}else{
if(bufstack2.top()=="@")
temp_result=temp_result+"0";
else
temp_result=temp_result/bufstack2.top();
bufstack2.pop();//把0pop掉
}//推入0,是为了代替运算后的结构的数据,因为运算后的结果已经保存到COM中了
mulsave.push_back(temp_result);
break;
case '(':
//不断计算算直到遇到 (
if(opstack2.top()!=')'){
///////////////////////////////////////////////////////////////////////////////////////////////////
switch (op){//用上面的东西再运算一遍
case '+':
//bufstack2.top()=bufstack2.top()+bufstack1.top();//进行运算
if(bufstack2.top() =="@" && mulsave.size()!=0){
result=result+mulsave.back();
mulsave.pop_back();
bufstack2.pop();
}else{
if(bufstack2.top()=="@")
result=result+"0";
else
result=result+bufstack2.top();
bufstack2.pop();//把0pop掉
}
if(bufstack2.top() =="@" && mulsave.size()!=0){
result=result+mulsave.back();
mulsave.pop_back();
bufstack2.pop();

}else{
if(bufstack2.top()=="@")
result=result+"0";
else
result=result+bufstack2.top();
bufstack2.pop();//把0pop掉
}
bufstack2.push("@");//推入0,是为了代替运算后的结构的数据,因为运算后的结果已经保存到COM中了
break;
case '-':
//bufstack2.top()=bufstack2.top()+bufstack1.top();//进行运算
if(bufstack2.top() =="@" && mulsave.size()!=0){
result=result+mulsave.back();
mulsave.pop_back();

bufstack2.pop();
}else{
if(bufstack2.top()=="@")
result=result+"0";
else
result=result+bufstack2.top();
bufstack2.pop();//把0pop掉
}
if(bufstack2.top() =="@" && mulsave.size()!=0){
result=result-mulsave.back();
mulsave.pop_back();
bufstack2.pop();
}else{
if(bufstack2.top()=="@")
result=result+"0";
else
result=result-bufstack2.top();
bufstack2.pop();//把0pop掉
}
bufstack2.push("@");//推入0,是为了代替运算后的结构的数据,因为运算后的结果已经保存到COM中了
break;
case '*':
temp_result=zero_com;
if(bufstack2.top() =="@" && mulsave.size()!=0){
temp_result=mulsave.back();
mulsave.pop_back();

bufstack2.pop();
}else{
if(bufstack2.top()=="@")
temp_result=temp_result+"0";
else
temp_result=temp_result+bufstack2.top();
bufstack2.pop();//把0pop掉
}
if(bufstack2.top() =="@" && mulsave.size()!=0){
temp_result=temp_result*mulsave.back();
mulsave.pop_back();

bufstack2.pop();
}else{
if(bufstack2.top()=="@")
temp_result=temp_result+"0";
else
temp_result=temp_result*bufstack2.top();
bufstack2.pop();//把0pop掉
}
bufstack2.push("@");//推入0,是为了代替运算后的结构的数据,因为运算后的结果已经保存到COM中了
mulsave.push_back(temp_result);
break;
case '/':
temp_result=zero_com;
//bufstack2.top()=bufstack2.top()+bufstack1.top();//进行运算
if(bufstack2.top() =="@" && mulsave.size()!=0){
temp_result=mulsave.back();
mulsave.pop_back();

bufstack2.pop();
}else{
if(bufstack2.top()=="@")
temp_result=temp_result+"0";
else
temp_result=temp_result+bufstack2.top();
bufstack2.pop();//把0pop掉
}
if(bufstack2.top() =="@" && mulsave.size()!=0){
temp_result=temp_result/mulsave.back();
mulsave.pop_back();

bufstack2.pop();
}else{
if(bufstack2.top()=="@")
temp_result=temp_result+"0";
else
temp_result=temp_result/bufstack2.top();
bufstack2.pop();//把0pop掉
}
bufstack2.push("@");//推入0,是为了代替运算后的结构的数据,因为运算后的结果已经保存到COM中了
mulsave.push_back(temp_result);
break;
default:
break;
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}else{
cout<<"将)出栈"<<endl;
opstack2.pop();//将stack2的op )出栈
}
default:
break;
}
}else{//opstack1不空,但是opstack2空。
if(opstack1.top()=='('&&opstack2.top()==')'){
opstack1.pop();
opstack2.pop();
}
opstack2.push(opstack1.top());
opstack1.pop();
bufstack2.push(bufstack1.top());
bufstack1.pop();
}
} //opstack2.size()<1
else {//只有一个符号或者为空.
if(opstack1.empty()){//符号栈空了,说明已经用完了,应该计算
//要么是运算符号
while (!opstack2.empty()){
char op=opstack2.top();
opstack2.pop();
switch (op){
case '+':
//bufstack2.top()=bufstack2.top()+bufstack1.top();//进行运算
if(bufstack2.top() =="@" && mulsave.size()!=0){
result=result+mulsave.back();
mulsave.pop_back();

bufstack2.pop();
}else{
if(bufstack2.top()=="@")
result=result+"0";
else
result=result+bufstack2.top();
bufstack2.pop();//把0pop掉
}
if(bufstack2.top() =="@" && mulsave.size()!=0){
result=result+mulsave.back();
mulsave.pop_back();

bufstack2.pop();
}else{
if(bufstack2.top()=="@")
result=result+"0";
else
result=result+bufstack2.top();
bufstack2.pop();//把0pop掉
}
bufstack2.push("@");//推入0,是为了代替运算后的结构的数据,因为运算后的结果已经保存到COM中了
break;
case '-':
//bufstack2.top()=bufstack2.top()+bufstack1.top();//进行运算
if(bufstack2.top() =="@" && mulsave.size()!=0){
result=result+mulsave.back();
mulsave.pop_back();
}else{
if(bufstack2.top()=="@")
result=result+"0";
else
result=result+bufstack2.top();
bufstack2.pop();//把0pop掉
}
if(bufstack2.top() =="@" && mulsave.size()!=0){
result=result-mulsave.back();
mulsave.pop_back();
}else{
if(bufstack2.top()=="@")
result=result+"0";
else
result=result-bufstack2.top();
bufstack2.pop();//把0pop掉
}
bufstack2.push("@");//推入0,是为了代替运算后的结构的数据,因为运算后的结果已经保存到COM中了
break;
case '*':
temp_result=zero_com;
if(bufstack2.top() =="@" && mulsave.size()!=0){
temp_result=temp_result+mulsave.back();
mulsave.pop_back();
bufstack2.pop();
}else{
if(bufstack2.top()=="@")
temp_result=temp_result+"0";
else
temp_result=temp_result+bufstack2.top();
bufstack2.pop();//把0pop掉
}
if(bufstack2.top() =="@" && mulsave.size()!=0){
temp_result=temp_result*mulsave.back();
mulsave.pop_back();
bufstack2.pop();
}else{
if(bufstack2.top()=="@")
temp_result=temp_result+"0";
else
temp_result=temp_result*bufstack2.top();
bufstack2.pop();//把0pop掉
}
bufstack2.push("@");//推入0,是为了代替运算后的结构的数据,因为运算后的结果已经保存到COM中了
mulsave.push_back(temp_result);
break;
case '/':
temp_result=zero_com;
//bufstack2.top()=bufstack2.top()+bufstack1.top();//进行运算
if(bufstack2.top() =="@" && mulsave.size()!=0){
temp_result=temp_result+mulsave.back();
mulsave.pop_back();
bufstack2.pop();
}else{
if(bufstack2.top()=="@")
temp_result=temp_result+"0";
else
temp_result=temp_result+bufstack2.top();
bufstack2.pop();//把0pop掉
}
if(bufstack2.top() =="@" && mulsave.size()!=0){
temp_result=temp_result/mulsave.back();
mulsave.pop_back();
bufstack2.pop();
}else{
if(bufstack2.top()=="@")
temp_result=temp_result+"0";
else
temp_result=temp_result/bufstack2.top();
bufstack2.pop();//把0pop掉
}
bufstack2.push("@");//推入0,是为了代替运算后的结构的数据,因为运算后的结果已经保存到COM中了
mulsave.push_back(temp_result);
break;
}
}
}else{
cerr<<"异常操作"<<endl;//此时opstack2为空,opstack1还没有操作
exit(0);
}
}
}
if(mulsave.size()==1){
result=mulsave.back();
mulsave.pop_back();
}
ETraslate(buf);
for(int i=0;i<buf.length();i++){
if(isalpha(buf[i])&&buf[i]!='i'){
cerr<<"存在非法变量"<<endl;
Invalid=1;
}
}
//对应输出
if(Out_State == 0){
buf=result.alldata();
Out_State=0;
}else if(Out_State == 1){
buf=result.mod();
Out_State=0;
}else if(Out_State == 2 ){
//buf=result.con();
Out_State=0;
}
return ;
}
void NameTraslate(string &buf){
string::const_iterator it = buf.begin();
string::const_iterator word_start;
string::const_iterator word_end;
string word;
int idx=0;
int next_idx=0;
for (const auto& it : umap) {
idx=buf.find(it.first,0);
if(idx!= std::string::npos){//如果不等于,说明找到了
next_idx=idx+it.first.length();
buf.replace(idx,it.first.length(),it.second);//用值替换对应对的键
}
}
if(buf.find('_')!=std::string::npos){//如果还找到相对应对的标识符,输出,未定义对的变量.
cerr<<"未定义的变量"<<endl;
}
}
bool NameCheck(string &buf){
if((buf=="mod")||(buf=="con")||(buf=="i")||(buf=="E")){
cerr<<"变量名和关键字方法相同,请重新命名..."<<endl;
}
if(std::isalpha(buf[0])||buf[0]=='_'){
for(int i=1;i<buf.length();i++){
if(std::isalpha(buf[i])||buf[i]=='_'||('0'<=buf[i]&&buf[i]<='9')){
}else{
cerr<<"变量名不符合规范..."<<endl;
return 0;
}
}
}else{
cerr<<"变量名首字符不符合规范..."<<endl;
return 0;
}
return 1;
}
void ModTraslate(string &buf){ //mod(3+5i)
Complex result=Complex();
int find_idx=buf.find("mod(",0);
int end_idx=buf.find(")",find_idx);
int start_idx=find_idx+4;
string temp;
if(find_idx!=std::string::npos||end_idx!=std::string::npos){
Out_State=1;
temp=buf.substr(start_idx,end_idx-start_idx);
CountEr(temp);
result=result+temp;
temp=result.mod();
buf.replace(find_idx,end_idx-find_idx+1,temp);
}
}
void ConTraslate(string &buf){
Complex result=Complex();
int find_idx=buf.find("con(",0);
int end_idx=buf.find(")",find_idx);
int start_idx=find_idx+4;
string temp;
if(find_idx!=std::string::npos||end_idx!=std::string::npos){
Out_State=2;
temp=buf.substr(start_idx,end_idx-start_idx);
CountEr(temp);
result=result+temp;
temp=result.con();
buf.replace(find_idx,end_idx-find_idx+1,temp);
}
}
void ETraslate(string &buf){
string s=buf;
int idx_e = s.find("E");
int idx_ch =s.find("#");
int idx_i=s.find("i");
bool flag_i=0;

if(idx_e!= std::string::npos){
if(idx_i!=std::string::npos){
buf.pop_back();//把i给pop掉
flag_i=1;
}
if(idx_ch!= std::string::npos){//如果存在的话{
buf[idx_ch]='-';
}
string base = s.substr(0, idx_e); //获取小数部分
int exp = stoi(s.substr(idx_e + 1)); //获取指数部分
buf=AdjustResult(exp,base);
if(flag_i){
buf.append("i");
}
}else {
return ;
}
}
bool CheckImga(string &buf)
{
for(int i=0;i<buf.length();i++){
if(buf[i]=='i')
return true;
}
return false;
}


void BlankFliter(string &str)//使用C++string类的方法快速删除空格
{
//std::remove_if函数用于将所有空白字符移动到字符串的末尾,
//然后使用erase函数将它们从字符串中删除。
//::isspace函数是一个标准库函数,用于检查一个字符是否为空白字符。
str.erase(std::remove_if(str.begin(), str.end(), ::isspace), str.end());
}

int WhoFirst(char op)
{
if(op=='(')
return 1;
else if(op=='+'||op=='-')
return 2;
else if(op=='*'||op=='/')
return 3;
if(op==')')
return 1;
else
cerr<<"错误的字符输入"<<endl;
}

string AdjustResult(int exp,string &buf){
string adjust_result;
if (exp < 0) {
// 计算小数点需要向左移动的位数
int move = -exp;
adjust_result = "0." + std::string(move, '0') + buf;
} else {
// 在整数部分后面拼接exp个"0"
adjust_result = buf + std::string(exp, '0');
}
return adjust_result;
}
string MpfAdjustResult(int exp,string &buf){
int len=buf.length();
if (exp <= 0) {
if(len){
// 计算小数点需要向左移动的位数
int move = -exp;
buf = "0." + std::string(move, '0') + buf;
}
} else if(exp>0){
if(len>exp){//对于长度大于exp的小数
buf.insert(exp,1,'.');
return buf;
}else if(len==exp){//对于小数点刚好在其数字后面的整数
return buf;
}
exp=exp-len;
buf = buf + std::string(exp, '0');
}else{
return buf;
}
return buf;
}