-
Notifications
You must be signed in to change notification settings - Fork 1
/
Poland.cpp
3077 lines (2812 loc) · 98.8 KB
/
Poland.cpp
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
/*
* Guangzhou ZHIYUAN electronics Co.,LTD.
* http:https://www.embedtools.com
* All rights reserved
*
* @file Poland.cpp
* @brief Poland Expression Class 波兰表达式的计算
*
* Change Logs:
* Date Author Notes
* 2012-08-10 Libing Second Edtion
*/
#include "Poland.h"
#define OPERATORMOST 38 /**< 运算符个数 */
#define CONSTVARIABLEMOST 2 /**< 常量个数 */
#define COMMANDMOST 11 /**< 命令个数 */
#include"BigDouble.h"
#include<string>
#include <iostream>
#include<vector>
#include <stack>
#include <fstream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include <iomanip>
/**
* @brief 常量字典
* @details 存储计算中常用到的常数,用户可以直接使用
*/
const Variable VariableDic[CONSTVARIABLEMOST]= {
{"pi",ConstVariable,3.141592653589793,BigDouble(3.141592653589793)},
{"e" ,ConstVariable,2.718281828459046,BigDouble(2.718281828459046)},
};
/**
* @brief 常用运算符字典
* @details 存储数学表达式中常用到的运算符、函数、括号等以及类型和优先级
*/
const Operator OperatorDic[OPERATORMOST] = {
{"&&",BinOperator ,2},
{"||",BinOperator ,2},
{"<=",BinOperator ,3},
{">=",BinOperator ,3},
{"==",BinOperator ,4},
{"!=",BinOperator ,4},
{"=" ,BinOperator ,1},
{"," ,BinOperator ,0},
{"<" ,BinOperator ,3},
{">" ,BinOperator ,3},
{"+" ,BinOperator ,5},
{"-" ,BinOperator ,5},
{"*" ,BinOperator ,6},
{"/" ,BinOperator ,6},
{"%" ,BinOperator ,6},
{"^" ,BinOperator ,7},
{"#" ,UnayOprator ,7}, /* 负号,使用#代替,和减号区分 */
{"~" ,UnayOprator ,7}, /* 布尔取反 */
{"!" ,UnayOprator ,7}, /* 阶乘 */
{"(" ,LeftParen ,8},
{")" ,RightParen ,8},
{";" ,EndExpression,9},
/* 函数 */
{"sin" ,Function ,7},
{"cos" ,Function ,7},
{"tan" ,Function ,7},
{"cot" ,Function ,7},
{"asin" ,Function ,7},
{"acos" ,Function ,7},
{"atan" ,Function ,7},
{"acot" ,Function ,7},
{"log10",Function ,7},
{"log" ,Function ,7},
{"exp" ,Function ,7},
{"pow" ,Function ,7},
{"sqrt" ,Function ,7},
{"abs" ,Function ,7},
{"ceil" ,Function ,7},
{"floor",Function ,7},
};
/**
* @brief 命令字典
* @details 存储命令系统中常用的命令,以及注解和用法示例
*/
const Command CommandDic[COMMANDMOST]={
{"help" , "Display help information" , "help whos \nhelp" },/**< 查看帮助 */
{"whos" , "Lists all the variables" , "whos" },/**< 查看所有变量 */
{"who" , "List current variables." , "who variableName" },/**< 查看指定变量 */
{"clc" , "Clear command window." , "clc" },/**< 清屏 */
{"clear" , "Removes all variables" , "clear variableName \nclear" },/**< 清除变量 */
{"operator" , "Define user's Operator" , "operator $ a$b 1/2*pi*a*b 4"},/**< 清屏 */
{"copyright", "Display copyright declaration" , "copyright" },/**< 版权声明 */
{"history" , "Display history expression." , "history" },/**< 历史记录 */
{"exit" , "Exit from the console" , "exit" },/**< 退出程序 */
{"test" , "Auto test the programm" , "test test.txt" },/**< 自动测试 */
{"dic" , "Display the dictionary" , "dic" },/**< 打印字典 */
};
/**
* @defgroup Constructors_Poland
* 用于Poland类的初始化
*/
/**
* @defgroup Destructors_Poland
* 用于Poland类的销毁
*/
/**
* @defgroup MemberFunction_Poland
* Poland类的成员函数,进行波兰表达式的计算
*/
/**
* @ingroup Constructors_Poland
* @brief Poland类的构造函数
*
* @code
* Poland poland;
* @endcode
*/
Poland::Poland(void)
{
this->Initialize();
}
/**
* @ingroup Destructors_Poland
* @brief Poland类的析构函数
*
* @code
* Poland poland;
* ~poland;
* @endcode
*/
Poland::~Poland(void)
{
}
/**
* @ingroup MemberFunction_Poland
* @brief Poland类的参数的初始化,在构造函数中自动调用
*
*/
void Poland::Initialize(){
/*
* 初始化代码,为了计算方便,这里加入一个变量ans和ansB,用于存储计算表达式的结果,供下次计算使用
*/
Variable VariableTemp = {"ans",VariableDouble,0.0,BigDouble(0.0)};
VariableVector.push_back(VariableTemp);
Variable VariableTemp2 = {"ansB",VariableBigDouble,0.0,BigDouble(1.23,1000)};
VariableVector.push_back(VariableTemp2);
}
/**
* @ingroup MemberFunction_Poland
* @brief 打印语法字典,包括运算符、常量、变量、自定义运算符
*
* @code
* Poland poland;
* Poland.PrintDictionary();
* @endcode
*/
void Poland::PrintDictionary(){
/*
* 打印常量
*/
cout<<"Variable Name\t\t"<<"Number"<<endl;
for (int i = 0; i< CONSTVARIABLEMOST;i++)
{
cout<<VariableDic[i].cName<<"\t\t\t"<<VariableDic[i].dNumber<<endl;
/*cout<<setw(35)<<VariableDic[i].cName<<VariableDic[i].dNumber<<endl;*/
}
/*
* 打印用户定义变量
*/
cout<<"\n\nUser Variable\t\t"<<"Number"<<endl;
for (int i = 0; i< static_cast<int>(VariableVector.size());i++)
{
if (VariableVector.at(i).kind == VariableDouble)
{
cout<<VariableVector.at(i).cName<<"\t\t\t"<<VariableVector.at(i).dNumber<<endl;
}else if (VariableVector.at(i).kind == VariableBigDouble)
{
cout<<VariableVector.at(i).cName<<"\t\t\t"
<<VariableVector.at(i).bdNumber.getBigDoubleStr()<<endl;
}
}
/*
* 打印常用运算符
*/
cout<<"\n\nOperator Name\t\t"<<"Priority"<<endl;
for (int i = 0; i< OPERATORMOST;i++)
{
cout<<OperatorDic[i].cName<<"\t\t\t"<<OperatorDic[i].iPriority<<endl;
}
/*
* 打印用户自定义运算符
*/
cout<<"\n\nUser Operator\t\t"<<"Priority\t\t"<<"Express"<<endl;
for (int i = 0; i< static_cast<int>(UserOperatorVector.size());i++)
{
cout<<UserOperatorVector.at(i).cOperator<<"\t\t\t"<<UserOperatorVector.at(i).iPriority<<"\t\t\t"
<<UserOperatorVector.at(i).sExpress<<endl;
}
}
/**
* @ingroup MemberFunction_Poland
* @brief 打印用户自定义变量
*
* @code
* Poland poland;
* Poland.PrintVariable();
* @endcode
*/
void Poland::PrintVariable(){
cout<<setiosflags(ios_base::left);
cout<<setw(35)<<"User Variable"<<"Number"<<endl;
for (int i = 0; i< static_cast<int>(VariableVector.size());i++)
{
if (VariableVector.at(i).kind == VariableDouble)
{
cout<<setw(35)<<VariableVector.at(i).cName
<<VariableVector.at(i).dNumber<<endl;
}else if (VariableVector.at(i).kind == VariableBigDouble)
{
cout<<setw(35)<<VariableVector.at(i).cName
<<VariableVector.at(i).bdNumber.getBigDoubleStr()<<endl;
}
}
cout<<resetiosflags(ios_base::left);
}
/**
* @ingroup MemberFunction_Poland
* @brief 打印常用运算符和用户自定义运算符
*
* @code
* Poland poland;
* Poland.PrintOperator();
* @endcode
*/
void Poland::PrintOperator(){
cout<<setiosflags(ios_base::left);
cout<<setw(20)<<"Operator Name"<<"Priority"<<endl;
for (int i = 0; i< OPERATORMOST;i++)
{
cout<<setw(20)<<OperatorDic[i].cName<<OperatorDic[i].iPriority<<endl;
}
cout<<setw(20)<<"User Operator"
<<setw(20)<<"Priority"<<"Express"<<endl;
for (int i = 0; i< static_cast<int>(UserOperatorVector.size());i++)
{
cout<<setw(20)<<UserOperatorVector.at(i).cOperator
<<setw(20)<<UserOperatorVector.at(i).iPriority
<<UserOperatorVector.at(i).sExpress<<endl;
}
cout<<resetiosflags(ios_base::left);
}
/**
* @ingroup MemberFunction_Poland
* @brief 将string类型表达式拆分成数值、变量、常量、运算符、自定义运算符等基本元素,分别存储到相应的向量
* vector中
* @param[in] sExpress 用户输入的的string类型的数学表达式
* @note sExpress中不能有汉字;可以有空格;可以含有多条表达式,但是需要用分号";"分隔
* @code
* string sExpress;
* Poland poland;
* getline(cin,sExpress);
* Poland.BreakExpress(sExpress);
* @endcode
*/
void Poland::BreakExpress(string sExpress){
/*
* 先将存储下标和类型的向量清空
*/
this->IndexVector.clear();
this->KindTypeVector.clear();
int iLength = sExpress.size();
char *cExpress = new char[iLength +1];
bool OperatorMatch = false;
int LeftIndex = 0;
int RightIndex = iLength;
for (int i = 0; i< iLength;i++)
{
cExpress[i] = sExpress.at(i);
}
cExpress[iLength] = '\0';
this->MarkNegative(cExpress); /* 对负号尽心标记 */
for (int i = 0;i<iLength;i++)
{
OperatorMatch = false;
/*
* 进行运算符匹配时,为了加快速度,首先对第一个字符进行匹配,若匹配第一个,再进行串匹配
*/
for (int j = 0 ; j< OPERATORMOST;j++)
{
bool FirstCharEqual = (cExpress[i] == OperatorDic[j].cName[0]);
if (FirstCharEqual)
{
int iOperatorLength = strlen(OperatorDic[j].cName);
bool IsEqual = this->strnmcmp(OperatorDic[j].cName,cExpress,i);
if (IsEqual)
{
if (OperatorDic[j].kind == Function && cExpress[i+ iOperatorLength] != '(')
{
/*
* 若函数名后面不是左括号,则认为不是函数,有可能是变量,如singal = 1,不能将sin
* 拆出作为函数处理
*/
OperatorMatch = false;
break;
}else{
OperatorMatch = true;
RightIndex = i-1;
/*
* 提取运算符前面的操作数
*/
this->AbstractOperand(cExpress,LeftIndex,RightIndex);
/*
* 将运算符存入vector
*/
IndexVector.push_back(j);
KindTypeVector.push_back(OperatorDic[j].kind);
LeftIndex = i + iOperatorLength;
i = i+ iOperatorLength -1;
break;
}
}
}
}
if (!OperatorMatch)
{
/*
* 若不是常用运算符,则搜索用户自定义运算符
*/
for (int k = 0; k<static_cast<int>(UserOperatorVector.size());k++)
{
if (UserOperatorVector.at(k).cOperator == cExpress[i])
{
OperatorMatch = true;
RightIndex = i-1;
/*
* 提取运算符前面的操作数
*/
this->AbstractOperand(cExpress,LeftIndex,RightIndex);
/*
* 将运算符存入vector
*/
IndexVector.push_back(k);
KindTypeVector.push_back(UserOperatorVector.at(k).kind);
LeftIndex = i + 1;
break;
}
}
}
}
/*
* 提取表达式最后的一个操作数
*/
this->AbstractOperand(cExpress,LeftIndex,iLength -1);
/*
* 允许一样输入多个表达式,表达式之间使用分号分隔,表达式末尾若没有分号,则自动追加
*/
if (KindTypeVector.back() != EndExpression)
{
IndexVector.push_back(20);
KindTypeVector.push_back(EndExpression);
}
delete [] cExpress;
/*
* 将打碎之后的表达式进行保存到历史记录
*/
this->SaveBreakedExpress();
}
/**
* @ingroup MemberFunction_Poland
* @brief 负号-和减号-在数学运算中具有不同的优先级,为了区分负号和减号,将表达式中的负号用一个不常用符号
* "#"代替
* @param[in] cExpress char类型字符串构成的数学表达式
* @code
* char cExpress[] = "1*-1/-2";
* Poland poland;
* Poland.MarkNegative(cExpress);
* @endcode
*/
void Poland::MarkNegative(char* cExpress){
/*
* 负号和减号的区分,加入'-'跟在一个运算符或者函数之后,或者左括号之后,或者新表达式的开头,则是负号
* 否则,认为是减号
*/
int iNextOperatorIndex = 0;
if (cExpress[0] == '-')
{
cExpress[0] = '#';
}
int iLength = strlen(cExpress);
bool OperatorMatch = false;
for (int i = 0;i<iLength;i++)
{
OperatorMatch = false;
for (int j = 0 ;
j< OPERATORMOST
&&( OperatorDic[j].kind == BinOperator
|| OperatorDic[j].kind == UnayOprator
|| OperatorDic[j].kind == LeftParen
|| OperatorDic[j].kind == EndExpression );
j++)
{
bool FirstCharEqual = (cExpress[i] == OperatorDic[j].cName[0]);
if (FirstCharEqual)
{
int iOperatorLength = strlen(OperatorDic[j].cName);
bool IsEqual = this->strnmcmp(OperatorDic[j].cName,cExpress,i);
if (IsEqual)
{
iNextOperatorIndex = i + iOperatorLength;
while(cExpress[iNextOperatorIndex] == ' '){iNextOperatorIndex++;}
if (cExpress[iNextOperatorIndex] == '-')
{
cExpress[iNextOperatorIndex] = '#';
i = iNextOperatorIndex -1;
break;
}
}
}
}
if (!OperatorMatch) /* 不是常用运算符 */
{
/* 查找用户自定义运算符 */
for (int k = 0; k< static_cast<int>(UserOperatorVector.size());k++)
{
if (UserOperatorVector.at(k).cOperator == cExpress[i])
{
if (cExpress[i+1] == '-')
{
cExpress[i+1] = '#';
break;
}
}
}
}
}
}
/**
* @ingroup MemberFunction_Poland
* @brief 自定义字符串比较函数
* @details 子串cSubStr与cStr的从下标StartIndex开始逐个比对,若完全匹配则返回true,否则范围false
* @param[in] cSubStr 子字符串
* @param[in] cStr 字符串
* @param[in] StartIndex 字符串开始下标,从此处开始与子串比对
* @retval true 子串与字符串匹配
* @retval false 子串与字符串不匹配
*/
bool Poland::strnmcmp(const char * cSubStr,char * cStr,int StartIndex){
int iLengthSubStr = strlen(cSubStr);
int iLengthStr = strlen(cStr);
bool IsEqual = true;
if ((iLengthSubStr + StartIndex) <= iLengthStr)
{
for (int i = 0;i< iLengthSubStr;i++)
{
if (cSubStr[i] != cStr[i+StartIndex])
{
IsEqual = false;
break;
}
}
return IsEqual;
}else {
return false;
}
}
/**
* @ingroup MemberFunction_Poland
* @brief 自定义字符串拷贝函数
* @details 从字符串cStr的下标iStartIndex到下标iStopIndex,将之间的字符串拷贝到cSubStr
* @param[in] cSubStr 字符串拷贝目标字符串
* @param[in] cStr 字符串拷贝源字符串
* @param[in] iStartIndex 字符串拷贝开始下标
* @param[in] iStopIndex 字符串拷贝结束下标
*/
void Poland::my_strnmcpy(char * cSubStr,char * cStr,int iStartIndex,int iStopIndex){
int i;
for (i = iStartIndex ; i<= iStopIndex ;i++)
{
cSubStr[i -iStartIndex] = cStr[i];
}
cSubStr[i-iStartIndex] = '\0';
/*cSubStr[iStopIndex-iStartIndex + 1] = '\0';*/
}
/**
* @ingroup MemberFunction_Poland
* @brief 将字符串格式的操作数转化为数值
* @details 其中操作数可以是十六进制、十进制、八进制、二进制数据
* @param[in] cOperandStr 从数学表达式中提取的操作数的字符串
* @return 返回从字符串中提取的double类型的数值
* @note 使用不同进制时,需要加进制标志,例如十六进制加前缀0x或者后缀h,八进制添加后缀o,二进制添加后缀b,
* 十进制添加后缀d,若没有前缀后缀则默认是十进制数,前缀后缀字母使用大小写均可
* @code
* char cOperandStr[] = "ad.ffh";
* Poland poland;
* double dNumber = Poland.OperandStr2Number(cOperandStr);
* @endcode
*/
double Poland::OperandStr2Number(char * cOperandStr){
/*
* 寻找小数点,根据每个数距离小数点的位置得到不同的权值,
* 每个权值*该位的值并求和得到数值
*/
int iLength = strlen(cOperandStr);
int iDotIndex;
double dNumber = 0.0;
char cNumberType = this->NumberTypeCheck(cOperandStr);
if (cNumberType == 'd') /* 十进制,无前缀后缀 */
{
//string DecimalStr = string(cOperandStr);
return atof(cOperandStr);
}else if (cNumberType == 'D') /* 十进制,后缀d */
{
char * cDecimalStr = new char [iLength + 1];
double dTempNumber = 0.0;
for (int j = 0; j<iLength -1;j++)
{
cDecimalStr[j] = cOperandStr[j];
}
cDecimalStr[iLength-1] = '\0';
dTempNumber = atof(cDecimalStr);
delete [] cDecimalStr;
return dTempNumber;
}else if (cNumberType == 'h') /* 十六进制,前缀0x */
{
iDotIndex = iLength;
for (int j = 2 ;j< iLength;j++)
{
if (cOperandStr[j] == '.')
{
iDotIndex = j;
}
}
dNumber = 0.0;
for (int j = 2;j< iLength;j++)
{
if (j > iDotIndex)
{
if (isdigit(cOperandStr[j]))
{
dNumber += pow(16.0, iDotIndex - j)*(cOperandStr[j]-48);
}else {
dNumber += pow(16.0, iDotIndex - j)*(tolower(cOperandStr[j])-'a' + 10);
}
}else if (j< iDotIndex)
{
if (isdigit(cOperandStr[j]))
{
dNumber += pow(16.0, iDotIndex -j-1)*(cOperandStr[j]-48);
}else{
dNumber += pow(16.0, iDotIndex -j-1)*(tolower(cOperandStr[j])-'a' + 10);
}
}
}
return dNumber;
}else if (cNumberType == 'H') /* 十六进制,后缀h */
{
iDotIndex = iLength - 1;
for (int j = 0 ;j< iLength - 1;j++)
{
if (cOperandStr[j] == '.')
{
iDotIndex = j;
}
}
dNumber = 0.0;
for (int j = 0;j< iLength -1;j++)
{
if (j > iDotIndex)
{
if (isdigit(cOperandStr[j]))
{
dNumber += pow(16.0, iDotIndex - j)*(cOperandStr[j]-48);
}else {
dNumber += pow(16.0, iDotIndex - j)*(tolower(cOperandStr[j])-'a' + 10);
}
}else if (j< iDotIndex)
{
if (isdigit(cOperandStr[j]))
{
dNumber += pow(16.0, iDotIndex -j-1)*(cOperandStr[j]-48);
}else{
dNumber += pow(16.0, iDotIndex -j-1)*(tolower(cOperandStr[j])-'a' + 10);
}
}
}
return dNumber;
}else if (cNumberType == 'o') /* 八进制,后缀o */
{
iDotIndex = iLength -1;
for (int j = 0 ;j< iLength -1;j++)
{
if (cOperandStr[j] == '.')
{
iDotIndex = j;
}
}
dNumber = 0.0;
for (int j = 0;j< iLength -1;j++)
{
if (j > iDotIndex)
{
dNumber += pow(8.0, iDotIndex - j)*(cOperandStr[j]-48);
}else if (j< iDotIndex)
{
dNumber += pow(8.0, iDotIndex -j-1)*(cOperandStr[j]-48);
}
}
return dNumber;
}else if (cNumberType == 'b') /* 二进制,后缀b */
{
iDotIndex = iLength -1;
for (int j = 0 ;j< iLength -1;j++)
{
if (cOperandStr[j] == '.')
{
iDotIndex = j;
}
}
dNumber = 0.0;
for (int j = 0;j< iLength -1;j++)
{
if (j > iDotIndex)
{
dNumber += pow(2.0, iDotIndex - j)*(cOperandStr[j]-48);
}else if (j< iDotIndex)
{
dNumber += pow(2.0, iDotIndex -j-1)*(cOperandStr[j]-48);
}
}
return dNumber;
}else if (cNumberType == 'n') /* 不是数字 */
{
cout<<"invalid number '"<<cOperandStr<<"'"<<endl;
return -1.0;
}
return -1.0;
}
/**
* @ingroup MemberFunction_Poland
* @brief 将字符串格式的操作数转化为数值
* @details 其中操作数可以是十六进制、十进制、八进制、二进制数据
* @param[in] sOperandStr 从数学表达式中提取的操作数的字符串
* @return 返回从字符串中提取的double类型的数值
* @note 使用不同进制时,需要加进制标志,例如十六进制加前缀0x或者后缀h,八进制添加后缀o,二进制添加后缀b,
* 十进制添加后缀d,若没有前缀后缀则默认是十进制数,前缀后缀字母使用大小写均可
* @code
* string sOperandStr = string("ad.ffh)";
* Poland poland;
* double dNumber = Poland.OperandStr2Number(sOperandStr);
* @endcode
*/
double Poland::OperandStr2Number(string sOperandStr){
int iLength = sOperandStr.size();
char * cOperandStr = new char [iLength +1];
double dTempNumber = 0.0;
for (int i = 0;i< iLength;i++)
{
cOperandStr[i] = sOperandStr.at(i);
}
cOperandStr[iLength] = '\0';
dTempNumber = this->OperandStr2Number(cOperandStr);
delete [] cOperandStr;
return dTempNumber;
}
/**
* @ingroup MemberFunction_Poland
* @brief 变量搜索函数
* @param[in] cVariableStr 待搜索的变量名字符串
* @return 返回搜索到的变量名的下标,不存在时则返回-1
* @note
* @code
* @endcode
*/
int Poland::SearchVariable(char *cVariableStr){
for (int i = 0; i< static_cast<int>(VariableVector.size());i++)
{
if (!strcmp(cVariableStr,VariableVector.at(i).cName))
{
return i;
}
}
return -1;
}
/**
* @ingroup MemberFunction_Poland
* @brief 常量搜索函数
* @param[in] cVariableStr 待搜索的常量量名字符串
* @return 返回搜索到的常量量名的下标,不存在时则返回-1
* @note
* @code
* @endcode
*/
int Poland::SearchConstVariable(char * cVariableStr){
for (int i =0 ;i< CONSTVARIABLEMOST;i++)
{
if (!strcmp(cVariableStr,VariableDic[i].cName))
{
return i;
}
}
return -1;
}
/**
* @ingroup MemberFunction_Poland
* @brief 打印被拆分成变量、函数、运算符等基本元素之后的表达式,用于查看
* 成员函数BreakExpress()的结果
*
* @code
* Poland poland;
* Poland.PrintBreakedExpress();
* @endcode
*/
void Poland::PrintBreakedExpress(){
cout<<"Infix Expression: "<<endl;
this->PrintExpress(this->IndexVector,this->KindTypeVector);
}
/**
* @ingroup MemberFunction_Poland
* @brief 从字符串中提取操作数
* @details 操作数可以是变量或者数字,字符串前后可以有空格
* @param[in] cExpress 字符串形式的数学表达式
* @param[in] LeftIndex 操作数字串在cExpress中的开始下标
* @param[in] RightIndex 操作数字串在cExpress中的结束下标
* @return 返回操作数的类型
* @code
* @endcode
*/
KindType Poland::AbstractOperand(char * cExpress, int LeftIndex,int RightIndex){
int iLeftSpace = LeftIndex - 1;
int iRightSpace = RightIndex + 1;
/*
* 操作符两端可能有空格,将操作数两端的空格剔除
*/
for (int i = LeftIndex ;i<= RightIndex ;i++)
{
if (cExpress[i] != ' ')
{
break;
}
iLeftSpace = i;
}
for (int i = RightIndex ;i>= LeftIndex ;i--)
{
if (cExpress[i] != ' ')
{
break;
}
iRightSpace = i;
}
int iLength = iRightSpace - iLeftSpace -1;
/*
* 操作数长度不超过308可以使用double类型表示,否则换用BigDouble来表示
*/
if (iLength > 0 && iLength <= 308)
{
char *cOperandStr = new char[iLength+1];
this->my_strnmcpy(cOperandStr,cExpress,iLeftSpace+1,iRightSpace-1);
/*for (int i = iLeftSpace + 1 ; i<= iRightSpace-1 ;i++)
{
cOperandStr[i -iLeftSpace -1] = cExpress[i];
}
cOperandStr[iLength] = '\0';*/
/*
* 变量名合格检测,要求和c的变量名规范相同,数字、下划线、字母,首字符不能使数字
*/
if(this->IsValidVariableName(cOperandStr)){
int iIndex = -1;
iIndex = this->SearchConstVariable(cOperandStr);
/*
* 若是常量,存储类型和下标即可
*/
if (iIndex>= 0 && iIndex < CONSTVARIABLEMOST)
{
IndexVector.push_back(iIndex);
KindTypeVector.push_back(ConstVariable);
return ConstVariable;
}else{
iIndex = this->SearchVariable(cOperandStr);
/*
* 自定义变量,并记下下标和类型
*/
if (iIndex >= 0 && iIndex < static_cast<int>(VariableVector.size()))
{
IndexVector.push_back(iIndex);
KindTypeVector.push_back(VariableVector.at(iIndex).kind);
return VariableVector.at(iIndex).kind;
}else{
/*
* 未定义变量,存储变量到VariableVector中,并记下下标和类型,
* 使用时只允许出现在等号的左侧,并且对变量名长度有限制,32个字符以内
*/
if (strlen(cOperandStr) <= 32)
{
Variable VariableTemp;
strcpy(VariableTemp.cName,cOperandStr);
VariableTemp.kind = Undefine;
VariableTemp.dNumber = 0.0;
VariableTemp.bdNumber = BigDouble(0.0);
IndexVector.push_back(VariableVector.size());
KindTypeVector.push_back(Undefine);
VariableVector.push_back(VariableTemp);
return Undefine;
}else{
cout<<"Variable name must be less than 32 Byte"<<endl;
/*
* TODO: 添加对变量超长时的错误处理
*/
}
}
}
}else if (this->NumberTypeCheck(cOperandStr) != 'n')
{
/*
* 操作数不是变量,而是数字,将数字解析成double并存储到DoubleVector,记下下标和类型
*/
double dOperand = this->OperandStr2Number(cOperandStr);
IndexVector.push_back(DoubleVector.size());
KindTypeVector.push_back(OperandDouble);
DoubleVector.push_back(dOperand);
delete [] cOperandStr;
return OperandDouble;
}
else{
delete [] cOperandStr;
cout<<"Invalid Variable or Function '"<<cOperandStr<<"'"<<endl;
}
}else if (iLength > 308)
{
/*
* 若操作数长度超过308,有可能是BigDouble大数值,提取大数值,并存储
*/
char *cOperandStr = new char[iLength+1];
this->my_strnmcpy(cOperandStr,cExpress,iLeftSpace+1,iRightSpace-1);
if (isdigit(cOperandStr[0]) || cOperandStr[0] == '.')
{
BigDouble BigDoubleTemp = BigDouble(cOperandStr);
IndexVector.push_back(BigDoubleVector.size());
KindTypeVector.push_back(OperandBigDouble);
BigDoubleVector.push_back(BigDoubleTemp);
delete [] cOperandStr;
return OperandBigDouble;
}else{
delete [] cOperandStr;
cout<<"Undefine Variable or Function '"<<cOperandStr<<"'"<<endl;
return Undefine;
}
}else {
}
return Undefine;
}
/**
* @ingroup MemberFunction_Poland
* @brief 数值进制检测函数
* @param[in] cOperandStr 从数学表达式中提取的字符串形式的数值
* @retval n 不是数值
* @retval h 十六进制 0x前缀
* @retval H 十六进制 h后缀
* @retval d 十进制 无前缀或后缀
* @retval D 十进制 d后缀
* @retval o 八进制 o后缀
* @retval b 二进制 b后缀
* @note 前缀或者缀写作大写小写均支持
* @code
* char cOperandStr[] = "ad.ffh";
* Poland poland;
* char NumberType = Poland.NumberTypeCheck(cOperandStr);
* @endcode
*/
char Poland::NumberTypeCheck(char * cOperandStr){
int iLength = strlen(cOperandStr);
int iDotCount = 0;
/*
* 进制判别
*/
if((cOperandStr[0] == '0' && tolower(cOperandStr[1]) == 'x') ){
for (int i = 2; i< iLength ;i++)
{