- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
背景:在传统的逆波兰表示法中,所有运算符都必须具有固定长度,这使得 RPN 可以很容易地被代码评估和操作,因为每个标记、表达式和子表达式都是“自包含”的,以至于人们可以盲目地替换 y
在 x y *
为 y 1 +
获取 x y 1 + *
, 这是另一个有效的表达式,它完全符合您的要求。这是一个带有命名变量支持的简单 RPN 计算器的交互式演示。请注意,演示试图展示算法的要点;它们与生产代码无关或不代表生产代码。
var rpn = prompt("Please enter RPN string, where each token is " +
"separated by a space", "x 1 x + * 2 /").trim().split(/\s+/);
var stack = [], variables = [], values = [];
for (let i = 0, len = rpn.length|0; i < len; i=i+1|0) {
if (/^\d*(\.\d*)?$/.test(rpn[i]) && rpn[i] !== "") {
stack.push( rpn[i] );
} else if (/^[a-z]$/i.test(rpn[i])) {
stack.push( rpn[i] );
if (!~variables.indexOf(rpn[i])) variables.push( rpn[i] );
} else {
if(stack.length<2)throw Error("No operand for " + rpn[i]);
const firstPop = stack.pop(); //lacks check if stack empty
stack.push( "(" + stack.pop() + rpn[i] + firstPop + ")" );
}
}
if (stack.length !== 1) throw Error("Invalid RPN got: " + stack);
for (let i = 0, len = variables.sort().length|0; i < len; i=i+1|0)
values[i] = +prompt(variables[i] + " = ", Math.random()*10|0);
variables.push("'use strict';return(" + stack.pop() + ")");
alert("Result: " + Function.apply(0, variables).apply(0, values));
#
来解决这个问题)。该解决方案与传统 RPN 背道而驰,因为它添加了前缀运算符来表示参数开始的位置。这使得参数列表的大小自动扩展,并有助于调试,因为格式错误的标记替换不会破坏参数列表,从而更容易定位错误。由于需要更多代码来处理嵌套函数调用等情况,这可能会使参数的操作变得更加复杂,但我不完全确定可能会出现什么复杂情况。我猜我会遇到解析包含前缀和后缀运算符的语法的障碍。它还使直接评估更加困难,因为需要回溯或单独的堆栈来定位参数的开头。 var rpn = prompt("Please enter a RPN string, where each token is " +
"separated by a space", "# # x 210 gcd x 6 * 126 gcd").trim()
.split(/\s+/);
var stack = [], variables = [], values = [];
for (let i = 0, len = rpn.length|0; i < len; i=i+1|0) {
if (/^\d*(\.\d*)?$/.test(rpn[i]) && rpn[i] !== "") {
stack.push( rpn[i] );
} else if (/^[a-z]$/i.test(rpn[i])) {
stack.push( rpn[i] );
if (!~variables.indexOf(rpn[i])) variables.push( rpn[i] );
} else if (/^[a-z]\w*$/i.test(rpn[i])) {
const s = stack.lastIndexOf("#");
if(s<0) throw Error("No start of arguments to " + rpn[i]);
stack.push( rpn[i]+"(" + stack.splice(s).slice(1) + ")" );
} else if (rpn[i] === '#') {
stack.push( '#' ); // sparks a syntax error if misused
} else {
if(stack.length<2)throw Error("No operand for " + rpn[i]);
const firstPop = stack.pop();
stack.push( "(" + stack.pop() + rpn[i] + firstPop + ")" );
}
}
if (stack.length !== 1) throw Error("Invalid RPN got: " + stack);
for (let i = 0, len = variables.sort().length|0; i < len; i=i+1|0)
values[i] = +prompt(variables[i] + " = ", Math.random()*10|0);
variables.push( "gcd" );
values.push( function gcd(a, b) {return b ? gcd(b, a % b) : a;} );
variables.push("'use strict';return(" + stack.pop() + ")");
alert("Result: " + Function.apply(0, variables).apply(0, values));
,
对最后两个项目进行分组,并使用 ~
来表示这个问题的零长度组)。该解决方案是传统的 RPN,只是对逗号和零组运算符的处理稍有特殊。每个变长运算符都被视为长度为 1(零参数用 ~
表示)。逗号从两个项目中构建参数列表,每个项目都可以是普通标记、参数列表或零组运算符。优点包括易于操作和解析代码,符合 RPN 的简单性,以及保留 RPN 的 token 独立性。缺点包括 RPN 更难调试,因为一个微小的畸形 token 可能会扰乱整个参数列表并且滚雪球失控,无法检测它是故意的还是偶然的。 var rpn = prompt("Please enter RPN string, where each token is " +
"separated by a space", "x 6 * 126 , 210 , gcd ~ PI %")
.trim().split(/\s+/);
var stack = [], variables = [], values = [];
for (let i = 0, len = rpn.length|0; i < len; i=i+1|0) {
if (/^\d*(\.\d*)?$/.test(rpn[i]) && rpn[i] !== "") {
stack.push( rpn[i] );
} else if (/^[a-z]$/i.test(rpn[i])) {
stack.push( rpn[i] );
if (!~variables.indexOf(rpn[i])) variables.push( rpn[i] );
} else if (/^[a-z]\w*$/i.test(rpn[i])) {
if(stack.length<1)throw Error("No operand for " + rpn[i]);
stack.push( rpn[i] + "(" + stack.pop() + ")" );
} else if (rpn[i] === ',') {
if(stack.length<2)throw Error("No operand for " + rpn[i]);
const p2 = "" + stack.pop(), p1 = "" + stack.pop();
stack.push( p1 && p2 ? p1 + "," + p2 : p1 || p2 );
} else if (rpn[i] === '~') {
stack.push( "" ); // zero-length group
} else {
if(stack.length<2)throw Error("No operand for " + rpn[i]);
const firstPop = stack.pop(); //lacks check if stack empty
stack.push( "(" + stack.pop() + rpn[i] + firstPop + ")" );
}
}
if (stack.length !== 1) throw Error("Invalid RPN got: " + stack);
for (let i = 0, len = variables.sort().length|0; i < len; i=i+1|0)
values[i] = +prompt(variables[i] + " = ", Math.random()*10|0);
variables.push( "gcd", "PI" );
values.push( function gcd(a, b) {return b ? gcd(b, a % b) : a;} );
values.push( function PI() {return Math.PI;} );
variables.push("'use strict';return(" + stack.pop() + ")");
alert("Result: " + Function.apply(0, variables).apply(0, values));
var rpn = prompt("Please enter RPN string, where each token is " +
"separated by a space", "x 210 gcd2 x 6 * 126 gcd3").trim()
.split(/\s+/);
var stack = [], variables = [], values = [];
for (let i = 0, len = rpn.length|0, m; i < len; i=i+1|0) {
if (/^\d*(\.\d*)?$/.test(rpn[i]) && rpn[i] !== "") {
stack.push( rpn[i] );
} else if (/^[a-z]$/i.test(rpn[i])) {
stack.push( rpn[i] );
if (!~variables.indexOf(rpn[i])) variables.push( rpn[i] );
} else if (m = rpn[i].match(/^([a-z]+)(\d+)$/i)) {
if(stack.length<m[2])throw Error("No operand for "+rpn[i]);
stack.push( m[1] + "(" + stack.splice(-m[2]) + ")" );
} else {
if(stack.length<2)throw Error("No operand for " + rpn[i]);
const firstPop = stack.pop(); //lacks check if stack empty
stack.push( "(" + stack.pop() + rpn[i] + firstPop + ")" );
}
}
if (stack.length !== 1) throw Error("Invalid RPN got: " + stack);
for (let i = 0, len = variables.sort().length|0; i < len; i=i+1|0)
values[i] = +prompt(variables[i] + " = ", Math.random()*10|0);
variables.push( "gcd" );
values.push( function gcd(a, b) {return b ? gcd(b, a % b) : a;} );
variables.push("'use strict';return(" + stack.pop() + ")");
alert("Result: " + Function.apply(0, variables).apply(0, values));
最佳答案
我认为您已经涵盖了这些选项:如果您必须能够传递可变长度的参数列表,那么您的语言需要具有 native 数据结构,允许整个列表成为堆栈上的单个值(即#4 中的嵌套列表,或 #2 中的它们的模拟,其中列表表示为字符串,以逗号分隔,并且不能包含其他列表),否则列表元素必须是堆栈上的单独值。在这种情况下,可变长度必须由标记(如#1)或长度字段(如#3)确定。这似乎很详尽。
至于优缺点:
,
运算符可以创建一个 2 项列表,将一个项附加或前置到列表中,或者连接两个列表,具体取决于上下文)并且列表是不是一流的对象,因为列表不能包含列表。 [1 2 3].
通过使用
[
打开一个新堆栈来创建一个序列运算符,将文字值 1、2 和 3 推送到这个新堆栈,然后使用
].
关闭新堆栈运算符,它还将对新堆栈的引用推送到先前的当前堆栈上。这服从连接属性,因为例如,如果函数
three_and_close
被定义为做
3 ].
然后是代码
[1 2 three_and_close
具有与原始代码相同的行为;所以分解出部分代码仍然像在标准 RPN 中一样容易。
关于algorithm - 逆波兰表示法中的变长运算符(后缀),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65400013/
要在 R 中绘制正态分布曲线,我们可以使用: (x = seq(-4,4, length=100)) y = dnorm(x) plot(x, y) 如 dnorm将 y 计算为 x 的函数,R 是否
@XmlTransient 阻止将 JavaBeans 属性映射到 XML 表示。是否存在与此相反的情况,这意味着即使 WebService 未使用的方法也会被映射?如果这不可能,是否存在解决方法?
我有以下键数组: var keys = [{userId: "333"}, {userId: "334"}] 这个对象数组: var users = [ {id: "333", firstName:
我正在寻找将字符串转换为类型的通用方法。 例如: class SomeThing { public void Add(T value) { //... } pub
我看到了this question , 并弹出这个想法。 有没有一种在 PHP 中执行此操作的有效方法? 编辑 有演示最好吗? 最佳答案 你可以使用 pear 包 Math_Matrix为此。 关于矩
如何在 python 中求逆矩阵?我自己实现了它,但它是纯 python,我怀疑那里有更快的模块可以做到这一点。 最佳答案 你应该看看 numpy如果您进行矩阵操作。这是一个主要用C语言编写的模块,比
是否有比使用 IF ELSE 构造更简单的方法来反转 bool 值? 通常我会使用! bool 值前面。但这在 Navision 中不起作用 最佳答案 您可以使用 NOT 关键字代替 !。 关于nav
假设我有一个对象响应。现在我想检查一个 bool 变量,success,在 Response 下并做一个早期返回是 response 不成功。 if(response == null || !resp
任何人都可以提供/引用多维行主要顺序的“索引->偏移”*转换的倒数。此外,(伪)代码将不胜感激。 http://en.wikipedia.org/wiki/Row-major_order 举个例子,简
我有一个看起来像这样的系统: z1 = 5*x1 + x2*cos(x3) z2 = x1*sin(x3) + 3*x2 z3 = 3*x1 - 2*x2 这是微分方程组的变换(只是为了提供一些背景信
我正在使用org.apache.commons.math3.transform类FastFourierTransformer,我现在尝试在真实数据集上应用FFT,并应用逆FFT来获取原始数据集。我的问
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 关闭 9 年前。 Improve
背景 我需要使用已知的累积分布函数 (CDF) 从相当复杂的概率密度函数 (PDF) 中随机采样,并且我正在尝试使用 inverse transform sampling 。这应该很容易做到,因为我有
是否有任何 System.identityHashCode (object) 的逆函数能够从 System.identityHashCode (object) 的结果中提供对象的值? 最佳答案 Sys
有没有办法在mysql中获取group by语句的逆?我的用例是删除所有重复项。 假设我的表格如下所示: ID | columnA | ... 1 | A 2 | A 3 | A 4
我有一个查询,它给我一个公司列表(tblprov)及其相应的类别(tblrubro) 两个表通过查找表 (tblprovxrubro) 相关 SELECT p.id, p.name, r.idCat,
我有一个 jpg 图像,在矩形中有一个圆形物体,我想使圆形物体的环境透明... (本例去除红色区域) 借助这个iOS make part of an UIImage transparent和“UIBe
我想知道是否可以在不需要临时数组的情况下通过 Cholesky 分解获得矩阵的逆。截至目前,我可以在不使用临时数组的情况下进行 cholesky 分解,但从那里我还没有想出一种方法来获得原始矩阵的逆矩
是否可以在 Angular 中使用逆$watch? 我的问题 我使用 Angular-translate,并且我想对每个缺少的翻译使用 $http.put 。但我收到此错误: "10 $digets(
我正在执行 radix-2 dif 逆 fft。我正在使用共轭和缩放的属性来返回结果。我共轭我的输入 vector ,执行常规 radix-2 fft(不是 ifft),共轭结果,然后按 1.0/N
我是一名优秀的程序员,十分优秀!