我是
JavaScript的新手,我正在尝试编写一个解决线性方程的简单脚本.到目前为止,我的脚本只解决了加号和减号的线性方程,如“2x 28 – 18x = 36 – 4x 10”.我希望它能够解决包含乘法和除法的线性方程/代数问题,例如“2x * 3x = 4 / 2x”.
我有点想知道下一步该做什么,但我认为我现在的脚本可能过于复杂,而且只会使添加乘法和除法变得更复杂.
以下是我的脚本.我希望能有一些关于如何改进和简化我已经拥有的内容以及添加乘法和除法的最佳方法的几点建议?
我在JS Bin上的脚本:http://jsbin.com/ufekug/1/edit
我的剧本:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <Meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>Problem Solver</title> <script> window.onload = function() { // Total Xs on each side of equation // Example problem: 5x + 2 = 10 - 2x var leftSideXTotal = 0; // 5 var rightSideXTotal = 0; // -2 // Total integers on each side of equation // Example problem: 5x + 2 = 10 - 2x var leftSideIntTotal = 0; // 2 var rightSideIntTotal = 0; // 10 // Enter a math problem to solve var problem = "5x + 2 = 10 - 2x"; // Remove all spaces in problem // Example problem: 5x + 2 = 10 - 2x problem = problem.replace(/\s/g,''); // 5x+2=10-2x // Add + signs in front of all - signs // Example problem: 5x + 2 = 10 - 2x problem = problem.replace(/-/gi,"+-"); // 5x+2=10+-2x // Split problem into left and right sides // Example problem: 5x + 2 = 10 - 2x var problemArray = problem.split("="); var problemLeftSide = problemArray[0]; // 5x+2 var problemRightSide = problemArray[1]; // 10+-2x // Split values on each side into an array var problemLeftSideValues = problemLeftSide.split("+"); var problemRightSideValues = problemRightSide.split("+"); // Go through the left side values and add them up for (var i = 0; i < problemLeftSideValues.length; i++) { // Current value var currentValue = problemLeftSideValues[i]; // Length of current value var currentValueLength = currentValue.length; if (currentValue.charAt(currentValueLength - 1) == "x") { //Check if current value is a X value // Remove X from end of current value currentValue = currentValue.split("x"); // Add to total Xs on left side leftSideXTotal = Number(leftSideXTotal) + Number(currentValue[0]); } else { // Add to total integers on left side leftSideIntTotal = Number(leftSideIntTotal) + Number(problemLeftSideValues[i]); } } // Go through the right side values and add them up for (var i = 0; i < problemRightSideValues.length; i++) { // Current value var currentValue = problemRightSideValues[i]; // Length of current value var currentValueLength = currentValue.length; if (currentValue.charAt(currentValueLength - 1) == "x") { //Check if current value is a X value // Remove X from end of current value currentValue = currentValue.split("x"); // Add to total Xs on right side rightSideXTotal = Number(rightSideXTotal) + Number(currentValue[0]); } else { // Add to total integers on right side rightSideIntTotal = Number(rightSideIntTotal) + Number(problemRightSideValues[i]); } } // Compute var totalXs = (leftSideXTotal - rightSideXTotal) var totalIntegers = (rightSideIntTotal - leftSideIntTotal) var solution = (totalIntegers / totalXs) // Display solution document.getElementById("divSolution").innerText = solution; } </script> </head> <body> <div id="divSolution"></div> </body> </html>
解决方法
您需要编写(或使用)运算符优先级解析器.
想法是将等式转化为树,例如,
x + 3 = 3x - 2
真的是结构
= / \ + - / \ / \ x 3 * 2 / \ 3 x
每个运算符描述树的两个“分支”之间的操作.使用javascript对象创建结构应该不难:
function tree(lterm,op,rterm) { t.operator = op; t.left = lterm; t.right = rterm; return t; } expression = tree("x","/",tree("x","+",3) ); // x / (x+3)
然后通过操纵树,您可以解决方程,或进行计算.要评估表达式(没有未知数),您将从终端开始,从交叉点向交叉点向上运行树.您可以使用结果替换树的一部分,或使用结果对其进行注释 – 将结果变量添加到树对象.
以下是一些包含在树类中的有用方法:
> getLeft
> getRight
> prettyPrint
>评估
>评估(“x”,5)// x = 5,现在评估
…
这不仅可以通过这种方式“解析”线性操作.更好的解析器将有一个包含= * / – 的运算符列表,但也包括一元运算符: – ()sin cos …
我没有在javascript中使用运算符优先级解析器,但有些必须存在预写.当然,这个网站上的一个善良的灵魂将为我的答案添加一个很好的链接.
顺便说一下,树方法有很多应用.在电子表格中:
A2 = A1+B1
在布尔求解器中:
A = not (B or C) C = true
在XML解析中:
<main> <part>A</part> <part>B</part> </main>