不用eval写一个算带多层括号的四则运算数学表达式的功能

LOLimAcat-avatar

LOLimAcat

2021-09-14T14:35:15+00:00

比如2*(3+5.2/(1-6.5)),这种,不管用什么语言,只要不用eval()类似的系统函数就可以

这应该是什么学历的编程水平,初中、高中、大专、本科几年?

我写了个perl的示例,看看大家觉得这个能过关吗 scalar=python的length, 理论上可以无压力转为python代码
展开代码 ...
use strict; use warnings;
use 5.010;

# 计算带括号的四则表达式

sub say_ar{
# 打印数组
return join(',', @_);
}


sub orphan{
my @elems = @_;
# 返回单个数值
my @nums = ();
my $prefix = 1;
my $divide = 0; # 除法开关

for (my $i = 0; $i < scalar(@elems); $i++){
my $cur = $elems[$i];
if ($cur eq '+'){
push(@nums, $prefix);
$prefix = 1;
$divide = 0;
} elsif ($cur eq '-'){
push(@nums, $prefix);
$prefix = -1;
$divide = 0;
} elsif ($cur eq '*'){
$divide = 0;
} elsif ($cur eq '/'){
$divide = 1;
} else {
if ($divide == 0) {
$prefix = $prefix*$cur; # 转数值
} else {
$prefix = $prefix/$cur;
$divide = 0;
}
}
}
push(@nums, $prefix);
# say join(',', @nums);
my $sum = 0;
for (my $j = 0; $j < scalar(@nums); $j++){
$sum = $sum + $nums[$j];
}
# say 'orphan get '.say_ar(@elems).' return '.$sum;
return $sum;

}


sub scan{
my $fm = shift;
my @chars = split(//, $fm);
my @syms = ();
my $digit = 0;
my $num = 0;
my $num_editing = 0;
my @fm_curs = ();
for (my $i = 0; $i < scalar(@chars); $i++){
# say 'i = '.$i.'char = '.$chars[$i].' syms = '.say_ar(@syms);
my $cur = $chars[$i];
if ($cur eq '('){
push(@fm_curs, scalar(@syms));
$num_editing = 0;

} elsif ($cur eq ')'){
my $fm_cur = pop(@fm_curs);
# say 'fm_cur = '.$fm_cur;
my @temp_syms = ();
my $syms_len = scalar(@syms);
for (my $j = $fm_cur; $j < $syms_len; $j++){
push(@temp_syms, $syms[$j]);
}
if ($num_editing == 1){
push(@temp_syms, $num);
$num_editing = 0;
}
my $res = orphan(@temp_syms);

for (my $j = 1; $j <= ($syms_len - $fm_cur); $j++){
pop(@syms);
}
push(@syms, $res);
$num = 0;

} elsif ($cur eq '+' || $cur eq '-' || $cur eq '*' ||$cur eq '/') {
if ($num_editing == 1){
push(@syms, $num); $num = 0; $num_editing = 0;
}
$digit = 0;
push(@syms, $cur);
} elsif ($cur eq '.'){
$digit = 1;
} else {
# 数值
if ($digit == 0){
$num = $num*10+$cur;
} else {
$num = $num +0.1**$digit*$cur;
$digit++;
}
$num_editing = 1;
# say 'get num='.$num;
}

}
if ($num_editing == 1){
push(@syms, $num);
}
my $final = orphan(@syms);
return $final;
}

my @list = ('1.5', '+', '2', '*', '3');
my $ufm = '1.5+2*3';
$ufm = '2*(3+5.2/(1-6.5))';
$ufm = '(1/3+1/2)*11/20'; # 0.4583
#$ufm = '11/20';
print scan($ufm);
Mr. Grape-avatar

Mr. Grape

四则运算计算器吧?没记错的话,计算机专业大二的数据结构课会教,用栈实现的。
itzme_oli-avatar

itzme_oli

稍微了解了一点数据结构即可…感觉这种情况还用不着编译器和计算理论的知识
squtternut_bosh-avatar

squtternut_bosh

[url]https://leetcode-cn.com/problems/basic-calculator/[/url]
[url]https://leetcode-cn.com/problems/basic-calculator-ii/[/url]

中等难度,经典题[s:ac:哭笑]
angelsolis-avatar

angelsolis

转成逆波兰表达式,然后计算。说起来简单,我打赌泥潭90%程序员一小时内写不出来
Puffin-avatar

Puffin

本科前的计算机课除竞赛外一般不会教数据结构。

中缀表达式求值学会栈就能实现了,正常在本科的大一或大二会学到。
Háború-avatar

Háború

加减乘都好说
除麻烦点
angelsolis-avatar

angelsolis

[quote][pid=552271320,28624808,1]Reply[/pid] Post by [uid=60179627]wulinlw[/uid] (2021-09-22 22:52):

[url]https://leetcode-cn.com/problems/basic-calculator/[/url]
[url]https://leetcode-cn.com/problems/basic-calculator-ii/[/url]

中等难度,经典题[s:ac:哭笑][/quote]楼主这个问题比leetcode上所有的计算器题都要难,是括号+四则运算
🌹 𝕾𝖔𝖕𝖍𝖎𝖆 𝖙𝖍𝖊 2nd 🌷-avatar

🌹 𝕾𝖔𝖕𝖍𝖎𝖆 𝖙𝖍𝖊 2nd 🌷

中缀表达式转后缀表达式,数据结构没学多久就会学吧
Hectic Ren-avatar

Hectic Ren

科班出身的应该都知道怎么做,数据结构这门课有讲,虽然动手写不一定能准确写出来
没上过这门课或者没自学过数据结构的话,可能很难想到怎么做
Krw.-avatar

Krw.

前两天写了个动态分析html代码的
这个算简化版,套用一样逻辑10分钟左右吧
LOLimAcat-avatar

LOLimAcat

Reply to [pid=552272228,28624808,1]Reply[/pid] Post by [uid=60308564]ShooterMiku[/uid] (2021-09-22 22:56)

是因为除法没有交换律吗
COOM SLAYER-avatar

COOM SLAYER

至少普通程序员不刷题的话很少能现场写出来,更不用说培训班出身的。
kaivelta-avatar

kaivelta

说起来不难,写起来麻烦
Miza-avatar

Miza

学lisp的时候经典例子之一
inkie.-avatar

inkie.

antlr撸一个计算器
3BS_Reaper-avatar

3BS_Reaper

其实还是有点难度的
loadingazhd-avatar

loadingazhd

跟学历没关系,大概接触正规编程训练一年之内都会知道
LOLimAcat-avatar

LOLimAcat

写了一个代码,大家可以批评一下
LOLimAcat-avatar

LOLimAcat

顶贴zsbd