首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >按不同顺序求值时表达式的差异

按不同顺序求值时表达式的差异
EN

Code Golf用户
提问于 2014-07-16 00:52:27
回答 1查看 523关注 0票数 3

我们都知道数学函数(PEMDAS)的标准操作顺序,但是如果我们用从左到右的表达式来计算呢?

挑战

通过标准输入或命令行args给出一个字符串,找出该表达式的传统计算(PEMDAS)和顺序(从左到右)计算之间的区别。

详细信息

  • 您将获得如下格式的字符串:"1 +2*3^2- 11 /2+ 16“
  • 为了简化事情,将有:
    • 每个数和每个运算符之间的空格
    • 无前导或尾随舱位
    • 没有十进制数或负数(只有非负整数)
    • 除+(加号)、-(减号)、*(乘)、/(除)、^(指数)外没有任何运算符
    • 没有父母需要担心
    • 如果更容易处理,您可以删除空格,但不允许对输入格式进行其他修改。

  • 必须提供字符串的两个计算值之间差额的绝对值。
  • 您的除法可以是浮点数除法,也可以是整数除法,两者都将被接受。
  • 您的程序不能使用任何类型的表达式计算库。为了澄清-任何一种内置的eval函数,在这些函数中,您的语言计算同一语言的有效代码的字符串是可以接受的。
  • 最好解释您的代码。
  • 按字节数计算最短代码获胜
  • 获胜者将於星期六(2014年7月19日)获选。

示例:

A: 1+2*3^2-11/2+ 16 (使用浮点除法)

  • 按传统操作顺序:1+2*3^2- 11 /2+ 16 ->1+2*9- 11 /2+ 16 ->1+ 18 - 5.5 + 16 -> 29.5
  • 有序遍历产率:1+2*3^2-11/2+ 16 ->3^2^2-11/2+ 16 ->9^2-11/2+ 16 ->81-11/2+ 16 -> 70 /2+ 16 -> 35 + 16 -> 51
  • 结果差异:51-29.5= 21.5

B: 7-1*3^2+ 41 /3+2*9*2(使用整数除法)

  • 按传统操作顺序:7-1*3^2+ 41 /3+2*9*2->7-1*9+ 41 /3+2*9*2->7-9+ 13 + 18 *2->7-9+ 13 + 36 -> 47
  • 有序遍历产率:7-1*3^2+ 41 /3+2*9*2->6*3^2+ 41 /3+2*9*2-> 18 ^2+ 41 /3+2*9*2-> 324 + 41 /3+2*9*2-> 365 /3+2*9*2-> 121 +2*9*2->121+2*9*2-> 123 *9*2-> 1107 *2-> 2214
  • 结果差异: 2214 - 47 = 2167
EN

回答 1

Code Golf用户

发布于 2014-07-16 07:09:35

Python208

代码语言:javascript
复制
d=x=input();z=2;u='('*(((len(x)-len(x.replace(' ','')))/2)+1);d=x=d.replace(r'^','**');x=x.split();p=u+''.join(")".join(x[i:i+z]) for i in range(0,len(x),z))+")";m=eval(p)-eval(d);m=m*-1 if 0>m else m;print m;

卡尔文的霍布斯评论:

代码语言:javascript
复制
import re;e=input().replace('^','**');print abs(eval(e)-eval(e.count(' ')/2*'('+re.sub('(\d) ',r'\1)',e)))

解释:

代码语言:javascript
复制
# variable d  =  x, and x  =  user input

d = x = input() 

# variable z = 2

z = 2

# I take the length of the string 'x' (aka the equation we're solving) with 
# *all* whitespaces removed (it's the 'len(x.replace(' ', '')...' part) and 
# subtract that from 'len(x)' which is the vanilla length of our equation
# I divide the total by two and add one for reasons I'll explain in a minute
# the '(' * part means to make a string with as many '(' as I get from multiplying
# so '(' * 5 = '(((((', '(' * 3 = '((('

u = '(' * (((len(x) - len(x.replace(' ', ''))) / 2) + 1)

# Here I replace the caret with **, because in Python ^ == **
# I also split the string by whitespaces, but only for x;

d = x = d.replace(r'^','**'); x = x.split();

# I set the variable p = to the result of joining the list (aka array) that
# I just made with the .split() in the above section first with a ')' on every
# second character (e.g. [1,2,3,4,5,6] would be 1,2),3,4),... etc. I do it like
# this because in our math equation we'll (hopefully) follow the pattern of
# num op num op num op... etc. I insert parenthases because I'm using PEMDAS
# to my advantage by grouping each set of numbers in the order I want them
# to be completed. The initial ''.join simply rejoins all elements into a
# complete string (basically removes the commas that are left over from
# converting a list -> string). I add a '(' to the end because every 2nd
# character would skip the final one

p = u + ''.join(")".join(x[i:i + z]) for i in range(0, len(x), z)) + ")"

# I eval() both p and d. eval() will run arbitrary code, so you can pass it a
# string and it will act as if the string is code, so while print '1+1' would
# usually result in TypeError (or Value? I forget), print eval('1+1') would
# print '2', I have to do them separately because eval() thinks I wanna
# subtract two string for whatever reason

m = eval(p) - eval(d)

# Here I make use of Python's ternary operators by saying this:
# if 0 > m:
#   m = m * -1
# else:
#   m
# which means that if m is negative, multiply it by -1 to make it
# a positive number so we can get the absolute value. If it's not negative
# then we can just have m and not do anything with it

m = m * -1 if 0 > m else m

# Print m :)

print m
票数 0
EN
页面原文内容由Code Golf提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codegolf.stackexchange.com/questions/34599

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档