免费注册 查看新帖 |

Chinaunix

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

优先级和结合性的算法 [复制链接]

求职 : 软件工程师
论坛徽章:
3
程序设计版块每日发帖之星
日期:2015-10-07 06:20:00程序设计版块每日发帖之星
日期:2015-12-13 06:20:00程序设计版块每日发帖之星
日期:2016-05-05 06:20:00
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2016-10-15 19:55 |只看该作者 |倒序浏览
30可用积分
我以前感觉这个算法没什么用,现在想来,这个算法在语法树分析中,是非常必要的一种算法:

有若干个操作符,例如 +,  *, ^, 这三个操作符的优先级不同,结合性也不同,^ 是左结合的,而 +, * 则是右结合,当然左结合也行。现在悬赏算法,如果采纳的话,赠送 5000 积分,如果算法优秀,我相信会有人打赏的。


  1. a + b * c ^ d => (a + (b * (c ^ d))
复制代码


最佳答案

查看完整内容

my brick.plop:1+2+3+4+5 =>((((1 + 2) + 3) + 4) + 5)----------------------------------------------------------------1*2*3*4 * 5 + 6-7 /8 =>((((((1 * 2) * 3) * 4) * 5) + 6) - (7 / )----------------------------------------------------------------1^2~3*4-5 =>(((1 ^ (2 ~ 3)) * 4) - 5)----------------------------------------------------------------1/2/3/4/5*6*7^8^9-10-11*12 =>((((((((1 / 2) / 3) / 4 ...

论坛徽章:
7
戌狗
日期:2013-12-15 20:43:38技术图书徽章
日期:2014-03-05 01:33:12技术图书徽章
日期:2014-03-15 20:31:17未羊
日期:2014-03-25 23:48:20丑牛
日期:2014-04-07 22:37:44巳蛇
日期:2014-04-11 21:58:0915-16赛季CBA联赛之青岛
日期:2016-03-17 20:36:13
2 [报告]
发表于 2016-10-15 19:55 |只看该作者
my brick.pl

  1. #/usr/bin/perl
  2. use 5.024;

  3. my @op = qw[ + - * / ^ ~ ];
  4. my @preass = ( [ 0, 0 ], [ 0, 0 ], [ 1, 0 ], [ 1, 0 ], [ 2, 1 ], [ 3, 1 ] );
  5. my ( @it, @ass );
  6. sub that;

  7. for my $i ( 0 .. $#op ) {
  8.     $it[ $preass[$i][0] ] .= "\\$op[$i]";
  9.     $ass[ $preass[$i][0] ] //= $preass[$i][1];
  10. }

  11. @it = map qr/\s*([$_])\s*/, @it;

  12. sub that {
  13.     my ( $equ, $i ) = @_;
  14.     return @$equ if $i > $#it;
  15.    
  16.     state $at   = [ 0, -3 ];
  17.     state $join = [ [ 0 .. 2 ], [ -3 .. -1 ] ];
  18.     local $|    = 1;
  19.    
  20.     my @one = map $|-- ? that [ split $it[$i] ], $i + 1 : $_, @$equ;
  21.     my $ass = $ass[ $i - 1 ];
  22.     my $pos = $at->[$ass];
  23.     my $dit = $join->[$ass];

  24.     splice @one, $pos, 3, "(@one[@$dit])" until @one == 1;
  25.     @one;
  26. }

  27. sub this { that [shift], 0 }

  28. while (<DATA>) {
  29.     chomp;
  30.     say $_, ' =>';
  31.     say this $_;
  32.     say '-' x 64;
  33. }

  34. __DATA__
  35. 1+2+3+4+5
  36. 1*2*3*4 * 5 + 6-7   /8
  37. 1^2~3*4-5
  38. 1/2/3/4/5*6*7^8^9-10-11*12
  39. a + b * c ^ d + e - f * g / h ^ i ~ j
  40. 3 ^ 4 ^ 5 ^ 6 - 7 / 8 + 9 ^ 10 ^ 11 * 12
  41. 1 + 2 + 3 - 4 - 5 * 6 * 7 / 8 / 9 ^ 10 ^ 11 ~ 12 ~ 13 - 14
  42. 1 - 2 ^ 3 ^ 4 + 5 * 6 / 7
复制代码

op:
1+2+3+4+5 =>
((((1 + 2) + 3) + 4) + 5)
----------------------------------------------------------------
1*2*3*4 * 5 + 6-7   /8 =>
((((((1 * 2) * 3) * 4) * 5) + 6) - (7 / )
----------------------------------------------------------------
1^2~3*4-5 =>
(((1 ^ (2 ~ 3)) * 4) - 5)
----------------------------------------------------------------
1/2/3/4/5*6*7^8^9-10-11*12 =>
((((((((1 / 2) / 3) / 4) / 5) * 6) * (7 ^ (8 ^ 9))) - 10) - (11 * 12))
----------------------------------------------------------------
a + b * c ^ d + e - f * g / h ^ i ~ j =>
(((a + (b * (c ^ d))) + e) - ((f * g) / (h ^ (i ~ j))))
----------------------------------------------------------------
3 ^ 4 ^ 5 ^ 6 - 7 / 8 + 9 ^ 10 ^ 11 * 12 =>
(((3 ^ (4 ^ (5 ^ 6))) - (7 / ) + ((9 ^ (10 ^ 11)) * 12))
----------------------------------------------------------------
1 + 2 + 3 - 4 - 5 * 6 * 7 / 8 / 9 ^ 10 ^ 11 ~ 12 ~ 13 - 14 =>
(((((1 + 2) + 3) - 4) - ((((5 * 6) * 7) / / (9 ^ (10 ^ (11 ~ (12 ~ 13)))))) - 14)
----------------------------------------------------------------
1 - 2 ^ 3 ^ 4 + 5 * 6 / 7 =>
((1 - (2 ^ (3 ^ 4))) + ((5 * 6) / 7))
----------------------------------------------------------------

评分

参与人数 2信誉积分 +20 收起 理由
sunzhiguolu + 10 学习, 膜拜!!!
hztj2005 + 10 很给力!

查看全部评分

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
3 [报告]
发表于 2016-10-16 01:31 |只看该作者
不懂, 帮顶

求职 : 软件工程师
论坛徽章:
3
程序设计版块每日发帖之星
日期:2015-10-07 06:20:00程序设计版块每日发帖之星
日期:2015-12-13 06:20:00程序设计版块每日发帖之星
日期:2016-05-05 06:20:00
4 [报告]
发表于 2016-10-16 03:38 |只看该作者
看样要抛砖引玉了。

这是一个利用模块的实现:

https://github.com/ingydotnet/pe ... ial/Calculator.swim

  1. Consider the equation:

  2.   1 - 2 ^ 3 ^ 4 + 5 * 6 / 7

  3. Normal precedence and associativity rules make this the same as:

  4.   (1 - (2 ^ (3 ^ 4)) + ((5 * 6) / 7))
复制代码
  1. {
  2.       package Calculator;
  3.       use base 'Pegex::Tree', 'Precedence';

  4.       my $operator_precedence_table = {
  5.           '+' => {p => 1, a => 'l'},
  6.           '-' => {p => 1, a => 'l'},
  7.           '*' => {p => 2, a => 'l'},
  8.           '/' => {p => 2, a => 'l'},
  9.           '^' => {p => 3, a => 'r'},
  10.       };

  11.       sub got_expr {
  12.           my ($self, $expr) = @_;
  13.           $self->precedence_rpn($expr, $operator_precedence_table);
  14.       }
  15.   }
复制代码

论坛徽章:
0
5 [报告]
发表于 2016-10-16 20:10 |只看该作者
前几年看过龙书的大部分内容,但很久不用,印象就模糊了。

如果楼主懂c,可以看Kenneth C.Louden 《编译原理及实践》,此书有一个C语言实现的完整代码,看懂之后改写成Perl,是比较可行的方法。

要想完全独立用perl的实现,即使这么简单的问题,可能要折腾好几天乃至更久的时间。

可以分解问题,先不考虑结合性,只考虑优先级。

实现中,有这种问题: 4+6^(3+2)-5,就是操作数不是一个单纯的数字,而是一个表达式(3+2),需要递归实现。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP