- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
嘿编码器,
我有一个字符串“1+1”,在函数 eval() 中使用 javascript 构建我可以执行 eval("1+1") 所以返回值将是 2
但是如果我想在 javascript 中将这个概念实现到递归函数呢?
function evaluate(str) {
}
evaluate("1+1");
evaluate("1-1");
evaluate("1*1");
evaluate("1/1");
function evaluate(str) {
if (str.length === 0) {
return "";
}else{
let angka;
let symbol;
for (let i = 0; i < str.length; i++) {
if (isNaN(str[i])) {
symbol = str[i];
break;
}else{
angka = str[i];
}
}
switch (symbol) {
case "+":
return angka + evaluate(str.slice(1));
case "-":
return angka - evaluate(str.slice(1));
case "/":
return angka / evaluate(str.slice(1));
case "*":
return angka * evaluate(str.slice(1));
default:
return parseInt(str[0]) + evaluate(str.slice(1));
}
}
}
function evaluate(str) {
if (str.length === 0) {
return ""
}
let numbers = "";
let operator = "";
let lastIndex = 0;
for (let i = 0; i <= str.length; i++) {
if (!isNaN(parseInt(str[i]))) {
numbers += parseInt(str[i]);
}else{
operator = str[i];
lastIndex = i;
break;
}
}
// console.log(numbers, " " , operator , " " , lastIndex);
lastIndex = lastIndex < 1 ? 1 : lastIndex;
if (operator === "+") {
return numbers + evaluate(str.slice(lastIndex));
}
}
function evaluate(str) {
if (str.length === 0) {
return 1;
}else{
let numbers = "";
for (let i = 0; i <= str.length; i++) {
if(parseInt(str[i]) >= 0){
numbers = numbers + "+" + str[i];
}else{
let lengthNumbers = numbers.length > 1 ? numbers.length : 1;
let tempNumbers = numbers;
numbers = "";
return tempNumbers + evaluate(str.slice(lengthNumbers))
}
}
}
}
function evaluate(str) {
if(str.match(/[*/+-]/)){
let numbers = "";
for (let i = 0; i < str.length; i++) {
switch (str[i]) {
case "+":
return parseInt(numbers) + evaluate(str.slice(numbers.length+1))
case "*":
return parseInt(numbers) * evaluate(str.slice(numbers.length+1))
case "/":
return parseInt(numbers) / evaluate(str.slice(numbers.length+1))
case "-":
return parseInt(numbers) - evaluate(str.slice(numbers.length+1))
default:
numbers += str[i];
break;
}
}
}else{
return parseInt(str[0]);
}
}
console.log(evaluate('1+2+3+4+5')) // 15
console.log(evaluate('1*2*3*4*5')) // 120
console.log(evaluate('20/4')) // 5
console.log(evaluate('20-6')) // 14
最佳答案
另一种方法是将您的字符串转换为一个可以作为堆栈求值的数组,然后对该堆栈进行简单的求值。例如,我们可以制作 "10 - 20 + 30 * 2 / 10"
进入 [10, 20, "-", 30, "+", 2, "*", 10, "/"]
然后通过将堆栈的顶部两个元素依次替换为应用于它们的当前操作的值来评估它。
此技术仅适用于从左到右的操作。它忽略运算符优先级,不能处理括号或非二元运算。但它可能足以满足您的需求。
这是一个实现:
const evalExpr = (ops) => (expr) => expr
.replace (/([-+*\/])(\s)*(\d+)/g, (_, a, b, c) => c + b + a)
.split (/\s+/)
.map (n => Number(n) || n)
.reduce (
(stack, symbol, _, __, op = ops[symbol]) => op
? [... stack.slice(0, -2), op(...stack.slice(-2))]
: [... stack, symbol]
, []
) [0];
const ops = {
'+': (a, b) => a + b,
'-': (a, b) => a - b,
'*': (a, b) => a * b,
'/': (a, b) => a / b,
};
const evalNumericExpr = evalExpr (ops);
// Test
[
"1 + 1",
"1 - 1",
"1 * 1",
"1 / 1",
"2 + 4 + 7",
"5 - 7",
"5 * 2 + 10",
"10 - 20 + 30 * 2 / 10",
"1 + 5 * 2 + 12 * 2 * 2",
"10 + 13 - 5 * 3 + 12 / 3 + 3"
]
.forEach (expr => console .log (`${expr} ==> ${evalNumericExpr (expr)}`))
replace
,
split
, 和
map
步骤一起将这个字符串变成一个准备处理的堆栈。
reduce
step 实际上处理该数组,在堆栈上添加和删除元素。与
"10 - 20 + 30 * 2 / 10"
成为
[10, 20, "-", 30, "+", 2, "*", 10, "/"]
,减少将如下进行:
stack: [], next: 10 // Push 10 onto the stack
stack: [10], next: 20 // Push 20 onto the stack
stack: [10, 20], next: '-' // Pop 10 and 20 from the stack. Push (10 - 20) to it
stack: [-10], next: 30 // Push 30 to the stack
stack: [-10, 30], next: '+' // Pop -10 and 30 from the stack. Push (-10 + 30) to it
stack: [20], next: 2 // Push 2 to the stack
stack: [20, 2], next: '*' // Pop 20 and 2 from the stack. Push (20 * 2) to it
stack: [40], next: 10 // Push 10 to the stack
stack: [40, 10], next: '/' // Pop 40 and 10 from the stack. Push (40 / 10) to it
stack: [4] // For a well-formed expression, the stack now has just
// one element on it, and that's your result.
-2
来向缩减添加其他元操作(尽管将字符串转换为堆栈格式会更棘手)。与
-op.length
一起减少.如果我们想处理十进制数,我们可以将正则表达式更改为类似
/([-+*\/])(\s)*(\-?\d+(:?\.\d+)?)/g
的内容。 .
// Does not test for well-formedness. Will likely return NaN for
// ill-formed expression strings
const evalNumericExpr = (
expr,
[regex, fn, ops] = [
// parentheses
[/\(([^())]*)\)/, (ops, expr, regex) => evalNumericExpr (expr.replace(regex, (_, e) => evalNumericExpr(e))), {}],
// multiplication and division
[/\s*(\-?\d+)\s*([/*])\s*(\-?\d+)/, (ops, expr, regex) => evalNumericExpr (expr .replace (
regex,
(_, a, op, b) => String(ops[op](Number(a), Number(b)))
)), {'*': (a, b) => a * b, '/': (a, b) => a / b}],
// addition and subtraction
[/\s*(\-?\d+)\s*([+-])\s*(\-?\d+)/, (ops, expr, regex) => evalNumericExpr (expr .replace (
regex,
(_, a, op, b) => String(ops[op](Number(a), Number(b)))
)), {'+': (a, b) => a + b, '-': (a, b) => a - b}],
// everything else
[/.?/, (ops, expr, regex) => Number(expr.trim()), {}]
].find(([regex, fn, ops]) => regex.test(expr))
) => fn(ops, expr, regex)
// Test
; [
"1 + 5",
"7 - 2",
"3 * 5",
"21 / 3",
"2 + 4 + 7",
"5 - 7",
"5 * 2 + 10",
"5 * 2 + (3 * 5)",
"10 - 20 + 30 * 2 / 10",
"10 - ((4 * 5) - (5 * 6)) * 2 / 10",
"10 - ((4 * (2 + 3)) - (5 * 6)) * 2 / 10",
"1 + 5 * 2 + 12 * 2 * 2",
"10 + 13 - 5 * 3 + 12 / 3 + 3"
].forEach (expr => console .log (`${expr} ==> ${evalNumericExpr (expr)}`))
const evalNumericExpr = (() => {
const ops = [
[ // grouping
/\(([^()]+)\)/,
(evaluator, subexpr) => evaluator(subexpr)
], [ //exponentiation
/([-+]?\d+)\s*[\^]\s*([-+]?\d+)([^\^]*)$/,
(_, base, exp, rest) => `${base ** exp}${rest}`
], [ // multiplication, divide, remainder
/([-+]?\d+)\s*([*%\/])\s*([-+]?\d+)/,
((ops) => ((_, a, op, b) => ops [op] (Number (a), Number (b))))(
{'*': (a, b) => a * b, '/': (a, b) => a / b, '%': (a, b) => a % b}
)
], [ // addition, subtraction
/([-+]?\d+)\s*([+-])\s*([-+]?\d+)/,
((ops) => ((_, a, op, b) => ops [op] (Number (a), Number (b))))(
{'+': (a, b) => a + b, '-': (a, b) => a - b}
)
]
]
const evaluator = (expr) => Number(ops .reduce(
(expr, [regex, fn]) => regex .test (expr)
? evaluator(expr .replace (regex, (...args) => fn (evaluator, ...args .slice (1))))
: expr,
expr
))
return evaluator
})()
// Test
; [
"1 + 3",
"7 - 2",
"2 * 6",
"12 / 4",
"2 + 4 + 7",
"5 * 2 + 10",
"10 - 20 + 30 * 2 / 10",
"1 + 5 * 2 + 12 * 2 * 2",
"10 + 13 - 5 * 3 + 12 / 3 + 3",
"10 + (13 - 5) * 3 + 12 / 3 + 3",
"5 * (4 + (2 * (1 + 1 + 1)))",
"5 ^ 2",
"5 ^ 2 * 2",
"2 ^ 3 ^ 2", // Note: should parse as `2 ^ (3 ^ 2)`, not `(2 ^ 3) ^ 2`
"2 ^ 3 ^ 2 + 3 ^ 3 * 2",
]
.forEach (expr => console .log (`${expr} ==> ${evalNumericExpr (expr)}`))
replace
的函数相关联来工作。与该正则表达式一起回调。每个这样的对都会重复运行,直到输入中不再有匹配项。
^
) 用于求幂运算符;如果愿意,更改为双星号 (
**
) 应该很容易。
2 ^ 3 ^ (4 ^ 2 - 5 * 3 + 1) - (((2 + 2) * (2 * 5) ^ 2) + (2 * 5 * 7))
4 ^ 2 - 5 * 3 + 1 // grouping
16 - 5 * 3 + 1 // exponentiation
16 - 15 + 1 // multiplication
1 + 1 // subtraction
2 // addition
2 ^ 3 ^ 2 - (((2 + 2) * (2 * 5) ^ 2) + (2 * 5 * 7))
2 + 2 // grouping
4 // addition
2 ^ 3 ^ 2 - (( 4 * (2 * 5) ^ 2) + (2 * 5 * 7))
2 * 5 // grouping
10 // multiplication
2 ^ 3 ^ 2 - (( 4 * 10 ^ 2) + (2 * 5 * 7))
4 * 10 ^ 2 // grouping
4 * 100 // exponentiation
400 // multiplication
2 ^ 3 ^ 2 - ( 400 + (2 * 5 * 7))
2 * 5 * 7 // grouping
10 * 7 // multiplication
70 // multiplication
2 ^ 3 ^ 2 - ( 400 + 70)
400 + 70 // grouping
470 // addition
2 ^ 3 ^ 2 - 470
2 ^ 9 - 470 // expoentiation
512 - 470 // exponentiation
42 // subtraction
关于javascript - 使用递归函数解决了 : How to implement build in function . eval(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59325015/
main.cpp #include "Primes.h" #include int main(){ std::string choose; int num1, num2; w
似乎函数 qwertyInches() 应该可以工作但是当我在 main() 中调用它时它给了我 [Error] called object 'qwertyInches' is not a funct
我无法理解 C++ 语法的工作原理。 #include using namespace std; class Accumulator{ private: int value; public:
在 类中声明 函数成员时,我们可以同时执行这两种操作; Function first; Function() second; 它们之间有什么区别? 最佳答案 Function 代表任意函数: void
“colonna”怎么可能是一个简单的字符串: $('td.' + colonna).css('background-color','#ffddaa'); 可以正确突出显示有趣单元格的背景,并且: $
我正在尝试将网页中的动态参数中继到函数中,然后函数将它们传递给函数内部的调用。比如下面这个简化的代码片段,现在这样,直接传入参数是没有问题的。但是,如何在不为每个可能的 colorbox 参数设置 s
C++ 中是否有一种模式允许您返回一个函数,它返回一个函数本身。例如 std::function func = ...; do { func = func(); } while (func);
我正在将 Windows 程序集移植到 Linux。我有一些代码要移植。我实际上是 linux 中 C 的新手。我知道 C 基础知识是一样的! typedef struct sReader {
我一直在寻找一个很好的解释,所以我很清楚。示例: this.onDeleteHandler(index)}/> 对比 对比 this.nameChangedhandler(event, perso
function(){}.__proto__ === Function.prototype 和 Function.prototype === function(){}.__proto__ 得到不同的结
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function 据说 Propert
VBA 中的函数没有特殊类型。我很难理解如何在 Excel VBA 中将函数作为参数添加到函数中。 我想要完成的是这样的事情: function f(g as function, x as strin
所以我正在尝试制作一个包(我没有在下面包含我的 roxygen2 header ): 我有这个功能: date_from_text % dplyr::mutate(!!name := lubr
尝试从 std::function 派生一个类,对于初学者来说,继承构造函数。这是我的猜测: #include #include using namespace std; template cla
我正在尝试编写一个返回另一个函数的函数。我的目标是编写一个函数,它接受一个对象并返回另一个函数“search”。当我使用键调用搜索函数时,我想从第一个函数中给定的对象返回该键的值。 propertyO
我非常清楚函数式编程技术和命令式编程技术之间的区别。但是现在有一种普遍的趋势是谈论“函数式语言”,这确实让我感到困惑。 当然,像 Haskell 这样的一些语言比 C 等其他语言更欢迎函数式编程。但即
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 8 年前。 Improv
我在stackoverflow上查过很多类似的问题,比如call.call 1 , call.call 2 ,但我是新人,无法发表任何评论。我希望我能找到关于 JavaScript 解释器如何执行这些
向 Twilio 发送 SMS 时,Twilio 会向指定的 URL 发送多个请求,以通过 Webhook 提供该 SMS 传送的状态。我想让这个回调异步,所以我开发了一个 Cloud Functio
作为 IaC 的一部分,A 功能应用 ,让我们将其命名为 FuncAppX 是使用 Terraform 部署的,它有一个内置函数。 我需要使用 Terraform 在函数应用程序中访问相同函数的 Ur
我是一名优秀的程序员,十分优秀!