找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 3770|回复: 5

数学表达式解析器-(一)初期体验

[复制链接]
发表于 2014-3-7 13:59:02 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
学了堆栈以后,书上说可以用后缀表达式计算复杂数学表达式,因此想试试,既然开始探索,自然难度不能太低。这次选择表达式支持这些:
目的是可以计算sin(tan(x)*x)这种复杂表达式,给定定义域并画出图形
考虑到重用,因此先生成后缀表达式,因为后缀表达式是随着输入表达式固定的,而计算的时候只需要把x换成相应的值即可。
下面这些代码还处于理论阶段,因此现在称为初期体验,相信做出来以后还是蛮有用的

  1. enum type
  2. {
  3.         //LEVEL0        0 1 2 3 4 5 6 7 8 9 . PI E
  4.         LEVEL0,
  5.         TYPE_INVALID=LEVEL0,//无效数
  6.         TYPE_UNKNOWN,                //未知数
  7.         TYPE_INTEGER,                //整数
  8.         TYPE_DECIMAL,                //小数

  9.         //LEVEL1        ()+() ()-()
  10.         LEVEL1,
  11.         TYPE_ADD=LEVEL1,        //和
  12.         TYPE_SUB,                        //差

  13.         //LEVEL2                        ()*() ()/()
  14.         LEVEL2,
  15.         TYPE_MUL=LEVEL2,        //积
  16.         TYPE_DIV,                        //商

  17.         //LEVEL3                        ()^()
  18.         LEVEL3,
  19.         TYPE_POW=LEVEL3,        //乘方

  20.         //LEVEL4                        MOD() SIN() COS() TAN() ASIN() ACOS() ATAN() SINH() COSH() TANH() SQRT() LN() LOG10() EXP() CEIL() FLOOR() SGN()
  21.         //                                        () [] {} ||  
  22.         //                                        ()!   (-())取反
  23.         LEVEL4,
  24.         //括号模式
  25.         TYPE_MOD=LEVEL4,//取模
  26.         TYPE_SIN,                //正弦
  27.         TYPE_COS,                //余弦
  28.         TYPE_TAN,                //正切
  29.         TYPE_ASIN,                //反正弦
  30.         TYPE_ACOS,                //反余弦
  31.         TYPE_ATAN,                //反正切
  32.         TYPE_SINH,                //双曲正弦
  33.         TYPE_COSH,                //双曲余弦
  34.         TYPE_TANH,                //双曲正切
  35.         TYPE_SQRT,                //开平方
  36.         TYPE_LN,                //自然对数
  37.         TYPE_LOG10,                //以10为底的对数
  38.         TYPE_EXP,                //自然指数
  39.         TYPE_CEIL,                //向上取整
  40.         TYPE_FLOOR,                //向下取整
  41.         TYPE_SGN,                //符号函数
  42.         TYPE_BRACKET,        //括号

  43.         TYPE_ABS,                //绝对值
  44.         TYPE_FACTORIAL,        //阶乘
  45.         TYPE_NEG,                //取反

  46.         LEVEL5,
  47. };
复制代码



现在仅写了如下代码,还在完善

  1. struct numberstackdata
  2. {
  3.         type type;
  4.         union
  5.         {
  6.                 int                integer;//TYPE_INTEGER
  7.                 double        decimal;//TYPE_DECIMAL
  8.         }data;
  9. };

  10. struct point
  11. {
  12.         int x;
  13.         int y;
  14. };

  15. list<point> globalPTs;

  16. int resolvenum(char* pos,double& data)
  17. {//由字符串解析出小数
  18.         bool negative=false;
  19.         char* origin=pos;
  20.         if(*pos == '-' || * pos == '+')
  21.         {
  22.                 pos++;
  23.                 if(*pos == '-')
  24.                         negative=true;
  25.         }
  26.         int integer=0;
  27.         double decimal=0;
  28.         while(*pos >= '0' && *pos <= '9')
  29.         {
  30.                 integer=integer*10 + *pos - '0';
  31.                 pos++;
  32.         }
  33.         if(*pos == '.')
  34.         {
  35.                 pos++;
  36.                 while(*pos >= '0' && *pos <= '9')
  37.                 {
  38.                         decimal=decimal*10 + *pos - '0';
  39.                         pos++;
  40.                 }
  41.         }
  42.         while(decimal >= 1.0)
  43.         {
  44.                 decimal /= 10;
  45.         }

  46.         data=integer+decimal;
  47.         if(pos-origin > 1)
  48.                 return pos-origin;
  49.         else
  50.                 return 1;
  51. }


  52. bool compare(char A,char B)
  53. {//优先级A<=B true     A>B false
  54.         switch(A)
  55.         {
  56.                 case '+':
  57.                 case '-':
  58.                         switch(B)
  59.                         {
  60.                                 case '+':
  61.                                 case '-':
  62.                                         return true;
  63.                                 case '*':
  64.                                 case '/':
  65.                                         return true;
  66.                         }
  67.                 case '*':
  68.                 case '/':
  69.                         switch(B)
  70.                         {
  71.                                 case '+':
  72.                                 case '-':
  73.                                         return false;
  74.                                 case '*':
  75.                                 case '/':
  76.                                         return true;
  77.                         }
  78.                 case '(':
  79.                         return true;
  80.         }
  81. }
  82. //MOD()    SIN()    COS()    TAN()    ACOS()    ASIN()    ATAN()    COSH()    SINH()    TANH()    SQRT()   
  83. //()^()             ()!        LN()      EXP()     ()+()            ()-()           ()*()           ()/()        {}[]().    PI    E       |()| (-())
  84. void main()
  85. {//由普通表达式生成后缀表达式
  86.         stack<char> sigstack;
  87.         list<string> output;
  88.         char str[]="9+(3-1)*3+10/2";//9 3 1 - 3 * + 10 2 / +
  89.        
  90.         int pos1=0,pos2=0;
  91.         while(pos1<sizeof(str)-1)
  92.         {
  93.                 if(str[pos1] >= '0' && str[pos1] <= '9')
  94.                 {
  95.                         int endp=pos1;
  96.                         while(str[endp] >= '0' && str[endp] <= '9')
  97.                         {
  98.                                 endp++;
  99.                         }
  100.                         if(str[endp] == '.')
  101.                         {
  102.                                 endp++;
  103.                                 while(str[endp] >= '0' && str[endp] <= '9')
  104.                                 {
  105.                                         endp++;
  106.                                 }
  107.                         }
  108.                         string temp;
  109.                         temp.append(str+pos1,endp-pos1);
  110.                         output.push_back(temp);
  111.                         pos1=endp;
  112.                 }
  113.                 else if(str[pos1] == '+' || str[pos1] == '-' || str[pos1] == '*' || str[pos1] == '/')
  114.                 {
  115.                         if(sigstack.empty())
  116.                         {
  117.                                 sigstack.push(str[pos1]);
  118.                         }
  119.                         else
  120.                         {
  121.                                 if(!compare(sigstack.top(),str[pos1]))//若优先级A<B 则push
  122.                                 {
  123.                                         while(!sigstack.empty() && !compare(sigstack.top(),str[pos1]))
  124.                                         {
  125.                                                 output.push_back(string(1,sigstack.top()));
  126.                                                 sigstack.pop();
  127.                                         }
  128.                                         output.push_back(string(1,str[pos1]));
  129.                                 }
  130.                                 else
  131.                                 {
  132.                                         sigstack.push(str[pos1]);
  133.                                 }
  134.                         }
  135.                         pos1++;
  136.                 }
  137.                 else if(str[pos1] == '(' || str[pos1] == ')')
  138.                 {
  139.                         if(str[pos1] == '(')
  140.                         {
  141.                                 sigstack.push('(');
  142.                         }
  143.                         else
  144.                         {
  145.                                 while(sigstack.top() != '(')
  146.                                 {
  147.                                         output.push_back(string(1,sigstack.top()));
  148.                                         sigstack.pop();
  149.                                 }
  150.                                 sigstack.pop();
  151.                         }
  152.                         pos1++;
  153.                 }
  154.         }
  155. }


  156. int func(list<string>& str)//由后缀表达式计算结果
  157. {
  158.         stack<double> numstack;
  159. //        char str[]="9 3.1 1.2 - 3.3 * + 10.4 2.5 / +";
  160.         int len=str.size();
  161.         for(int pos=0;pos<len;)
  162.         {
  163.                 if(str[pos] >= '0' && str[pos] <= '9')
  164.                 {
  165.                         double data=0;
  166.                         pos += resolvenum(str+pos,data);
  167.                         numstack.push(data);
  168.                 }
  169.                 else if(str[pos] == '+' || str[pos] == '-' || str[pos] == '*' || str[pos]== '/')
  170.                 {
  171.                         double num=numstack.top();
  172.                         numstack.pop();
  173.                         if(str[pos] == '+')
  174.                                 numstack.top() += num;
  175.                         else if(str[pos] == '-')
  176.                                 numstack.top() -= num;
  177.                         else if(str[pos] == '*')
  178.                                 numstack.top() *= num;
  179.                         else
  180.                                 numstack.top() /= num;
  181.                         pos++;
  182.                 }
  183.                 else
  184.                         pos++;
  185.         }
  186.         cout<<numstack.top()<<endl;
  187. }

复制代码

回复

使用道具 举报

发表于 2014-11-18 22:43:08 | 显示全部楼层
基于栈的表达式计算,弄了好几个月,现在分享一下
  1. /*
  2. Calculation Engine Kernel v1.0[Static Edition]
  3. Created By CYY 20140201
  4. Copyright (C) 2014 Ctechnology Corporation
  5. All Rights Resaved.
  6. [email]cyycoish@hotmail.com[/email]
  7. 201402042139
  8. 201402241352
  9. 201403061734--func
  10. 201403140144--x1
  11. 201403202105--no add end
  12. 201404091752SAT--ALL END
  13. 注意:AddConstants必须在AddFunc前使用
  14. */
  15. //包含部分
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. //#include <Windows.h>
  20. #include <math.h>
  21. #include <time.h>
  22. //#include <iostream>
  23. //宏定义部分
  24. #define N 4096//输入总长
  25. #define M 1024//输入总长
  26. #define S_NUM_MAX 4096//单个数字大小
  27. #define S_OPR_MAX 4096//单个运算符大小
  28. #define OFUN_NUM  63  //运算符数量
  29. #define CST_CTR   5   //常数个数

  30. #define FUN_MAX   1024//运算符数量
  31. #define PAR_MAX   1024//函数参数数量
  32. #define UFN_MAX   1024//自定义函数数量

  33. #define MPI 3.1415926535897932384626433832795028841971693993751058
  34. #define MEE 2.7182818284590452353602874713526624977572470936999595
  35. //#define SFUN_NUM  10//自定义运算符数量
  36. //声明部分
  37. double CALC_main(char *exp);
  38. char *InputScanner(char *exp);
  39. void Debug_Print_Para(void);
  40. //
  41. int intFunParCount = 0;//函数参数个数
  42. double Answ = 0;//保存前一个运算结果
  43. double pa[M] = { 0 };//函数参数
  44. int ix = 0;//位置标记

  45. int iUserFun = 0;//自定义函数数量
  46. int iParCtr = 0;//函数参数数量
  47. int iUserCnt = 0;//自定义常量数量

  48. enum DEGSCALE{//角度度量
  49.         S_Rad,//弧度制
  50.         S_Deg,//角度制
  51.         S_Gra //梯度制
  52. };
  53. DEGSCALE degScale = S_Rad;//角度度量默认弧度
  54. //错误代码
  55. int ERR_NUM = 0;
  56. enum ERRORNUM{
  57.         NoError,
  58.         MathError,
  59.         StackError,
  60.         SyntaxError,
  61.         UnknownError,
  62. };
  63. typedef struct{
  64.         ERRORNUM num;
  65.         int pos;
  66. }ERRSTRU;
  67. ERRSTRU Error(ERRORNUM E){
  68.         ERRSTRU ERRNUMr;
  69.         ERRNUMr.num = E;
  70.         ERRNUMr.pos = ix;
  71.         return ERRNUMr;
  72. }
  73. //常数
  74. typedef struct{
  75.         char *name;
  76.         double value;
  77.         int number;
  78. }CONSTANT;
  79. //运算符结合性
  80. enum OPRCAL{
  81.         DoubleCalOpr,//双目运算符
  82.         FrontCalOpr, //前缀运算符
  83.         RearCalOpr,  //后缀运算符
  84.         IsBracket,   //是括号
  85.         Specific,    //特殊 ,
  86.         Functio,     //函数
  87.         UserFun,     //自定义函数
  88.         //VarCon       //变量/常数
  89. };
  90. //运算符类型
  91. typedef struct{
  92.         char *name;//运算符名称
  93.         int level;//优先级
  94.         OPRCAL ctype;//运算符结合性
  95.         /*
  96.         ctype取值:
  97.         0:双目运算符
  98.         1.前缀运算符
  99.         2.后缀运算符
  100.         3.括号
  101.         */
  102.         int number;//标识符
  103.         char *expr;//函数表达式
  104.         //double value;
  105. }OTYPE;
  106. //数栈
  107. typedef struct{
  108.         double stack[N];
  109.         int top;
  110. }NumSTACK;
  111. //二级数栈存放函数参数[操作对象函数CALC_fun]
  112. typedef struct{
  113.         double stack[N];
  114.         int top;
  115. }NumSTACK_fun;
  116. //符栈
  117. typedef struct{
  118.         OTYPE stack[M];
  119.         int top;
  120. }OprSTACK;
  121. //初始化数栈
  122. void InitNumSTACK(NumSTACK* s){
  123.         (*s).top = 0;
  124. }
  125. //进数栈
  126. bool NPush(NumSTACK* s, double n)
  127. {
  128.         //如果栈满则报错退出程序
  129.         if ((*s).top == N - 1){
  130.                 Error(StackError);
  131.                 return false;
  132.         }
  133.         (*s).stack[(*s).top] = n;
  134.         (*s).top++;
  135.         return true;
  136. }
  137. //出数栈
  138. double NPop(NumSTACK* s)
  139. {
  140.         //如果栈空则报错退出程序
  141.         if ((*s).top == 0){
  142.                 Error(StackError);
  143.                 return 0;
  144.         }
  145.         else{
  146.                 (*s).top--;
  147.                 return (*s).stack[(*s).top];
  148.         }
  149. }
  150. //初始化符栈
  151. void InitOprSTACK(OprSTACK* s){
  152.         (*s).top = 0;
  153. }
  154. //进符栈
  155. bool OPush(OprSTACK* s, OTYPE* sign)
  156. {
  157.         //如果栈满则报错退出程序
  158.         if ((*s).top == M - 1){
  159.                 Error(SyntaxError);
  160.                 return false;
  161.         }
  162.         (*s).stack[(*s).top] = *sign;
  163.         (*s).top++;
  164.         return true;
  165. }
  166. //出符栈
  167. OTYPE OPop(OprSTACK *s)
  168. {
  169.         //栈空则报错退出程序
  170.         if ((*s).top == 0){
  171.                 Error(SyntaxError);
  172.         }
  173.         else{
  174.                 (*s).top--;
  175.                 //return (*s).stack[M-((*s).top)];
  176.                 return (*s).stack[(*s).top];
  177.         }
  178. }
  179. //运算符表
  180. OTYPE oper[FUN_MAX];
  181. bool InitOperTable(void){
  182.         /*
  183.         oper[0].name="#";     oper[0].level=1;  oper[0].ctype=DoubleCalOpr; oper[0].number=1;
  184.         oper[1].name="NOT";   oper[1].level=2;  oper[1].ctype=FrontCalOpr;  oper[1].number=2;
  185.         oper[2].name="~NOT";  oper[2].level=7;  oper[2].ctype=FrontCalOpr;  oper[2].number=3;
  186.         oper[3].name="^";     oper[3].level=14; oper[3].ctype=DoubleCalOpr; oper[3].number=4;
  187.         oper[4].name="!";     oper[4].level=15; oper[4].ctype=RearCalOpr;   oper[4].number=5;
  188.         oper[5].name="*";     oper[5].level=13; oper[5].ctype=DoubleCalOpr; oper[5].number=6;
  189.         oper[6].name="/";     oper[6].level=13; oper[6].ctype=DoubleCalOpr; oper[6].number=7;
  190.         oper[7].name="MOD";   oper[7].level=13; oper[7].ctype=DoubleCalOpr; oper[7].number=8;
  191.         oper[8].name="AND";   oper[8].level=8;  oper[8].ctype=DoubleCalOpr; oper[8].number=9;
  192.         oper[9].name="~AND";  oper[9].level=3;  oper[9].ctype=DoubleCalOpr; oper[9].number=10;
  193.         oper[10].name="+";    oper[10].level=12;oper[10].ctype=DoubleCalOpr;oper[10].number=11;
  194.         //oper[11].name="-";    oper[11].level=4;oper[11].ctype=DoubleCalOpr;oper[11].number=12;
  195.         oper[11].name="OR";   oper[11].level=9; oper[11].ctype=DoubleCalOpr;oper[11].number=12;
  196.         oper[12].name="~OR";  oper[12].level=4; oper[12].ctype=DoubleCalOpr;oper[12].number=13;
  197.         oper[13].name="XOR";  oper[13].level=10;oper[13].ctype=DoubleCalOpr;oper[13].number=14;
  198.         oper[14].name="~XOR"; oper[14].level=5; oper[14].ctype=DoubleCalOpr;oper[14].number=15;
  199.         oper[15].name="XNOR"; oper[15].level=11;oper[15].ctype=DoubleCalOpr;oper[15].number=16;
  200.         oper[16].name="~XNOR";oper[16].level=6; oper[16].ctype=DoubleCalOpr;oper[16].number=17;
  201.         oper[17].name="=";    oper[17].level=16;oper[17].ctype=DoubleCalOpr;oper[17].number=18;
  202.         oper[18].name=";";    oper[18].level=17;oper[18].ctype=RearCalOpr;  oper[18].number=19;
  203.         oper[19].name="(";    oper[19].level=-1;oper[19].ctype=IsBracket;   oper[19].number=20;
  204.         oper[20].name=")";    oper[20].level=0; oper[20].ctype=IsBracket;   oper[20].number=21;
  205.         oper[21].name=",";    oper[21].level=0; oper[21].ctype=IsBracket;   oper[21].number=22;
  206.         */
  207.         oper[0].name = "NAN";   oper[0].level = 100; oper[0].ctype = Specific;     oper[0].number = -1;
  208.         oper[1].name = "NOT";   oper[1].level = 25;  oper[1].ctype = FrontCalOpr;  oper[1].number = 2;
  209.         oper[2].name = "~NOT";  oper[2].level = 24;  oper[2].ctype = FrontCalOpr;  oper[2].number = 3;
  210.         oper[3].name = "^";     oper[3].level = 14;  oper[3].ctype = DoubleCalOpr; oper[3].number = 4;
  211.         oper[4].name = "!";     oper[4].level = 15;  oper[4].ctype = RearCalOpr;   oper[4].number = 5;
  212.         oper[5].name = "*";     oper[5].level = 13;  oper[5].ctype = DoubleCalOpr; oper[5].number = 6;
  213.         oper[6].name = "/";     oper[6].level = 13;  oper[6].ctype = DoubleCalOpr; oper[6].number = 7;
  214.         oper[7].name = "MOD";   oper[7].level = 13;  oper[7].ctype = DoubleCalOpr; oper[7].number = 8;
  215.         oper[8].name = "AND";   oper[8].level = 23;  oper[8].ctype = DoubleCalOpr; oper[8].number = 9;
  216.         oper[9].name = "~AND";  oper[9].level = 22;  oper[9].ctype = DoubleCalOpr; oper[9].number = 10;
  217.         oper[10].name = "+";    oper[10].level = 12; oper[10].ctype = DoubleCalOpr; oper[10].number = 11;
  218.         oper[11].name = "OR";   oper[11].level = 21; oper[11].ctype = DoubleCalOpr; oper[11].number = 12;
  219.         oper[12].name = "~OR";  oper[12].level = 20; oper[12].ctype = DoubleCalOpr; oper[12].number = 13;
  220.         oper[13].name = "XOR";  oper[13].level = 19; oper[13].ctype = DoubleCalOpr; oper[13].number = 14;
  221.         oper[14].name = "~XOR"; oper[14].level = 18; oper[14].ctype = DoubleCalOpr; oper[14].number = 15;
  222.         oper[15].name = "XNOR"; oper[15].level = 17; oper[15].ctype = DoubleCalOpr; oper[15].number = 16;
  223.         oper[16].name = "~XNOR"; oper[16].level = 16; oper[16].ctype = DoubleCalOpr; oper[16].number = 17;
  224.         oper[17].name = ">>";   oper[17].level = 9;  oper[17].ctype = DoubleCalOpr; oper[17].number = 18;
  225.         oper[18].name = ";";    oper[18].level = 17; oper[18].ctype = RearCalOpr;   oper[18].number = 19;
  226.         oper[19].name = "(";    oper[19].level = -1; oper[19].ctype = IsBracket;    oper[19].number = 20;
  227.         oper[20].name = ")";    oper[20].level = 0;  oper[20].ctype = IsBracket;    oper[20].number = 21;
  228.         oper[21].name = ",";    oper[21].level = 0;  oper[21].ctype = IsBracket;    oper[21].number = 22;

  229.         oper[22].name = "ADD";  oper[22].level = 99; oper[22].ctype = Functio;      oper[22].number = 23;
  230.         oper[23].name = "SIN";  oper[23].level = 99; oper[23].ctype = FrontCalOpr;  oper[23].number = 24;
  231.         oper[24].name = "%";    oper[24].level = 26; oper[24].ctype = RearCalOpr;   oper[24].number = 1;
  232.         oper[25].name = "COS";  oper[25].level = 99; oper[25].ctype = FrontCalOpr;  oper[25].number = 25;
  233.         oper[26].name = "TAN";  oper[26].level = 99; oper[26].ctype = FrontCalOpr;  oper[26].number = 26;

  234.         oper[27].name = "~>";   oper[27].level = 11; oper[27].ctype = DoubleCalOpr; oper[27].number = 27;
  235.         oper[28].name = "~<";   oper[28].level = 11; oper[28].ctype = DoubleCalOpr; oper[28].number = 28;
  236.         oper[29].name = ">=";   oper[29].level = 11; oper[29].ctype = DoubleCalOpr; oper[29].number = 27;
  237.         oper[30].name = "<=";   oper[30].level = 11; oper[30].ctype = DoubleCalOpr; oper[30].number = 30;
  238.         oper[31].name = "==";   oper[31].level = 10; oper[31].ctype = DoubleCalOpr; oper[31].number = 31;
  239.         oper[32].name = "<>";   oper[32].level = 10; oper[32].ctype = DoubleCalOpr; oper[32].number = 32;

  240.         oper[33].name = "ARCSIN";  oper[33].level = 99; oper[33].ctype = FrontCalOpr;  oper[33].number = 33;
  241.         oper[34].name = "ARCCOS";  oper[34].level = 99; oper[34].ctype = FrontCalOpr;  oper[34].number = 34;
  242.         oper[35].name = "ARCTAN";  oper[35].level = 99; oper[35].ctype = FrontCalOpr;  oper[35].number = 35;
  243.         oper[36].name = "ABS";     oper[36].level = 99; oper[36].ctype = FrontCalOpr;  oper[36].number = 36;

  244.         oper[37].name = "SINH";    oper[37].level = 99; oper[37].ctype = FrontCalOpr;  oper[37].number = 37;
  245.         oper[38].name = "COSH";    oper[38].level = 99; oper[38].ctype = FrontCalOpr;  oper[38].number = 38;
  246.         oper[39].name = "TANH";    oper[39].level = 99; oper[39].ctype = FrontCalOpr;  oper[39].number = 39;

  247.         oper[40].name = "ARCSINH"; oper[40].level = 99; oper[40].ctype = FrontCalOpr;  oper[40].number = 40;
  248.         oper[41].name = "ARCCOSH"; oper[41].level = 99; oper[41].ctype = FrontCalOpr;  oper[41].number = 41;
  249.         oper[42].name = "ARCTANH"; oper[42].level = 99; oper[42].ctype = FrontCalOpr;  oper[42].number = 42;

  250.         oper[43].name = "LG";      oper[43].level = 99; oper[43].ctype = FrontCalOpr;  oper[43].number = 43;
  251.         oper[44].name = "LN";      oper[44].level = 99; oper[44].ctype = FrontCalOpr;  oper[44].number = 44;
  252.         oper[45].name = "LOG";     oper[45].level = 99; oper[45].ctype = Functio;      oper[45].number = 45;
  253.         oper[46].name = "SGN";     oper[46].level = 99; oper[46].ctype = FrontCalOpr;  oper[46].number = 46;

  254.         oper[47].name = "SQR";     oper[47].level = 99; oper[47].ctype = FrontCalOpr;  oper[47].number = 47;
  255.         oper[48].name = "INT";     oper[48].level = 99; oper[48].ctype = FrontCalOpr;  oper[48].number = 48;

  256.         oper[49].name = "SEC";     oper[49].level = 99; oper[49].ctype = FrontCalOpr;  oper[49].number = 49;
  257.         oper[50].name = "CSC";     oper[50].level = 99; oper[50].ctype = FrontCalOpr;  oper[50].number = 50;
  258.         oper[51].name = "COT";     oper[51].level = 99; oper[51].ctype = FrontCalOpr;  oper[51].number = 51;
  259.         oper[52].name = "ARCSEC";  oper[52].level = 99; oper[52].ctype = FrontCalOpr;  oper[52].number = 52;
  260.         oper[53].name = "ARCCSC";  oper[53].level = 99; oper[53].ctype = FrontCalOpr;  oper[53].number = 53;
  261.         oper[54].name = "ARCCOT";  oper[54].level = 99; oper[54].ctype = FrontCalOpr;  oper[54].number = 54;
  262.         oper[55].name = "SECH";    oper[55].level = 99; oper[55].ctype = FrontCalOpr;  oper[55].number = 55;
  263.         oper[56].name = "CSCH";    oper[56].level = 99; oper[56].ctype = FrontCalOpr;  oper[56].number = 56;
  264.         oper[57].name = "COTH";    oper[57].level = 99; oper[57].ctype = FrontCalOpr;  oper[57].number = 57;
  265.         oper[58].name = "ARCSECH"; oper[58].level = 99; oper[58].ctype = FrontCalOpr;  oper[58].number = 58;
  266.         oper[59].name = "ARCCSCH"; oper[59].level = 99; oper[59].ctype = FrontCalOpr;  oper[59].number = 59;
  267.         oper[60].name = "ARCCOTH"; oper[60].level = 99; oper[60].ctype = FrontCalOpr;  oper[60].number = 60;
  268.         oper[61].name = "ROOT";    oper[61].level = 99; oper[61].ctype = Functio;      oper[61].number = 61;

  269.         oper[62].name = "AVG";     oper[62].level = 99; oper[62].ctype = Functio;      oper[62].number = 62;
  270.         oper[63].name = "INT";     oper[63].level = 99; oper[63].ctype = FrontCalOpr;  oper[63].number = 63;
  271.         //oper[25].name = "PI";   oper[25].level = 100; oper[25].ctype = VarCon;     oper[25].number = 25; oper[25].value = 3.14;
  272.         return true;
  273. }
  274. //常数表
  275. CONSTANT constants[CST_CTR];//常数变量
  276. CONSTANT functpara[PAR_MAX];//函数参数
  277. void InitParaTable(void){
  278.         register int i = 0;
  279.         for (i = 0; i < PAR_MAX; i++){
  280.                 functpara[i].name = "";
  281.                 functpara[i].number = 0;
  282.                 functpara[i].value = 0;
  283.         }
  284. }
  285. bool InitConstTable(void){
  286.         constants[0].name = "NULL"; constants[0].value = 0;   constants[0].number = 1;
  287.         constants[1].name = "PI";   constants[1].value = MPI; constants[1].number = 2;
  288.         constants[2].name = "E";    constants[2].value = MEE; constants[2].number = 3;
  289.         constants[3].name = "ANS";  constants[3].value = 0;   constants[3].number = 4;
  290.         constants[4].name = "RND";  constants[4].value = 0;   constants[4].number = 5;
  291.         return true;
  292. }
  293. /////////////////
  294. double Sgn(double x){
  295.         if (x > 0)
  296.                 return 1.0;
  297.         else if (x == 0)
  298.                 return 0.0;
  299.         else
  300.                 return -1.0;
  301. }
  302. //运算符运算过程表
  303. double DOprCal(double b, double a, int number){//双目运算符运算
  304.         switch (number){
  305.         case 4://^
  306.                 //printf("%s\n","hello^");////////////////////
  307.                 return powf(a, b);
  308.         case 6://*
  309.                 //printf("%s\n","hello*");////////////////////
  310.                 return a*b;
  311.         case 7:///
  312.                 if (b != 0)
  313.                         return a / b;
  314.                 else{
  315.                         Error(MathError);
  316.                         return 0;
  317.                 }
  318.         case 8://MOD
  319.                 return (int)a % (int)b;
  320.         case 9://AND
  321.                 return a&&b;
  322.         case 10://~AND
  323.                 return (int)a&(int)b;
  324.         case 11://+
  325.                 //printf("%s\n","hello+");////////////////////
  326.                 return a + b;
  327.                 //case 12://-
  328.                 //return a-b;
  329.         case 12://OR
  330.                 //printf("%s\n","hello or");////////////////////
  331.                 return a || b;
  332.         case 13://~OR
  333.                 return (int)a | (int)b;
  334.         case 14://XOR
  335.                 if (a == b)
  336.                         return 0;
  337.                 else
  338.                         return 1;
  339.         case 15://~XOR
  340.                 return (int)a ^ (int)b;
  341.         case 16://XNOR
  342.                 if (a == b)
  343.                         return 1;
  344.                 else
  345.                         return 0;
  346.         case 17://~XNOR
  347.                 return ~((int)a ^ (int)b);
  348.         case 18://=
  349.                 if (a == b)
  350.                         return 1;
  351.                 else
  352.                         return 0;
  353.         case 27:
  354.                 if (a > b)
  355.                         return 1;
  356.                 else
  357.                         return 0;
  358.         case 28:
  359.                 if (a < b)
  360.                         return 1;
  361.                 else
  362.                         return 0;
  363.         case 29:
  364.                 if (a >= b)
  365.                         return 1;
  366.                 else
  367.                         return 0;
  368.         case 30:
  369.                 if (a <= b)
  370.                         return 1;
  371.                 else
  372.                         return 0;
  373.         case 31:
  374.                 if (a == b)
  375.                         return 1;
  376.                 else
  377.                         return 0;
  378.         case 32:
  379.                 if (a != b)
  380.                         return 1;
  381.                 else
  382.                         return 0;
  383.         }
  384. }
  385. double FOprCal(int number, double a = 0){//单目前缀运算符运算
  386.         int j = 0; double x = 0; char tStr[N] = { '\0' };
  387.         //printf("入FO的数字代码:%s\n",number);/////////////////////////
  388.         switch (number){
  389.         case 2://NOT
  390.                 if (a != 0)
  391.                         return 0;
  392.                 else
  393.                         return 1;
  394.         case 3://~NOT
  395.                 return ~((int)a);
  396.         case 23://add
  397.                 for (j = 0; j <= intFunParCount; j++)
  398.                         x += pa[j];
  399.                 return x;
  400.         case 24://sin
  401.                 switch (degScale){
  402.                 case S_Rad:
  403.                         return sin(a);
  404.                 case S_Deg:
  405.                         return sin(MPI / 180 * a);
  406.                 case S_Gra:
  407.                         return sin(MPI / 200 * a);
  408.                 }
  409.         case 25://cos
  410.                 switch (degScale){
  411.                 case S_Rad:
  412.                         return cos(a);
  413.                 case S_Deg:
  414.                         return cos(MPI / 180 * a);
  415.                 case S_Gra:
  416.                         return cos(MPI / 200 * a);
  417.                 }
  418.         case 26:
  419.                 switch (degScale){
  420.                 case S_Rad:
  421.                         return tan(a);
  422.                 case S_Deg:
  423.                         return tan(MPI / 180 * a);
  424.                 case S_Gra:
  425.                         return tan(MPI / 200 * a);
  426.                 }
  427.         case 33:
  428.                 x = asin(a);
  429.                 switch (degScale){
  430.                 case S_Rad:
  431.                         return x;
  432.                 case S_Deg:
  433.                         return MPI / 180 * x;
  434.                 case S_Gra:
  435.                         return MPI / 200 * x;
  436.                 }
  437.         case 34:
  438.                 x = acos(a);
  439.                 switch (degScale){
  440.                 case S_Rad:
  441.                         return x;
  442.                 case S_Deg:
  443.                         return MPI / 180 * x;
  444.                 case S_Gra:
  445.                         return MPI / 200 * x;
  446.                 }
  447.         case 35:
  448.                 x = atan(a);
  449.                 switch (degScale){
  450.                 case S_Rad:
  451.                         return x;
  452.                 case S_Deg:
  453.                         return MPI / 180 * x;
  454.                 case S_Gra:
  455.                         return MPI / 200 * x;
  456.                 }
  457.         case 36:
  458.                 return fabs(a);
  459.         case 37://sinh
  460.                 return (exp(a) - exp(-a)) / 2;
  461.         case 38://cosh
  462.                 return (exp(a) + exp(-a)) / 2;
  463.         case 39://tanh
  464.                 return  (exp(a) - exp(-a)) / (exp(a) + exp(-a));
  465.         case 40://arcsinh
  466.                 return log(a + sqrt(a * a + 1));
  467.         case 41://arccosh
  468.                 return log(a + sqrt(a * a - 1));
  469.         case 42://arctanh
  470.                 return log((1 + a) / (1 - a)) / 2;
  471.         case 43://lg
  472.                 return log(a) / log(10.0);
  473.         case 44://ln
  474.                 return log(a) / log(MEE);
  475.         case 45://log
  476.                 return log(pa[0]) / log(pa[1]);
  477.         case 46://sgn
  478.                 return Sgn(a);
  479.         case 47://sqr
  480.                 return sqrt(a);
  481.         case 48://int
  482.                 return (double)int(a);
  483.         case 49://sec
  484.                 if (a == 0)
  485.                         return 1.0;
  486.                 else
  487.                         x = 1 / cos(a);
  488.                 switch (degScale){
  489.                 case S_Rad:
  490.                         return x;
  491.                 case S_Deg:
  492.                         return MPI / 180 * x;
  493.                 case S_Gra:
  494.                         return MPI / 200 * x;
  495.                 }
  496.         case 50://csc
  497.                 x = 1 / sin(a);
  498.                 switch (degScale){
  499.                 case S_Rad:
  500.                         return x;
  501.                 case S_Deg:
  502.                         return MPI / 180 * x;
  503.                 case S_Gra:
  504.                         return MPI / 200 * x;
  505.                 }
  506.         case 51://cot
  507.                 x = 1 / tan(a);
  508.                 switch (degScale){
  509.                 case S_Rad:
  510.                         return x;
  511.                 case S_Deg:
  512.                         return MPI / 180 * x;
  513.                 case S_Gra:
  514.                         return MPI / 200 * x;
  515.                 }
  516.         case 52://arc sec
  517.                 if (a == 1)
  518.                         return 0.0;
  519.                 else
  520.                         x = atan(a / sqrt(a * a - 1)) + Sgn((a)-1) * (2 * atan(1.0));
  521.                 switch (degScale){
  522.                 case S_Rad:
  523.                         return x;
  524.                 case S_Deg:
  525.                         return MPI / 180 * x;
  526.                 case S_Gra:
  527.                         return MPI / 200 * x;
  528.                 }
  529.         case 53://arc csc
  530.                 x = atan(a / sqrt(a * a - 1)) + (Sgn(a) - 1) * (2 * atan(1.0));
  531.                 switch (degScale){
  532.                 case S_Rad:
  533.                         return x;
  534.                 case S_Deg:
  535.                         return MPI / 180 * x;
  536.                 case S_Gra:
  537.                         return MPI / 200 * x;
  538.                 }
  539.         case 54://arc cot
  540.                 x = atan(a) + 2 * atan(1.0);
  541.                 switch (degScale){
  542.                 case S_Rad:
  543.                         return x;
  544.                 case S_Deg:
  545.                         return MPI / 180 * x;
  546.                 case S_Gra:
  547.                         return MPI / 200 * x;
  548.                 }
  549.         case 55://sech
  550.                 if (a == 0)
  551.                         return 1;
  552.                 else
  553.                         x = 2 / (exp(a) + exp(-a));
  554.         case 56://scsh
  555.                 x = 2 / (exp(a) - exp(-a));
  556.         case 57://coth
  557.                 x = (exp(a) + exp(-a)) / (exp(a) - exp(-a));
  558.         case 58://arc sech
  559.                 x = log((sqrt(-a * a + 1) + 1) / a);
  560.         case 59://arc scsh
  561.                 x = log((Sgn(a) * sqrt(a * a + 1) + 1) / a);
  562.         case 60://arc coth
  563.                 x = log((a + 1) / (a - 1)) / 2;
  564.         case 61:
  565.                 return powf(pa[0], 1 / pa[1]);
  566.         case 62:
  567.                 for (j = 0; j <= intFunParCount; j++)
  568.                         x += pa[j];
  569.                 return x / (intFunParCount + 1);
  570.         case 63:
  571.                 return (double)int(a);
  572.         default:
  573.                 //Debug_Print_Para();
  574.                 //double xxxz = 0;
  575.                 //char *cah;
  576.                 strcpy(tStr, InputScanner(oper[number].expr));
  577.                 //printf("\tA1st::\'%s\'\n", tStr);/////////////////////////////////////////InputScanner(oper[number].expr)
  578.                 return CALC_main(tStr);
  579.         }
  580. }
  581. double ROprCal(double a, int number){//单目后缀运算符运算
  582.         int k;
  583.         double r = 1.0;
  584.         switch (number){
  585.         case 1:
  586.                 return (a / 100);
  587.                 //printf("hello");
  588.         case 5://!

  589.                 for (k = 1; k <= (int)a; k++)
  590.                         r = r*(double)k;
  591.                 return r;
  592.         case 19://;
  593.                 ;
  594.         }
  595. }
  596. //查找运算符
  597. int IsOper(char *s){
  598.         register int i = 0;
  599.         //printf("iUserFun:%d\n", iUserFun);////////////////////
  600.         for (i = 0; i <= (OFUN_NUM + iUserFun); i++){
  601.                 //printf("比较前:%s\n", oper[i].name);
  602.                 //if (i == 63) printf("hello\n");//////////////////////////////////
  603.                 if ((s[0] != '\0') && (strcmp(s, oper[i].name) == 0)){
  604.                         //printf("找到的:%d\n",i);/////////////////////////////////////////
  605.                         return i;
  606.                 }
  607.         }
  608.         //printf("LAST:%d\n", i);/////////////////////////////////////////
  609.         return 0;
  610. }
  611. //查找函数参数变量
  612. int IsPara(char *s){
  613.         register int i = 1;
  614.         for (i = 1; i <= iParCtr; i++){
  615.                 if ((s[0] != '\0'))
  616.                         if ((strcmp(s, functpara[i].name) == 0))
  617.                                 return i;
  618.         }
  619.         return 0;
  620. }
  621. //查找常数
  622. int IsConst(char *s){
  623.         register int i = 1;
  624.         for (i = 1; i < CST_CTR + iUserCnt; i++){
  625.                 if ((s[0] != '\0') && (strcmp(s, constants[i].name) == 0)){
  626.                         return i;
  627.                 }
  628.         }
  629.         return 0;
  630. }
  631. //符栈看栈顶
  632. OTYPE OPeek(OprSTACK *s){
  633.         OTYPE r;
  634.         if ((*s).top == 0){//判栈空,空则赋等级0值
  635.                 r.level = 0;
  636.                 return r;
  637.         }
  638.         else
  639.                 return(*s).stack[(*s).top - 1];
  640. }
  641. ///////////////////////////////
  642. //字符串函数
  643. char *Mid(char *String, long Start, long Length = -1){
  644.         long i = 0, j = 0;
  645.         char string[N] = { '\0' }; strcpy(string, String);
  646.         if (Length == -1)
  647.                 Length = strlen(string) - Start + 1;
  648.         string[Start + Length - 1] = '\0';
  649.         for (i = 0, j = Start - 1; i <= strlen(string); i++, j++)
  650.                 string[i] = string[j];
  651.         return string;
  652. }
  653. ///////////////////////////////
  654. bool AddFunc(char *name, char para[][M], char *expr){
  655.         int i = 0;
  656.         if (IsOper(name) != 0)
  657.                 return false;
  658.         ++iUserFun;

  659.         //printf("\t\\%s\\\n", oper[OFUN_NUM + iUserFun].name);///////////////////////////////////
  660.         oper[OFUN_NUM + iUserFun].ctype = UserFun;
  661.         oper[OFUN_NUM + iUserFun].level = 99;
  662.         oper[OFUN_NUM + iUserFun].name = name;
  663.         oper[OFUN_NUM + iUserFun].number = OFUN_NUM + iUserFun;
  664.         oper[OFUN_NUM + iUserFun].expr = expr;
  665.         //printf("自定义函数:"%s"\n", oper[OFUN_NUM + iUserFun].name);////////////////////
  666.         //oper[OFUN_NUM + iUserFun]
  667.         for (i = 0; i < PAR_MAX; i++){
  668.                 //printf("参数:"%s"\n", para[i]);////////////////////////////////////////
  669.                 if ((IsConst(para[i]) == 0) && (IsPara(para[i]) == 0) && (para[i][0] != '\0')){
  670.                         //printf("参数:"%s"\n", para[i]);////////////////////////////////////////
  671.                         functpara[i + 1].name = para[i];
  672.                         //iParCtr++;
  673.                 }
  674.                 else{
  675.                         break;
  676.                 }
  677.         }
  678.         return true;
  679.         //printf("自定义函数:%s\n", oper[OFUN_NUM + iUserFun].name);////////////////////
  680. }
  681. void SetPara(double value){
  682.         ++iParCtr;
  683.         functpara[iParCtr].number = iParCtr;
  684.         functpara[iParCtr].value = value;
  685. }
  686. bool ClearAllFunc(void){
  687.         int i = 0;
  688.         for (i = 0; i <= iUserFun; i++){
  689.                 oper[OFUN_NUM + iUserFun].name = "";
  690.                 oper[OFUN_NUM + iUserFun].number = 0;
  691.         }
  692.         iUserFun = 0;
  693.         iParCtr = 0;
  694.         return true;
  695. }
  696. //////
  697. bool AddConstant(char *cname, double value){
  698.         int i = 0;
  699.         if (IsConst(cname) != 0)
  700.                 return false;
  701.         if (IsPara(cname) != 0)
  702.                 return false;
  703.         if (IsOper(cname) != 0)
  704.                 return false;
  705.         ++iUserCnt;
  706.         //printf("CST HELLO!\t%d\n", CST_CTR + iUserCnt);///////////////////////////////
  707.         constants[CST_CTR + iUserCnt].name = cname;
  708.         constants[CST_CTR + iUserCnt].value = value;
  709.         constants[CST_CTR + iUserCnt].number = CST_CTR + iUserCnt;
  710.         return true;
  711. }
  712. bool ClearAllConst(void){
  713.         int i = 0;
  714.         for (i = 0; i <= iUserCnt; i++){
  715.                 constants[CST_CTR + iUserCnt].name = "";
  716.                 constants[CST_CTR + iUserCnt].number = 0;
  717.         }
  718.         iUserCnt = 0;
  719.         return true;
  720. }
  721. ///////////////////////////////
  722. void CALC_simple(OTYPE OTOpr, NumSTACK* dblStack, bool isFun = false){
  723.         double tmpNumA = 0.0, tmpNumB = 0.0, tmpNumR = 0.0;
  724.         int j = 0;
  725.         //printf("CALC_simple hello\n");///////////////////////////////
  726.         //printf("\t运算符出栈:%s\n",OTOpr.name);/////////////////////////////////
  727.         switch (OTOpr.ctype){//检测运算符类型
  728.         case DoubleCalOpr:
  729.                 tmpNumA = NPop(dblStack);//取出一个操作数
  730.                 //printf("\t数栈出栈A:%f\n",tmpNumA);////////////////////////////
  731.                 tmpNumB = NPop(dblStack);//取出一个操作数
  732.                 //printf("\t数栈出栈B:%f\n",tmpNumB);////////////////////////////
  733.                 tmpNumR = DOprCal(tmpNumA, tmpNumB, OTOpr.number);//双目运算符运算
  734.                 break;
  735.         case FrontCalOpr:
  736.                 tmpNumA = NPop(dblStack);//取出一个操作数1
  737.                 //printf("\t数栈出栈A2:%f\n",tmpNumA);////////////////////////////
  738.                 tmpNumB = NPop(dblStack);//取出一个操作数2
  739.                 //printf("\t数栈出栈B2:%f\n",tmpNumB);////////////////////////////
  740.                 tmpNumR = FOprCal(OTOpr.number, tmpNumA);
  741.                 NPush(dblStack, tmpNumB);//操作数1进栈
  742.                 //printf("\t内进栈:%f\n",tmpNumB);////////////////////////////
  743.                 break;
  744.         case RearCalOpr:
  745.                 tmpNumA = NPop(dblStack);//取出一个操作数1
  746.                 tmpNumR = ROprCal(tmpNumA, OTOpr.number);
  747.                 break;
  748.         case Functio:
  749.                 for (j = 0; j <= intFunParCount; j++){
  750.                         pa[j] = NPop(dblStack);//取出一个操作数1
  751.                         //printf("\t数栈出栈AF:%f\n", tmpNumA);////////////////////////////
  752.                 }
  753.                 tmpNumR = FOprCal(OTOpr.number);
  754.                 break;
  755.         case UserFun:
  756.                 for (j = 0; j <= intFunParCount; j++)
  757.                         SetPara(NPop(dblStack));//取出一个操作数
  758.                 tmpNumR = FOprCal(OTOpr.number);
  759.                 break;
  760.         }
  761.         NPush(dblStack, tmpNumR);//运算结果进栈
  762.         //printf("数栈进栈 内:%f\n",tmpNumR);////////////////////////////
  763. }
  764. double CALC_main(char *exp){//计算
  765.         //初始化
  766.         //InitOperTable();
  767.         //定义栈
  768.         NumSTACK nStack;
  769.         OprSTACK oStack;
  770.         //初始化栈
  771.         InitNumSTACK(&nStack);
  772.         InitOprSTACK(&oStack);
  773.         char sTmpNum[S_NUM_MAX] = { 0 };//用于[数字整合]的临时变量
  774.         char sTmpOpr[S_OPR_MAX] = { 0 };//用于[运算符整合]临时变量
  775.         char cTmpDblChar[2] = { 0, 0 };//临时存放单个字符
  776.         OTYPE y, w;//
  777.         int iWhichOpr = 0;//记录运算符返回值
  778.         //主循环
  779.         //ix = 0;//位置标记
  780.         if (exp == "")return 0;//空串返零
  781.         //exp = strupr(exp);//全转为大写
  782.         for (ix = 0; ix <= strlen(exp); ix++){
  783.                 if ((exp[ix] >= '0'&&exp[ix] <= '9') || exp[ix] == '-' || exp[ix] == '.'){//区分操作数和运算符及其进栈
  784.                         //数字整合
  785.                         cTmpDblChar[0] = exp[ix];
  786.                         strcat(sTmpNum, cTmpDblChar);
  787.                         if ((exp[ix + 1] >= '0'&&exp[ix + 1] <= '9') || exp[ix + 1] == '-' || exp[ix + 1] == '.'){
  788.                                 continue;
  789.                         }
  790.                         else{//数字进栈
  791.                                 double x = atof(sTmpNum);//转换
  792.                                 NPush(&nStack, x);//数字进栈
  793.                                 //printf("数字进栈A:%f\n",x);/////////////////////////////////
  794.                                 sTmpNum[0] = '\0';//进栈后的临时数串清零
  795.                         }
  796.                 }
  797.                 else{//运算符整合及运算
  798.                         //运算符整合
  799.                         cTmpDblChar[0] = exp[ix];
  800.                         strcat(sTmpOpr, cTmpDblChar);
  801.                         //printf("符号:%s\n", sTmpOpr);////////////////////////////////////////////////////////
  802.                         //printf("yname==%d\n", IsOper(sTmpOpr));/////////////////////////////////////////////////////
  803.                         if (iWhichOpr = IsOper(sTmpOpr)){
  804.                                 y = oper[iWhichOpr];
  805.                                 //printf("yname==%s\n",y.name);/////////////////////////////////////////////////////
  806.                                 sTmpOpr[0] = '\0';
  807.                                 if (y.ctype != IsBracket){
  808.                                         //////////////////////////////////////////////////////////////////////////////////////////////////////////////
  809.                                         while (OPeek(&oStack).level >= y.level&&oStack.top > 0 && OPeek(&oStack).level > 0){//当栈中符的等级大于当前等级时则取出符进行运算
  810.                                                 w = OPop(&oStack);//出栈一个运算符
  811.                                                 //printf("\t运算符出栈1:%s\n",w.name);/////////////////////////////////
  812.                                                 CALC_simple(w, &nStack);
  813.                                                 intFunParCount = 0;
  814.                                         }
  815.                                         OPush(&oStack, &y);//直到无法运算将当前符放入栈中
  816.                                         //printf("运算符进栈1:%s\n",y.name);/////////////////////////////////
  817.                                         //////////////////////////////////////////////////////////////////////////////////////////////////////////////
  818.                                 }
  819.                                 else{
  820.                                         if (y.number == 20){//如果是左括号则无条件进栈
  821.                                                 OPush(&oStack, &y);//进栈后等级为-1,以便遇到右括号出栈
  822.                                                 //printf("运算符进栈2:%s\n",y.name);/////////////////////////////////
  823.                                         }
  824.                                         else if (y.number == 21){//右括号计算
  825.                                                 while (OPeek(&oStack).level != -1){//遇到右括号则计算直到左括号
  826.                                                         w = OPop(&oStack);//出栈一个运算符
  827.                                                         //printf("\t运算符出栈2:%s\n", w.name);/////////////////////////////////
  828.                                                         CALC_simple(w, &nStack);
  829.                                                 }
  830.                                                 OPop(&oStack);//直到遇到左括号将左括号出栈
  831.                                         }
  832.                                         else if (y.number == 22){
  833.                                                 intFunParCount++;
  834.                                         }
  835.                                 }
  836.                         }
  837.                         else{
  838.                                 continue;
  839.                         }
  840.                 }
  841.         }
  842.         while (OPeek(&oStack).level != 0){//表达式结束后对栈进行操作直到栈空
  843.                 if (OPeek(&oStack).level == -1){//如果有为用掉的左括号则报错退出程序
  844.                         Error(SyntaxError);
  845.                         return 0;
  846.                 }
  847.                 //printf("\t\t运算符1:%s\n",OPeek(&oStack).name);/////////////////////////////////
  848.                 w = OPop(&oStack);//取出两个数和一个符进行计算
  849.                 //printf("\t运算符出栈3:%s\n",w.name);/////////////////////////////////
  850.                 CALC_simple(w, &nStack);
  851.                 intFunParCount = 0;
  852.         }
  853.         Answ = NPop(&nStack);
  854.         //constants[3].value = Answ;
  855.         return Answ;
  856. }
  857. ///////////////////////////////
  858. //功能
  859. //角度弧度梯度制转换
  860. inline void ChangeScaleEnv(int x){
  861.         if (x == 0)
  862.                 degScale = S_Rad;
  863.         else if (x == 2)
  864.                 degScale = S_Deg;
  865.         else
  866.                 degScale = S_Gra;
  867. }
  868. //Preprocesser Debugger
  869. char *InputScanner(char *exp){
  870.         srand((int)time(NULL));
  871.         register int i = 0, j = 0, z = 0, h = 0;//循环计数器
  872.         //初始化
  873.         //InitOperTable();
  874.         //InitConstTable();
  875.         constants[4].value = rand();
  876.         if (InitConstTable) constants[3].value = Answ;

  877.         char sTmpOpr[S_OPR_MAX] = { 0 };//用于[运算符整合]临时变量
  878.         char cTmpDblChar[2] = { 0, 0 };//临时存放单个字符
  879.         register int iWhichOpr = 0;//记录运算符返回值
  880.         //int iWhichCst = 0;//记录常数
  881.         OTYPE y; bool bEnvIsTrue = false; CONSTANT c;
  882.         int absCtrAll = 0;//记录"|"的总数

  883.         char tStr[N] = { '\0' }, ttStr[N] = { '\0' }, ttStrB[N] = { '\0' };
  884.         for (i = 0; i <= strlen(exp); i++){
  885.                 if (exp[i] == ' ')//跳过空格
  886.                         continue;
  887.                 if (exp[i] >= 'a'&&exp[i] <= 'z'){
  888.                         tStr[j] = exp[i] - 32;
  889.                 }
  890.                 else{
  891.                         tStr[j] = exp[i];
  892.                 }
  893.                 if (exp[i] == '|')
  894.                         absCtrAll++;
  895.                 j++;
  896.         }
  897.         tStr[j + 1] = '\0';
  898.         strcpy(ttStr, tStr);
  899.         //处理绝对值 将|-1|转换为ABS(-1)
  900.         if (absCtrAll % 2 != 0){
  901.                 Error(SyntaxError);
  902.                 return "";
  903.         }
  904.         for (i = 0; i <= strlen(tStr); i++){
  905.                 if (tStr[i] == '|'){
  906.                         if (h < absCtrAll / 2){
  907.                                 z = 0;
  908.                                 strcpy(ttStr, Mid(tStr, 1, i));
  909.                                 strcpy(ttStrB, Mid(tStr, i + 2));
  910.                                 tStr[0] = '\0';
  911.                                 strcat(tStr, ttStr);
  912.                                 strcat(tStr, "ABS(");
  913.                                 strcat(tStr, ttStrB);
  914.                                 //printf("\t%s\n", tStr);//////////////////
  915.                                 h++;
  916.                         }
  917.                         else
  918.                                 tStr[i] = ')';
  919.                 }
  920.         }
  921.         /*
  922.         for (i = 0; i <= strlen(tStr); i++)
  923.         if (tStr[i] == '|')
  924.         tStr[i] = ')';
  925.         */
  926.         //
  927.         i = 0; j = 0; z = 0; h = 0;
  928.         ttStr[0] = '\0'; ttStrB[0] = '\0';
  929.         //将减法转换为加法 a-b == a+-b
  930.         for (i = 0; i <= strlen(tStr); i++){
  931.                 if ((tStr[0] != NULL) && (i >= 1) && ((tStr[i - 1] >= '0'&&tStr[i - 1] <= '9' || tStr[i - 1] == ')') && (tStr[i] == '-') && ((tStr[i + 1] >= '0'&&tStr[i + 1] <= '9') || tStr[i + 1] == '.' || tStr[i + 1] == '('))){
  932.                         z = 0;
  933.                         ttStr[i] = '+';
  934.                         for (z = i; z <= strlen(tStr); z++)
  935.                                 ttStr[z + 1] = tStr[z];
  936.                         ttStr[z + 1] = '\0';
  937.                         for (z = 0; z <= strlen(ttStr); z++)
  938.                                 tStr[z] = ttStr[z];
  939.                         i++;
  940.                 }
  941.         }
  942.         //将+-()转换为+-1*()
  943.         for (i = 0; i <= strlen(tStr); i++){
  944.                 if ((tStr[0] != NULL) && (tStr[i - 1] == '-' && (tStr[i] == '(' || (tStr[i] >= 'a'&&tStr[i] <= 'z' || tStr[i] >= 'A'&&tStr[i] <= 'Z')))){
  945.                         z = 0;
  946.                         for (z = 0; z < i; z++)
  947.                                 ttStr[z] = tStr[z];
  948.                         ttStr[z] = '1';
  949.                         ttStr[++z] = '*';
  950.                         for (z = i + 2; tStr[z - 2] != NULL; z++)
  951.                                 ttStr[z] = tStr[z - 2];
  952.                         strcpy(tStr, ttStr);
  953.                         i += 2;
  954.                 }
  955.         }
  956.         //printf("1 hello!!\n");//////////////////////////////////////
  957.         //将:2sin变成2*sin
  958.         for (i = 0; i <= strlen(tStr); i++){
  959.                 if ((tStr[i] >= '0'&&tStr[i] <= '9') || tStr[i] == '-' || tStr[i] == '.'){//区分操作数和运算符
  960.                         bEnvIsTrue = true;
  961.                         sTmpOpr[0] = '\0';///////////////////////////WARNING!!!
  962.                 }
  963.                 else{
  964.                         cTmpDblChar[0] = tStr[i];
  965.                         strcat(sTmpOpr, cTmpDblChar);
  966.                         if (iWhichOpr = IsOper(sTmpOpr)){
  967.                                 y = oper[iWhichOpr];
  968.                                 sTmpOpr[0] = '\0';
  969.                                 if ((y.ctype == FrontCalOpr || y.ctype == Functio) && bEnvIsTrue){
  970.                                         z = 0;
  971.                                         ttStr[i - strlen(y.name) + 1] = '*';
  972.                                         for (z = i - strlen(y.name) + 1; z <= strlen(tStr); z++)
  973.                                                 ttStr[z + 1] = tStr[z];
  974.                                         ttStr[z + 1] = '\0';
  975.                                         for (z = 0; z <= strlen(ttStr); z++)
  976.                                                 tStr[z] = ttStr[z];
  977.                                         i++;
  978.                                 }
  979.                                 bEnvIsTrue = false;
  980.                         }
  981.                 }
  982.         }
  983.         //printf("2 hello!!\n");//////////////////////////////////////

  984.         //printf("3 hello!!\n");//////////////////////////////////////
  985.         //将2pi转换成2*pi
  986.         bEnvIsTrue = false; sTmpOpr[0] = '\0';
  987.         for (i = 0; i <= strlen(tStr); i++){
  988.                 if ((tStr[i] >= '0'&&tStr[i] <= '9') || tStr[i] == '-' || tStr[i] == '.'){//区分操作数和运算符
  989.                         bEnvIsTrue = true;
  990.                         sTmpOpr[0] = '\0';
  991.                 }
  992.                 else{
  993.                         //printf("hello\n");///////////////////////////
  994.                         cTmpDblChar[0] = tStr[i];
  995.                         strcat(sTmpOpr, cTmpDblChar);
  996.                         //printf("%s\n",sTmpOpr);////////////////////////////
  997.                         if (iWhichOpr = IsConst(sTmpOpr)){
  998.                                 //printf("hello\n");///////////////////////////
  999.                                 c = constants[iWhichOpr];
  1000.                                 sTmpOpr[0] = '\0';
  1001.                                 if (bEnvIsTrue){
  1002.                                         /*
  1003.                                         z = 0;
  1004.                                         ttStr[i - strlen(c.name) + 1] = '*';
  1005.                                         for (z = i - strlen(c.name) + 1; z <= strlen(tStr); z++)
  1006.                                         ttStr[z + 1] = tStr[z];
  1007.                                         ttStr[z + 1] = '\0';
  1008.                                         for (z = 0; z <= strlen(ttStr); z++)
  1009.                                         tStr[z] = ttStr[z];
  1010.                                         i++;
  1011.                                         */
  1012.                                         strcpy(ttStr, Mid(tStr, 1, i - strlen(c.name) + 1));
  1013.                                         //printf("A\tttStr %s\n", ttStr); system("pause");////////////////////////////////////
  1014.                                         strcat(ttStr, "*");
  1015.                                         //printf("B\tttStr %s\n", ttStr); system("pause");////////////////////////////////////
  1016.                                         //printf("BA\tttStr %s\n", Mid(tStr, i)); system("pause");////////////////////////////////////
  1017.                                         strcat(ttStr, Mid(tStr, i));
  1018.                                         //printf("C\tttStr %s\n", ttStr); system("pause");////////////////////////////////////
  1019.                                         i = i - strlen(c.name) + 1;
  1020.                                         strcpy(tStr, ttStr);
  1021.                                 }
  1022.                                 bEnvIsTrue = false;
  1023.                         }
  1024.                 }
  1025.         }
  1026.         //printf("\t"%s"\n", tStr);/////////////////////////////////////////////////////////
  1027.         //

  1028.         //printf("::::%s\n", tStr);/////////////////////////////////////////////////////i <= strlen(tStr)
  1029.         //将函数参数替换成数值
  1030.         sTmpOpr[0] = '\0'; bEnvIsTrue = true;
  1031.         for (i = 0; i <= strlen(tStr); i++){
  1032.                 if ((tStr[i] >= '0'&&tStr[i] <= '9') || tStr[i] == '-' || tStr[i] == '.'){//区分操作数和运算符
  1033.                         //bEnvIsTrue = true;
  1034.                         sTmpOpr[0] = '\0';
  1035.                 }
  1036.                 else{
  1037.                         //printf("tstr %s\n", tStr);
  1038.                         //printf("i==%d\n", i);///////////////////////////////////////////////////////////////////////
  1039.                         //printf("\t%c\n",tStr[i]);////////////////////////////////////////////
  1040.                         //if ((tStr[i] >= 'A') && (tStr[i] <= 'Z')){//区分操作数和运算符
  1041.                         //printf("1A,%d====%s\n", i, sTmpOpr);///////////////////////////////////////////
  1042.                         cTmpDblChar[0] = tStr[i];
  1043.                         //if (cTmpDblChar[0] >= '0' || cTmpDblChar[0] <= '9')sTmpOpr[0] = '\0';///////////////////////////////////////////
  1044.                         strcat(sTmpOpr, cTmpDblChar);
  1045.                         //printf("XX %s\n",sTmpOpr);///////////////////////////////////////////////////////////
  1046.                         //printf("IsPara %d\n", IsPara(sTmpOpr));////////////////////////////////////////////////
  1047.                         //printf("\t\tEnv %d\n", bEnvIsTrue);/////////////////////////////////////////////////////
  1048.                         //if (strcmp(sTmpOpr, "PI") == 0) printf("ok\n");
  1049.                         if (IsOper(sTmpOpr)){
  1050.                                 sTmpOpr[0] = '\0';
  1051.                                 bEnvIsTrue = true;
  1052.                         }
  1053.                         else if ((iWhichOpr = IsConst(sTmpOpr)) && bEnvIsTrue){
  1054.                                 //printf("sTmpOpr \'%s\'\n", sTmpOpr);//////////////////////////////////////////////////显示字符串
  1055.                                 sTmpOpr[0] = '\0';
  1056.                                 bEnvIsTrue = false;
  1057.                                 c = constants[iWhichOpr];
  1058.                                 //printf("替换hello\n");
  1059.                                 printf("替换 %s\n",c.name);
  1060.                                 strcpy(ttStr, Mid(tStr, 1, i - strlen(c.name) + 1));
  1061.                                 //printf("A\tttStr %s\n", ttStr); system("pause");////////////////////////////////////
  1062.                                 j = sprintf(ttStrB, "%.16f", c.value);
  1063.                                 strcat(ttStr, ttStrB);
  1064.                                 //printf("B\tttStr %s\n", ttStr); system("pause");////////////////////////////////////
  1065.                                 strcat(ttStr, Mid(tStr, i + strlen(c.name)));
  1066.                                 //printf("C\tttStr %s\n", ttStr); system("pause");////////////////////////////////////
  1067.                                 i = i - strlen(c.name) + j;
  1068.                                 strcpy(tStr, ttStr);

  1069.                                 //printf("tStr %s\n", tStr);
  1070.                                 //printf("i %d\n", i + strlen(c.name)+j);
  1071.                                 //i += (j + (i - (strlen(c.name) + 1)));
  1072.                                 //i += strlen(c.name) + j;
  1073.                         }
  1074.                 }
  1075.         }
  1076.         //将函数参数替换成数值B
  1077.         sTmpOpr[0] = '\0'; bEnvIsTrue = true;
  1078.         for (i = 0; i <= strlen(tStr); i++){
  1079.                 if ((tStr[i] >= '0'&&tStr[i] <= '9') || tStr[i] == '-' || tStr[i] == '.'){//区分操作数和运算符
  1080.                         sTmpOpr[0] = '\0';
  1081.                 }
  1082.                 else{
  1083.                         cTmpDblChar[0] = tStr[i];
  1084.                         strcat(sTmpOpr, cTmpDblChar);

  1085.                         if (IsOper(sTmpOpr)){
  1086.                                 sTmpOpr[0] = '\0';
  1087.                                 bEnvIsTrue = true;
  1088.                         }
  1089.                         else if ((iWhichOpr = IsPara(sTmpOpr)) && bEnvIsTrue){
  1090.                                 sTmpOpr[0] = '\0';
  1091.                                 bEnvIsTrue = false;
  1092.                                 c = functpara[iWhichOpr];

  1093.                                 strcpy(ttStr, Mid(tStr, 1, i - strlen(c.name) + 1));
  1094.                                 //printf("A\tttStr %s\n", ttStr); system("pause");////////////////////////////////////
  1095.                                 j = sprintf(ttStrB, "%.16f", c.value);
  1096.                                 strcat(ttStr, ttStrB);
  1097.                                 //printf("B\tttStr %s\n", ttStr); system("pause");////////////////////////////////////
  1098.                                 strcat(ttStr, Mid(tStr, i + strlen(c.name)));
  1099.                                 //printf("C\tttStr %s\n", ttStr); system("pause");////////////////////////////////////
  1100.                                 i = i - strlen(c.name) + j;
  1101.                                 strcpy(tStr, ttStr);
  1102.                         }
  1103.                 }
  1104.         }
  1105.         return tStr;
  1106. }
  1107. ///////////////////////////////
  1108. void Debug_Print_Para(void){
  1109.         int i = 0;
  1110.         for (i = 0; i <= CST_CTR + iUserCnt; i++){
  1111.                 //printf("参数:"%s"\n", para[i]);////////////////////////////////////////
  1112.                 //printf("参数:"%s"\n", para[i]);////////////////////////////////////////
  1113.                 //printf("\t%s %f\n", functpara[i].name, functpara[i].value);
  1114.                 printf("\t%s\n", constants[i].name);
  1115.                 //iParCtr++;
  1116.         }
  1117. }
  1118. //主函数
  1119. void PrintTitle(void){
  1120.         printf("Calculation Engine Kernel Alpha\n");
  1121.         printf("Copyright (C) 2014 Ctechnology Corporation & TZR Lab.\n");
  1122.         printf("All Rights Resaved.\n");
  1123. }
  1124. int main(){
  1125.         //////freopen("C:\\Users\\Cosh Cage\\Desktop\\t.txt","r",stdin);
  1126.         //////char* a="16.714+56";
  1127.         InitOperTable();
  1128.         InitConstTable();
  1129.         InitParaTable();

  1130.         char a[N] = { 0 };
  1131.         //Debug_Print_Para();
  1132.         AddConstant("ZZZ", 3.0);
  1133.         //Debug_Print_Para();
  1134.         char par[10][M] = { '\0' };
  1135.         strcat(par[0], "AA");
  1136.         strcat(par[1], "BB");
  1137.         strcat(par[2], "CC");

  1138.         AddFunc("SSUM", par, "AA+BB+CC");

  1139.         //printf("??%d\n", IsConst("ZZ"));//////////////////////////////////
  1140.         //printf("!! %s\n", constants[5].name);/////////////////////////////////////////////
  1141.         //ClearAllFunc();
  1142.         //printf("Calculation Engine Kernel Alpha\n");
  1143.         //printf("Copyright (C) 2014 Ctechnology Corporation & TZR Lab.\n");
  1144.         //printf("All Rights Resaved.\n");
  1145.         /*
  1146.         do{
  1147.         printf("?"); gets(a);
  1148.         //////////std::cin >> a;
  1149.         strcpy(a, InputScanner(a));
  1150.         printf("%s\n", a);
  1151.         printf("ANS=%f\n", CALC_main(a));
  1152.         } while (a[0] != NULL);
  1153.         */
  1154.         //15+6-8/2*5\n3+8*6-13\n9-2*3*3+8-6+5
  1155.         //printf("2*(1+2)\n");
  1156.         //printf("9-2-6\n");
  1157.         //8+2-(7-4)*2//3+2*(5-2)-4//3+4-(6+2)*2
  1158.         /////////////////////InitConstTable();
  1159.         //////////////////////printf("%d\n", IsConst("PIP\0"));//////////////////

  1160.         //strcpy(a, InputScanner("zz+1"));
  1161.         //printf(""%s"\n", a);
  1162.         //printf("ANS=%f\n", CALC_main(a));

  1163.         //Debug_Print_Para();
  1164.         //printf("IsPara %d\n", IsPara("AA"));////////////////////////////////////////////////
  1165.         //printf("\n");
  1166.         //printf("End:%s\n", InputScanner("AA+BB+CC"));

  1167.         //system("Pause");

  1168.         int i = 0; double localAns;
  1169.         char *fn; char str[M];
  1170.         PrintTitle();
  1171.         do{
  1172.                 printf("?"); gets(a);
  1173.                 if (strcmp(strupr(a), "ADDFUN") == 0){
  1174.                         do{
  1175.                                 printf("\tFunction Name?"); gets(a);
  1176.                                 fn = a;
  1177.                                 for (i = 0; i < 10; i++){
  1178.                                         printf("\tFunction Parament?"); gets(a);
  1179.                                         if (a[0] == '\0'){
  1180.                                                 break;
  1181.                                         }
  1182.                                         else{
  1183.                                                 strcat(par[0], a);
  1184.                                         }
  1185.                                 }
  1186.                                 printf("\tFunction Expression?"); gets(a);
  1187.                                 AddFunc(fn, par, a); printf("\tAdded OK!\n");
  1188.                                 printf("\tFunction Name?"); gets(a);
  1189.                         } while (a[0] != NULL);
  1190.                         printf("?"); gets(a);
  1191.                 }
  1192.                 else if (strcmp(strupr(a), "ADDVAR") == 0){
  1193.                         do{
  1194.                                 printf("\tVar Name?"); gets(a);
  1195.                                 fn = a;
  1196.                                 printf("\tVar Value?"); gets(a);
  1197.                                 AddConstant(fn, atof(a)); printf("\tAdded OK!\n");
  1198.                                 printf("\tVar Name?"); gets(a);
  1199.                         } while (a[0] != NULL);
  1200.                         printf("?"); gets(a);
  1201.                 }
  1202.                 else if (strcmp(strupr(a), "DELALLFUN") == 0){
  1203.                         ClearAllFunc(); printf("Done!\n");
  1204.                         printf("?"); gets(a);
  1205.                 }
  1206.                 else if (strcmp(strupr(a), "DELALLVAR") == 0){
  1207.                         ClearAllConst(); printf("Done!\n");
  1208.                         printf("?"); gets(a);
  1209.                 }
  1210.                 else if (strcmp(strupr(a), "SCALE") == 0){
  1211.                         do{
  1212.                                 printf("\t\t0:Rad\n\t\t2:Deg\n\t\tAny:Gra\n\tScale?"); gets(a);
  1213.                                 ChangeScaleEnv(atoi(a));
  1214.                         } while (a[0] != NULL);
  1215.                         printf("?"); gets(a);
  1216.                 }
  1217.                 else if (strcmp(strupr(a), "CLS") == 0){
  1218.                         system("cls");
  1219.                         PrintTitle();
  1220.                 }
  1221.                 else{
  1222.                         //////////std::cin >> a;
  1223.                         strcpy(a, InputScanner(a));
  1224.                         localAns = CALC_main(a);
  1225.                         //printf("%s\n", a);
  1226.                         str[0] = '\0';
  1227.                         if (ERR_NUM != NoError){
  1228.                                 for (i = 1; i <= ix - 2; i++){
  1229.                                         strcat(str, " ");
  1230.                                 }
  1231.                                 strcat(str, "^\n");
  1232.                                 if (ERR_NUM == MathError){
  1233.                                         strcat(str, "MathError!");
  1234.                                 }
  1235.                                 else if (ERR_NUM == StackError){
  1236.                                         strcat(str, "StackError!");
  1237.                                 }
  1238.                                 else if (ERR_NUM == SyntaxError){
  1239.                                         strcat(str, "SyntaxError!");
  1240.                                 }
  1241.                                 else if (ERR_NUM == UnknownError){
  1242.                                         strcat(str, "UnknownError!");
  1243.                                 }
  1244.                                 printf("%s\n", a);
  1245.                                 printf("%s\n", str);
  1246.                         }
  1247.                         printf("ANS=%f\n", localAns);
  1248.                 }
  1249.         } while (a[0] != NULL);

  1250.         return 0;
  1251. }
  1252. //////////END///////////////////
复制代码
回复 赞! 靠!

使用道具 举报

发表于 2014-11-18 22:51:35 | 显示全部楼层
天哪,上边怎么回事?我的代码呢!?

点评

广告位下面。  发表于 2014-12-30 17:16
回复 赞! 靠!

使用道具 举报

发表于 2014-11-18 22:55:20 | 显示全部楼层
calengknl.zip (9.43 KB, 下载次数: 6)
回复 赞! 靠!

使用道具 举报

发表于 2014-12-30 17:16:12 | 显示全部楼层
哈哈 这个好
回复 赞! 靠!

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-12-27 03:02 , Processed in 0.052175 second(s), 31 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表