免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 9058 | 回复: 6
打印 上一主题 下一主题

字符串表达式 计算表达式 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-08-09 17:08 |只看该作者 |倒序浏览
calc.exe   v1*v1+v2*v3   10  20  30  40
           calc.exe : 程序名
v1*v1+v2*v3 : 字符串表达式
10  20  30  40 : 4个参数

最重要的是把字符串表达式v1*v1+v2*v3 转化成计算表达式,现在没有什么可行的思路, 请各位给点指导,谢谢。

论坛徽章:
0
2 [报告]
发表于 2011-08-09 17:13 |只看该作者
没太明白

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
3 [报告]
发表于 2011-08-09 17:24 |只看该作者
本帖最后由 yulihua49 于 2011-08-09 17:51 编辑
calc.exe   v1*v1+v2*v3   10  20  30  40
           calc.exe : 程序名
v1*v1+v2*v3 : 字符串表达式 ...
jz1043 发表于 2011-08-09 17:08


哈哈,我有类似的玩意儿。
不过,变量是项号,可以理解为数组下标。

  1. 2. 字典编写规则

  2.         ① 基本运算符

  3.             ()
  4.             算术运算符:         +, -, *, /, %  ( 优先级 )
  5.             逻缉运算符:         =, <=, >=, <>, !=,
  6.                                 &,|
  7.                                 :?

  8.         ② 基本格式

  9.             每行由两部分组成,前半部份为表达式, 由分号隔开的后半部份
  10.             为格式说明, '#'后可跟注释,如需打印#,可用\#.


  11.             1. 算术表达式

  12.                算术表达式可由三种最基本的表达式组成

  13.                (1)    a1,a2,a3,a4,a5, n 尾标
  14.                       ┃          ┃  ┃
  15.                       ┗━━┳━━━┛  ┗━━━━━━━━┓
  16.                            ┃                        ┃
  17.                            ┃                        ┃
  18.                            ┃                        ┃
  19.                          索引标记                     项号

  20.                索引标记: 由字母或数字构成, 若含有 + - * / % , \
  21.                                  应前置 \ 引导.
  22.                        项    号: 由数字构成.
  23.                        尾    标: 由一个字母构成 a - z, A - Z.
  24.                (2)    nL
  25.                     字典用存储变量. 详见存储规则
  26.                (3) 浮点表达式, 代表立即数. 例: 0.5, -5e10.
  27.     2. 条件表达式

  28.             单行条件表达式:
  29.                若e1, e2和e3是三个算术表达式, 则在条件表达式
  30.                        e1?e2:e3
  31.                e1的格式:变量或数值 操作符 变量或数值 逻辑操作符 ...
  32.                中, 首先计算e1的值, 若非零(真), 则计算e2的值, 并且此值就是该表达
  33.                式的值; 否则, 计算e3的值, 并且此值就是该表达式的值. e2和e3仅有一
  34.                个被求值.  e2 和 e3 含有格式说明.

  35.             多行条件表达式:
  36.                        条件表达式?
  37.                         条件为真的语句
  38.                        :
  39.                         条件为假的语句
  40.                        $
  41.                        条件表达式?
  42.                         条件为真的语句
  43.                        :第二个条件表达式?       # else if,可以有多个
  44.                         第二个条件为真的语句
  45.                        :                         # 可以没有
  46.                         条件为假的语句
  47.                        $

  48.            条件表达式可以嵌套使用。

  49.             3. 输出格式规则

  50.                若表达式后跟有分号, 则表明本行字典值要输出. 格式为 ;m.n
  51.                其中: m 为保留小数位数
  52.                      无n时m:为小数点左移位数.
  53.                   n 为舍入规则
  54. n: 0-- 遇0输出0 四舍五入.
  55.    以下遇0输出空
  56.    1-- 向-舍入.
  57.    2-- 向+舍入.
  58.    3-- 向0舍入.
  59.    4-- 只入.
  60.    5-- 四舍五入.
  61.    无- 小数点左移m位,四舍五入.  为加权四舍五入.
  62.                 例:
  63.                      3450.495;2.5
  64.                      3450.50

  65.                      3450.495;2
  66.                      34.50

  67.                      3450.50;2
  68.                      34.51

  69.                     ;g float format
  70.                     ;y: 年
  71.                     ;m: 月
  72.                     ;d: 日
  73.                     ;w: 星期
  74.                     ;Y: 年月日
  75.                     ;j: 季度
  76.                     ;l: 字符串打印小写
  77.                     ;u: 字符串打印大写
  78.                     ;n: 不打印

  79.                     ;+m.n  输出需要+-号
  80.                     ;0m    输出m位宽, 补前0
  81.                     ; m    输出m位宽, 补空格
  82.              基本格式之后跟其他字符将被打印出来, 行尾的&表示不换行.

  83.             4. 字典日期

  84.                     D:  日期
  85.                     0D:  数据库日期 本月  几日
  86.                     1D:  记录的日
  87.                     2D:  当日的日 (程序日期)
  88.                     3D:  当年的天数
  89.                     4D:  程序指定的月份
  90.                     6D:  内部日
  91.                     7D:  季度天数

  92.                 日期表达式

  93.                     .               当日
  94.                     \+1          明天
  95.                     \-1           昨天
  96.                     .\-1.,2D;   昨日日期
  97.                     .L,2D;      月底日
  98.                     . .,4D;     当日月份

  99.         ③ 存储规则

  100.             字典具有变量存储功能. 要将某字典行的值存储, 可写成 nL=表达式.
  101.             (其中, n为正整数),  其中, nL即为变量,其中 0<= n <=9,若超过此
  102.             值,则须用 LABN=n  加以说明. 此说明应单独占一行.


  103.         ④ 缺省规则

  104.             编写字典时, 索引标记部分的值均可省略, 若某个值缺省, 则其值为
  105.             前一次查找记录所使用的索引值, 依此类推.


  106.         ⑤ 几个完整字典行

  107.             LABN=m
  108.             nL=A+B/C+1000.;      #  (即存储又输出)
  109.             pL=E+nL              #         (存储不输出)
  110.             A?B;:C-D;2.0          #         (若A为真, 则输出B, 否则输出C,
  111.                                  #          输出格式为保留两位小数, 全舍)

  112.             注: 上例中 A,B,C,D,E 均为算术表达式. m,n,p为正整数.

  113.         ⑥ 字典特别说明


  114.             表达式  项  操作符
  115.             表达式  [; 格式]
  116.                      ; 输出

  117.                日期,单位,表名,标记,项号

  118.               例如:
  119.               .,1000,kyl,101,1..14;
  120.                                ↑
  121.                              1 至 14 项输出

  122.               .,1000,byb2,101,1..61=.,1000,yb2,101,1&&-,,qyb2,,1&&;
  123.                                ↑                  ↑          ↑
  124.                        byb2的  1 至 61 项     =    yb2的1 至 61 项 -  qyb2的1 至 61 项

  125.                              ;ABC 输出 ABC
  126.                              9++14;    9+10+11+12+13+14  之和输出

  127.               赋值表达式
  128.                .,1000,kyl,102,19=.,1000,kyl,102,18/17  第 19 项为第 18 项 / 第 17 项


复制代码

论坛徽章:
0
4 [报告]
发表于 2011-08-09 17:25 |只看该作者
首先 程序中 应将 字符串表达式作为第一个参数传入进行分离 ,然后使其中的变量=其后的参数吧

论坛徽章:
2
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:56:11
5 [报告]
发表于 2011-08-09 17:39 |只看该作者
变量替换比较简单。复杂的是运算符如果有优先级,则需要使用栈来实现。没有优先级则简单。

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
6 [报告]
发表于 2011-08-09 17:41 |只看该作者
本帖最后由 yulihua49 于 2011-08-09 17:54 编辑
变量替换比较简单。复杂的是运算符如果有优先级,则需要使用栈来实现。没有优先级则简单。
cobras 发表于 2011-08-09 17:39



    逆波兰表达式。
递归栈。

项号替换是回调函数。你自己定义如何取得数据。

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
7 [报告]
发表于 2011-08-09 17:57 |只看该作者
本帖最后由 yulihua49 于 2011-08-09 18:06 编辑
变量替换比较简单。复杂的是运算符如果有优先级,则需要使用栈来实现。没有优先级则简单。
cobras 发表于 2011-08-09 17:39

基本的表达式计算,不包括条件语句的处理。
  1. cat calcu.c
  2. /* @(#) calc.c 1.4 91/04/19 */
  3. #include <stdio.h>
  4. #include <ctype.h>
  5. #include <regex.h>
  6. #include <sdbc.h>

  7. #include "calc.h"

  8. struct args {
  9.         double (*getdata)(int,int,char *[CALCID]);
  10.         int argc;
  11.         char *argv[CALCID];
  12.         char argbuf[130];
  13.         char *cp;
  14. };

  15. /*double getdata(int,char,int,char[CALCID][CALCIDLEN]);*/
  16. static char * setarg(struct args *);
  17. static double cal(double,int,struct args *),F0=0.;

  18. static char Moper_src[]="^[     ]*(-{0,1}[0-9]{1,5})[+][+](-{0,1}[0-9]{1,5})";
  19. static regex_t Moper;
  20. static int regflg=0;
  21. #define MAXREG 5
  22. static regmatch_t pmatch[MAXREG];
  23. /*
  24. static char Moper[] = {
  25. 040,031,03,040,011,027,055,00,01,033,04,020,
  26. 060,071,01,05,030,02,053,030,02,053,074,00,
  27. 027,055,00,01,033,04,020,060,071,01,05,014,
  28. 00,00,064,
  29. 0};
  30. */

  31. static char *__loc1;
  32. //主要函数,getdata是取数回调函数。
  33. double calculator(str,getdata)
  34. char *str;
  35. double (*getdata)(int,int,char *[CALCID]);
  36. {
  37. struct args arg;
  38.         if(!str||*str=='#'||*str==';') return 0.;
  39.         if(!regflg) {
  40.         int ret;
  41.         char errbuf[200];
  42.                 ret=regcomp(&Moper,Moper_src,REG_EXTENDED);
  43.                 if(ret) {
  44.                         regerror(ret,&Moper,errbuf,sizeof(errbuf));
  45.                         fprintf(stderr,"%s\n",errbuf);
  46.                         return 0;
  47.                 }
  48.                 regflg=1;
  49.         }
  50.         arg.getdata=getdata;
  51.         arg.cp=str;
  52.         return(cal(0.,ADD,&arg));
  53. }
  54. //递归计算。
  55. static double cal(x,op,arg)
  56. double x;
  57. int op;
  58. register struct args *arg;
  59. {
  60. char *rp;
  61. double tmp;
  62. union {
  63.         int n;
  64.         long l;
  65.         } m;

  66.         if(!*arg->cp) return(calc(x,op,0.));
  67.         tmp=F0,m.l=0;
  68.         do {

  69.                 if(*arg->cp=='('/*)*/) {
  70.                         arg->cp++;
  71.                         tmp=cal(0.,ADD,arg);
  72.                         rp=arg->cp;
  73.                         goto oper;
  74.                 }
  75.                 setarg(arg);
  76.                 if(*arg->cp<=' ') {
  77.                         arg->cp++;
  78.                         if(!*arg->cp) x=calc(x,op,tmp);
  79.                         continue;
  80.                 }
  81.                 m.l=0;
  82.                 if(tolower(*arg->cp)=='c') {
  83.                         tmp=strtod(arg->cp+1,&rp);
  84.                         if(isdigit(*rp)) rp++;
  85.                         if(rp==arg->cp+1) {
  86.                                 arg->cp=++rp;
  87.                                 if(!*rp)  {
  88.                                         x=calc(x,op,tmp);
  89.                                         break;
  90.                                 }
  91.                                 continue;
  92.                         }
  93.                 }
  94.                 else {
  95.                 char right[7];
  96.                 char *p;
  97.                         tmp=strtod(arg->cp,&rp);
  98.                         if(rp!=arg->cp) {
  99.                                 if(isdigit(*rp)) rp++;
  100.                                 if(!arg->getdata) goto oper;
  101.                                 for(p=arg->cp;p<rp;p++) {
  102.                                         if(*p=='.' || *p=='E' || *p=='e') {
  103.                                                 goto oper;
  104.                                         }
  105.                                 }
  106.                         }
  107.                         if(!regexec(&Moper,arg->cp,MAXREG,pmatch,0)) {
  108.                         int i;

  109.                                 p=arg->cp+pmatch[0].rm_eo;
  110.                                 __loc1=arg->cp+pmatch[1].rm_so;// 线程不安全。
  111.                                 i=pmatch[2].rm_eo-pmatch[2].rm_so;
  112.                                 strncpy(right,arg->cp+pmatch[2].rm_so,i);
  113.                                 right[i]=0;

  114. /* XXXXX   1++80  
  115. fprintf(stderr,"calc:left=%s, right=%s\n",lft,right);
  116. */
  117.                            tmp=F0;
  118.                            if(isalpha(*p)) *arg->argv[0]=*p++;
  119.                            else *arg->argv[0]=0;
  120.                             m.l=atoi(right);
  121.                             for(i=atoi(__loc1);i<=m.n;i++) {
  122.                                if(arg->getdata)
  123.                                   tmp+=(*arg->getdata)(i,arg->argc,arg->argv);
  124.                                else tmp+=(double)i;
  125.                             }
  126.                             rp=p;
  127.                         }
  128.                         else {
  129.                            if(*arg->cp) m.l=strtol(arg->cp,&rp,0);
  130.                            if(isalpha(*rp)) *arg->argv[0]=*rp++;
  131.                            else *arg->argv[0]=0;
  132.                            if(arg->getdata) {
  133.                               tmp=(*arg->getdata)(m.n,arg->argc,arg->argv);
  134.                            }
  135.                            else tmp=(double)m.l;
  136.                         }
  137.                 }
  138. oper:
  139.                 if(!*rp) {
  140.                         x=calc(x,op,tmp);
  141.                         arg->cp=rp;
  142.                         break;
  143.                 }
  144.                 while(isspace(*rp)) rp++;
  145.                 switch(*rp) {
  146.                 case '+': m.n=ADD;
  147.                           rp++;
  148.                           break;
  149.                 case '-': m.n=SUBT;
  150.                           rp++;
  151.                           break;
  152.                 case '*': m.n=MUL;
  153.                           rp++;
  154.                           break;
  155.                 case '/': m.n=DIV;
  156.                           rp++;
  157.                           break;
  158.                 case '%': m.n=MOD;
  159.                           rp++;
  160.                           break;
  161. /*
  162.                 case ')':
  163. printf("op=%d,x=%f m.n=%d tmp=%f rp=%s\n",op,x,m.n,tmp,rp);
  164.                           if(*rp) rp++;
  165.                           if(x==0. && op==0) {
  166.                                 return tmp;
  167.                           }
  168.                           m.n=-1;
  169.                           break;
  170. */
  171.                 case '\n':
  172.                 case '\r':
  173.                 case ';':
  174.                 case '#': *rp=0;
  175.                 default: m.n=-1;
  176.                           if(*rp) rp++;
  177.                           break;
  178.                 }
  179.                 arg->cp=rp;

  180.                 if(m.n==-1) {
  181.                         x=calc(x,op,tmp);
  182.                         break;
  183.                 }
  184.                 else if((m.n>>2) > (op>>2)){
  185.                         tmp=cal(tmp,m.n,arg);
  186.                         rp=arg->cp;

  187.                         goto oper;
  188.                 }
  189.                 x=calc(x,op,tmp);
  190.                 if((m.n>>2) == (op>>2)) {
  191.                         op=m.n;
  192.                 }
  193.                 else  {
  194.                         arg->cp--;
  195.                         break;
  196.                 }

  197.         } while(*arg->cp);
  198.         return(x);
  199. }

  200. let(str,x,putdata)
  201. char *str;
  202. double x;
  203. int (*putdata)(int,int,char *[CALCID],double);
  204. {
  205. struct args arg;
  206. int n=0;
  207. char *p;
  208.         arg.cp=str;
  209.         setarg(&arg);
  210.         n=strtol(arg.cp,&p,0);
  211.         if(p==arg.cp) return(-1);
  212.         if(p&&isalpha(*p)) *arg.argbuf=*p;
  213.         return((*putdata)(n,arg.argc,arg.argv,x));
  214. }
  215. static char * setarg(arg)
  216. register struct args *arg;
  217. {
  218. int n;
  219. register char *rp;
  220. char *p;
  221.         arg->argc=0;
  222.         *(arg->argv[0]=arg->argbuf)=0;
  223.         for(n=1;n<CALCID;n++) {
  224.                 *(p=arg->argv[n]=arg->argv[n-1]+strlen(arg->argv[n-1])+1)=0;
  225. again:
  226.                 if((p-arg->argbuf) >= sizeof(arg->argbuf)-1)
  227.                         break;
  228.                 rp=stptok(arg->cp,p,
  229.                         sizeof(arg->argbuf)-(p-arg->argbuf),
  230.                         ",+*-/%()#;");
  231.                 if(*rp && rp[-1]=='\\') {
  232.                         p=arg->argv[n]+strlen(arg->argv[n])-1;/* del \\ */
  233.                         *p++=*rp++;
  234.                         *p=0;
  235.                         arg->cp=rp;
  236.                         goto again;
  237.                 }
  238.                 if(*rp!=',') break;
  239.                 arg->cp=rp+1,arg->argc=n;
  240.         }
  241.         return(arg->cp);
  242. }
  243. int strlet(label,str,putdata)
  244. char *label;
  245. char *str;
  246. int (*putdata)(int,int,char *[CALCID],char *str);
  247. {
  248. struct args arg;
  249. int n=0;
  250. char *p;
  251.         arg.cp=label;
  252.         setarg(&arg);
  253.         n=strtol(arg.cp,&p,0);
  254.         if(p==arg.cp) return(-1);
  255.         if(p&&isalpha(*p)) *arg.argbuf=*p;
  256.         return((*putdata)(n,arg.argc,arg.argv,str));
  257. }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP