逆波兰计算器revpolish.exe

happy886rr
渐入佳境
渐入佳境
帖子: 45
注册时间: 2016年09月27日 16:11
拥有现金: 锁定
储蓄: 锁定
Has thanked: 14 times
Been thanked: 14 times
联系:

逆波兰计算器revpolish.exe

帖子 #1 happy886rr » 2017年01月18日 19:00

纯C语言写的计算器,支持复杂多函数混合嵌套,每秒可连续处理百万行乃至千万行算式。
摘要:
x86&x64架构windows版,下载:revpolish.exe
图片

x86&x64架构linux版,下载: revpolish
图片

安卓apk 版,下载: revpolish.apk
图片

arm架构版,下载: revpolish

用法:
-----------------------------------------------------------------------------
revpolish [expression]
-----------------------------------------------------------------------------

示例:
-----------------------------------------------------------------------------
revpolish ((3*3+2)%6+7.187)*5-7/189+3^2
revpolish (ceil(sin(pi/3)+2)%6+0.187)*e-lg(6.5)
revpolish 5*(arctan(cos(sin(ln(lg(2.71828))))))
-----------------------------------------------------------------------------

备注:
-----------------------------------------------------------------------------
常数类
pi 3.1415926535897932
e 2.7182818284590452
通用类
round 四舍五入
floor 整取
abs 绝对值
ceil 向上舍入
deg 角度转弧度
exp e的次幂
sqrt 开方
fac 阶乘
lg 常用对数,以10为底
ln 自然对数
+ 加
- 减
* 乘
/ 除
% 取余数
^ 次方
! 阶乘

三角函数类
sin、cos、tan
arcsin、arccos、arctan

双曲函数类
sinh、cosh、tanh
arcsinh、arccosh、arctanh
-----------------------------------------------------------------------------

revpolish.c源码:
Code: [全选] [展开/收缩] [Download] (Untitled.c)
  1. /*
  2.     REVERSE POLISH EXPRESSION CALCULATOR, COPYRIGHT@2017~2019 BY HAPPYSXYF
  3.     REVPOLISH.EXE
  4.     VERSION 1.6
  5. */
  6.  
  7. #include   <stdio.h>
  8. #include   <ctype.h>
  9. #include    <math.h>
  10. #include <windows.h>
  11.  
  12. /***************定义宏变量***************/
  13. //堆栈尺寸
  14. #define  STACK_SIZE   1024
  15. //帮助说明
  16. #define HELPINFORMATION "\
  17. REVERSE POLISH EXPRESSION CALCULATOR, VERSION 1.6\n\
  18. -----------------------------------------------------------------\n\
  19. revpolish [expression]\n\
  20. -----------------------------------------------------------------\n\
  21. EXAMPLES:\n\
  22.     revpolish ((3*3+2)%6+7.187)*5-7/189+3^2\n\
  23.     revpolish (ceil(sin(pi/3)+2)%6+0.187)*e-lg(6.5)\n\
  24.     revpolish 5*(arctan(cos(sin(ln(lg(2.71828))))))\n\
  25. -----------------------------------------------------------------\n\
  26. FUNCTIONS:\n\
  27.     pi=3.1415926535897932, e=2.7182818284590452\n\
  28.     +, -, *, /, %, ^, !\n\
  29.     round, floor, ceil, exp, deg, sqrt, abs, lg, ln\n\
  30.     sin, cos, tan, arcsin, arccos, arctan\n\
  31.     sinh, cosh, tanh, arcsinh, arccosh, arctanh\n\
  32. -----------------------------------------------------------------\n\
  33. COPYRIGHT@2017~2019 BY HAPPYSXYF 2017-01-03\n"
  34.  
  35. /***************全局类变量***************/
  36. //数学函数关键词
  37. static const char* KEY_WORDS[]={"e", "pi", "sqrt", "lg", "ln", "sin", "cos", "tan", "arcsin", "arccos", "arctan", "deg", "abs", "round", "floor", "ceil", "exp", "sinh", "cosh", "tanh", "arcsinh", "arccosh", "arctanh", NULL};
  38. //运算符栈
  39. char   STACK1[STACK_SIZE]={0};
  40. //逆波兰栈
  41. char   STACK2[STACK_SIZE]={0};
  42. //浮点数栈
  43. double STACK3[STACK_SIZE]={0};
  44.  
  45. /***************功能函数类***************/
  46. //阶乘函数
  47. long long fact(long long n)
  48. {
  49.     return (n<2) ?1 :n*(fact(n-1));
  50. }
  51. //逆波兰核心
  52. double RevPolishCore(const char* expression)
  53. {
  54.     char   *op=(char*)expression, *S1=STACK1, *S2=STACK2, **key, *cp, *kp;
  55.     double *S3=STACK3, di, ni;
  56.    
  57.     //生成逆波兰  
  58.     while(*op!='\0'){      
  59.         switch(*op){
  60.         case ' ' :
  61.         case '\t':
  62.         case '\r':
  63.         case '\n':
  64.             //过滤空字符
  65.             op++;
  66.             continue;
  67.  
  68.         case 'a':
  69.         case 'b':
  70.         case 'c':
  71.         case 'd':
  72.         case 'e':
  73.         case 'f':
  74.         case 'g':
  75.         case 'h':
  76.         case 'i':
  77.         case 'j':
  78.         case 'k':
  79.         case 'l':
  80.         case 'm':
  81.         case 'n':
  82.         case 'o':
  83.         case 'p':
  84.         case 'q':
  85.         case 'r':
  86.         case 's':
  87.         case 't':
  88.         case 'u':
  89.         case 'v':
  90.         case 'w':
  91.         case 'x':
  92.         case 'y':
  93.         case 'z':
  94.             //识别数学函数关键词
  95.             key=(char**)KEY_WORDS;
  96.             while(*key !=NULL){
  97.                 cp=op, kp=*key;
  98.                 //比对关键词字母
  99.                 while(*cp==*kp && *kp!='\0'){
  100.                     cp++, kp++;
  101.                 }
  102.                 //验证关键词结尾
  103.                 if((*cp<'a'||*cp>'z') && (*kp=='\0')){
  104.                     op=cp;
  105.                     break;
  106.                 }
  107.                 key++;
  108.             }
  109.             //构建伪双目
  110.             if(*key !=NULL){               
  111.                 *(S2++)='.';
  112.                 *(S2++)=' ';
  113.                 //伪双目入栈
  114.                 while('A'<=(*S1) && (*S1)<='Z'){
  115.                     *(S2++)=*(S1--);
  116.                 }
  117.                 *(++S1)=key-(char**)KEY_WORDS+65;
  118.                 continue;
  119.             }else{
  120.                 //无法识别的数学函数
  121.                 fputs("Unrecognized math function\n", stderr);
  122.                 exit(1);
  123.             }
  124.             break;
  125.        
  126.         case '(':
  127.             *(++S1)=*op;
  128.             if(*(op+1)=='-' || *(op+1)=='+'){
  129.                 *(S2++)='0', *(S2++)=' ';
  130.             }
  131.             break;
  132.  
  133.         case ')':
  134.             while(*S1!='(')
  135.             {
  136.                 *(S2++)=*(S1--);
  137.             }      
  138.             //舍弃'('
  139.             S1--;      
  140.             break;
  141.  
  142.         case '+':
  143.         case '-':
  144.             while(S1!=STACK1 && *S1!='(')
  145.             {
  146.                 *(S2++)=*(S1--);
  147.             }
  148.             *(++S1)=*op;
  149.             break;
  150.  
  151.         case '^':
  152.             //指数符
  153.             while('A'<=(*S1) && (*S1)<='Z')
  154.             {
  155.                 *(S2++)=*(S1--);
  156.             }
  157.             *(++S1)=*op;
  158.             break;
  159.  
  160.         case '!':
  161.             //阶乘符
  162.             *(S2++)=*op;
  163.             break;
  164.  
  165.         case '%':
  166.         case '*':
  167.         case '/':
  168.             while(('A'<=(*S1) && (*S1)<='Z') ||*S1=='%' ||*S1=='*' ||*S1=='/' ||*S1=='^'){
  169.                 *(S2++)=*(S1--);
  170.             }
  171.             *(++S1)=*op;
  172.             break;
  173.  
  174.         default :
  175.             if((*op<'0' || *op>'9') && (*op!='.')){
  176.                 //无法识别的运算符
  177.                 fputs("Unrecognized operator\n", stderr);
  178.                 exit(1);
  179.             }
  180.             //浮点数入栈
  181.             while(('0'<=*op && *op<='9') ||*op=='.'){
  182.                 *(S2++)=*(op++);
  183.             }
  184.             op--;
  185.             *(S2++)=' ';
  186.             break;
  187.         }
  188.         op++;
  189.     }
  190.     //收尾逆波兰
  191.     while(S1 !=STACK1){*(S2++)=*(S1--);}
  192.     *S2=' ';
  193.  
  194.     //计算逆波兰
  195.     op=STACK2;
  196.     while(*op!=' '){
  197.         switch(*op){
  198.         case 'A':
  199.             *S3=2.7182818284590452;
  200.             break;
  201.         case 'B':
  202.             *S3=3.1415926535897932;
  203.             break;
  204.         case 'C':
  205.             if(*S3 <0){
  206.                 //负数没有平方根
  207.                 fputs("Negative numbers have no square root\n", stderr);
  208.                 exit(1);
  209.             }
  210.             *(S3-1)=sqrt(*S3);
  211.             S3--;
  212.             break;
  213.         case 'D':
  214.             if(*S3 <0){
  215.                 //负数没有对数
  216.                 fputs("Negative numbers are not logarithmic\n", stderr);
  217.                 exit(1);
  218.             }
  219.             *(S3-1)=log10(*S3);
  220.             S3--;
  221.             break;
  222.         case 'E':
  223.             if(*S3 <0){
  224.                 //负数没有自然对数
  225.                 fputs("Negative numbers have no natural logarithms\n", stderr);
  226.                 exit(1);
  227.             }
  228.             *(S3-1)=log(*S3);
  229.             S3--;
  230.             break;
  231.         case 'F':
  232.             *(S3-1)=sin(*S3);
  233.             S3--;
  234.             break;
  235.         case 'G':
  236.             *(S3-1)=cos(*S3);
  237.             S3--;
  238.             break;
  239.         case 'H':
  240.             if(*S3==3.1415926535897932/2){
  241.                 //π/2没有正切值
  242.                 fputs("The pi/2 has no tangent\n", stderr);
  243.                 exit(1);
  244.             }
  245.             *(S3-1)=tan(*S3);
  246.             S3--;
  247.             break;
  248.         case 'I':
  249.             *(S3-1)=asin(*S3);
  250.             S3--;
  251.             break;
  252.         case 'J':
  253.             *(S3-1)=acos(*S3);
  254.             S3--;
  255.             break;
  256.         case 'K':
  257.             *(S3-1)=atan(*S3);
  258.             S3--;
  259.             break;
  260.         case 'L':
  261.             *(S3-1)=(*S3)*3.1415926535897932/180.0;
  262.             S3--;
  263.             break;
  264.         case 'M':
  265.             *(S3-1)=(*S3<0)?(-(*S3)):(*S3);
  266.             S3--;
  267.             break;
  268.         case 'N':
  269.             *(S3-1)=round(*S3);
  270.             S3--;
  271.             break;
  272.         case 'O':
  273.             *(S3-1)=floor(*S3);
  274.             S3--;
  275.             break;
  276.         case 'P':
  277.             *(S3-1)=ceil(*S3);
  278.             S3--;
  279.             break;
  280.         case 'Q':
  281.             *(S3-1)=exp(*S3);
  282.             S3--;
  283.             break;
  284.         case 'R':
  285.             *(S3-1)=sinh(*S3);
  286.             S3--;
  287.             break;
  288.         case 'S':
  289.             *(S3-1)=cosh(*S3);
  290.             S3--;
  291.             break;
  292.         case 'T':
  293.             *(S3-1)=tanh(*S3);
  294.             S3--;
  295.             break;
  296.         case 'U':
  297.             *(S3-1)=asinh(*S3);
  298.             S3--;
  299.             break;
  300.         case 'V':
  301.             *(S3-1)=acosh(*S3);
  302.             S3--;
  303.             break;
  304.         case 'W':
  305.             *(S3-1)=atanh(*S3);
  306.             S3--;
  307.             break;
  308.         case '+':
  309.             *(S3-1)+=*S3;
  310.             S3--;
  311.             break;
  312.         case '-':
  313.             *(S3-1)-=*S3;
  314.             S3--;
  315.             break;
  316.         case '*':
  317.             *(S3-1)*=*S3;
  318.             S3--;
  319.             break;
  320.         case '%':
  321.         case '/':
  322.             if(*S3 !=0){
  323.                 if(*op=='%'){
  324.                     //取余数
  325.                     *(S3-1)=(int)*(S3-1) % (int)*S3;
  326.                 }else{
  327.                     *(S3-1)/=*S3;
  328.                 }
  329.                
  330.             }else{
  331.                 //除数不能为零
  332.                 fputs("Divisor is zero error\n", stderr);
  333.                 exit(1);
  334.             }
  335.             S3--;
  336.             break;
  337.         case '^':
  338.             if(*(S3-1)==0 && *S3<0){
  339.                 //除数不能为零
  340.                 fputs("Function pow's divisor is zero error\n", stderr);
  341.                 exit(1);
  342.             }
  343.             *(S3-1)=pow(*(S3-1), *S3);
  344.             S3--;
  345.             break;
  346.         case '!':
  347.             if(*S3 <0){
  348.                 //负数没有阶乘
  349.                 fputs("Negative numbers have no factorial\n", stderr);
  350.                 exit(1);
  351.             }
  352.             *S3=fact((long long)(*S3));
  353.             break;
  354.         default :
  355.             //字符串转浮点
  356.             di=0, ni=1;
  357.             while('0'<=*op && *op<='9'){
  358.                 di=10*di+(*op)-'0';
  359.                 op++;
  360.             }  
  361.             if(*op=='.'){
  362.                 op++;
  363.                 while('0'<=*op && *op<='9'){
  364.                     di=10*di+(*op)-'0';
  365.                     op++, ni*=10;
  366.                 }  
  367.             }
  368.             *(++S3)=di/ni;
  369.             break;
  370.         }
  371.         op++;
  372.     }
  373.  
  374.     /////////////////////////////////////////////////////////////////////
  375.     //返回计算结果
  376.     //return *S3;
  377.  
  378.     //打印中缀式
  379.     fprintf(stdout, "ORIGINALEXP: %s\n", expression);
  380.  
  381.     //打印后缀式
  382.     fprintf(stdout, "REVPOLISH:   ");
  383.     op=STACK2;
  384.     while(op!=S2){
  385.         if(*op=='.' && *(op+1)==' '){
  386.             op++;
  387.  
  388.         }else if('A'<=(*op) && (*op)<='Z'){
  389.             fprintf(stdout, "%s ", KEY_WORDS[*op-65]);
  390.            
  391.         }else{
  392.             fputc(*op, stdout);
  393.             if(*op=='+' ||*op=='-' ||*op=='*' ||*op=='/' ||*op=='%' ||*op=='^' ||*op=='!'){fputc(' ', stdout);}
  394.         }
  395.         op++;
  396.     }
  397.     fputc('\n', stdout);
  398.  
  399.     //打印计算结果
  400.     fprintf(stdout, "RESULT:      %.16lf\n", *S3);
  401. }
  402.  
  403. /*************MAIN主函数入口*************/
  404. int main(int argc, char** argv)
  405. {
  406.     if((argc==1) || (argc==2 && argv[1][0]=='/' && (argv[1][1]=='?'||argv[1][1]=='h'))){
  407.         //使用说明
  408.         fputs(HELPINFORMATION, stderr);
  409.         exit(1);
  410.     }
  411.     RevPolishCore(argv[1]);
  412.     return 0;
  413. }

回到 “算法和编码”

在线用户

用户浏览此论坛: 没有注册用户 和 0 访客