- bounty将在7天后过期**。此问题的答案可获得+200声望奖励。stackdeveloper希望奖励现有答案:非常感谢@Matt Timmermans,我想奖励你更多
我正在寻找一个函数,它可以转换一个作为参数传递的数学字符串(使用操作+
,-
,/
,*
),以有序/更好的方式返回一个包含数学字符串片段的对象,这样更容易遍历。
输入特性:
- 是包含公式的字符串
- 这个公式没有
=
,所以它不是一个方程 - 没有浮点数只有整数
- 整数可以是正的或负的
- 没有像x y z这样的变量
- 可以包含括号
测试用例
示例1:基础数学(相同操作)
| 数量|输入(字符串)|输出(对象)|
| - ------| - ------| - ------|
| 1个|1个|{ values: [1], operation: null }
|
| 第二章|一加一|{ values: [1,1], operation: "+" }
|
| 三个|1 + 2 + 3| { values: [1,2,3], operation: "+" }
|
| 四个|三、二、一|{ values: [3,2,1], operation: "-" }
|
| 五个|10 * 80| { values: [10,80], operation: "*" }
|
| 六个|100/10| x1米10英寸1x|
示例2:2次运算公式
➡️ + and - samples
N1
输入:1+1-1
输出:
{
values: [
{
values: [1, 1],
operation: "+",
},
1,
],
operation: "-",
};
氮气
输入:3+2-1+5
输出:
{
values: [
{
values: [
{
values: [3, 2],
operation: "+",
},
1,
],
operation: "-",
},
5,
],
operation: "+",
};
N3
输入:3+2-1+5+10+7
输出:
{
values: [
{
values: [
{
values: [3, 2],
operation: "+",
},
1,
],
operation: "-",
},
5,
10,
7
],
operation: "+",
};
➡️ + and / samples
N4
输入:1+2/3
输出:
{
values: [
1,
{
values: [2, 3],
operation: "/",
},
],
operation: "+",
};
N5
输入:2/3+1
输出:
{
values: [
{
values: [2, 3],
operation: "/",
},
1,
],
operation: "+",
};
N6
输入:1/2+3/4+5/6
输出:
{
values: [
{
values: [1, 2],
operation: "/",
},
{
values: [3, 4],
operation: "/",
},
{
values: [5, 6],
operation: "/",
},
],
operation: "+",
};
N7
输入:1/2/3/4/5+6+7+8/9+10/11
输出:
{
values: [
{
values: [1, 2, 3, 4, 5],
operation: "/",
},
6,
7,
{
values: [8, 9],
operation: "/",
},
{
values: [10, 11],
operation: "/",
},
],
operation: "+",
};
➡️ / and - samples
N8
输入:1-2/3
输出:
{
values: [
1,
{
values: [2, 3],
operation: "/",
},
],
operation: "-",
};
➡️ / and * samples
N9
输入:10/2*5
输出:
{
values: [
{
values: [10, 2],
operation: "/",
},
5,
],
operation: "*",
};
实施例3:4次运算公式
N1
输入:10/2*5+1-1*5/3+2*4
输出:
{
values: [
{
values: [
{
values: [
{
values: [
{
values: [10, 2],
operation: "/",
},
5,
],
operation: "*",
},
1,
],
operation: "+",
},
{
values: [
{
values: [1, 5],
operation: "*",
},
3,
],
operation: "/",
},
],
operation: "-",
},
{
values: [2, 4],
operation: "*",
},
],
operation: "+",
};
实施例4:带()括号的公式
N1
输入:1+2*(3+2)
输出:
{
values: [
1,
{
values: [
2,
{
values: [3, 2],
operation: "+",
},
],
operation: "*",
},
],
operation: "+",
};
氮气
输入:(1+2*3)*2
输出:
{
values: [
{
values: [
1,
{
values: [2, 3],
operation: "*",
},
],
operation: "+",
},
2,
],
operation: "*",
};
N3
输入:(1/1/10)+1/30+1/50
输出:
{
values: [
{
values: [1, 1, 10],
operation: "/",
},
{
values: [1, 30],
operation: "/",
},
{
values: [1, 50],
operation: "/",
},
],
operation: "+",
};
其他病例
N1
输入:-(1+2)
输出:
{
values: [
{
values: [1, 2],
operation: "+",
},
],
operation: "-",
};
...
2条答案
按热度按时间twh00eeo1#
这里有一个函数似乎通过了所有的测试用例。
我写了很多表达式解析器,最后我决定在几乎所有的情况下都这样做,这是一个recursive descent解析器,它就像一个功能齐全的表达式解析器一样简单。
秘密在于
parseTokens
函数的minPrec
参数,该参数告诉函数进行解析,直到遇到优先级较低的操作符为止,这使得函数在每个优先级上递归调用自身变得容易。cnwbcb6i2#
我将发布我的解决方案,这是基于这个答案类似的问题。
该解决方案基于一个正则表达式,该表达式使用命名的捕获组对输入进行标记化。因此,代码的其余部分不必处理字符比较,而可以专注于语法规则。该实现没有显示优先级规则的显式概念,因为它们是由语法隐含的。
我在此重复语法规则,但也可参见上述答案中的解释:
在此,我将通过以下细节扩展该解决方案:
-(-(1+2))
将生成与1+2
相同的树。您可以在下面的代码片段中尝试不同的输入。
x一个一个一个一个x一个一个二个一个x一个一个三个一个