2013-01-07 21 views
7

我是JavaScript新手,想寫一個解決線性方程的簡單腳本。到目前爲止,我的腳本解決了只有「2x + 28 - 18x = 36 - 4x + 10」的正負線性方程。我希望它能夠解決包含乘法和除法的線性方程/代數問題,例如「2x * 3x = 4/2x」。用JavaScript解決線性方程和類似的代數問題

我有種想法,接下來該做什麼,但我認爲現在的腳本可能過於複雜,只會增加乘法和除法的複雜性。

下面是我的腳本。我希望提供一些關於如何改進和簡化我已有的內容以及添加乘法和除法的最佳方法的幾點提示。

我對JS斌腳本: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> 
+0

這是一個非常有趣的問題。如果你縮短了標題,我想你可以吸引更多的回答者。 –

+3

'2x * 3x = 4/2x'並不是一個真正的線性方程。 – Rikonator

+0

編輯標題。線性方程改爲線性方程和類似的代數問題。 – user1822824

回答

6

你需要寫(或使用)一個操作員優先解析器。

這個想法是將公式變成樹,

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) 

然後通過操縱樹,您可以解析公式或進行計算。爲了評估一個表達式(沒有未知數),你從終端開始穿過樹,從交叉點到交叉點向上。您可以用結果替換樹的一部分,或者用結果註釋它 - 將結果變量添加到tree對象。

下面是一些有用的方法在樹類,包括:

  • getLeft
  • GetRight時
  • prettyPrint
  • 評估
  • 評估( 「×」,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> 
0

我已經定義了兩個功能:

getTotalX():它會給你的x計數任何輸入字符串。

getTotalScalars():它會給你標量(數字)的總數。

最後,您更新的代碼(它仍然只做加法和減法):

<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 

    leftSideXTotal = getTotalX(problemLeftSide); 
    leftSideIntTotal = getTotalScalars(problemLeftSide); 

    rightSideXTotal = getTotalX(problemRightSide); 
    rightSideIntTotal = getTotalScalars(problemRightSide); 

    // Compute 
    var totalXs = (leftSideXTotal - rightSideXTotal) 
    var totalIntegers = (rightSideIntTotal - leftSideIntTotal) 
    var solution = (totalIntegers/totalXs) 

    // Display solution 
    document.getElementById("divSolution").innerText = solution; 

    // Find the total number of X in the string 
    function getTotalX(data) { 
     data = data.replace(/\s/g,''); 
     xCount = 0; 

     if(data.indexOf('x') != -1) { 
      if (data.indexOf('+') != -1) { 
       data = data.split('+'); 

       for(var i = 0; i < data.length; i++) { 
        xCount += getTotalX(data[i]); 
       } 
      } else if (data.indexOf('-') != -1) { 
       data = data.split('-'); 

       // Single negative 
       if(data[0] == "") { 
        xCount -= getTotalX(data[1]); 
       } else { 
        xCount += getTotalX(data[0]); 

        for(var i = 1; i < data.length; i++) { 
         xCount -= getTotalX(data[i]); 
        } 
       } 
      } else { 
       xCount = parseInt(data.split('x')[0]); 
      } 
     } 

     return xCount; 
    } 

    // Find the total of scalars 
    function getTotalScalars(data) { 
     data = data.replace(/\s/g,''); 
     intCount = 0; 

     if (data.indexOf('+') != -1) { 
      data = data.split('+'); 

      for(var i = 0; i < data.length; i++) { 
       intCount += getTotalScalars(data[i]); 
      } 
     } else if (data.indexOf('-') != -1) { 
      data = data.split('-'); 

      // Single negative 
      if(data[0] == "") { 
       intCount -= getTotalScalars(data[1]); 
      } else { 
       intCount += getTotalScalars(data[0]); 

       for(var i = 1; i < data.length; i++) { 
        intCount -= getTotalScalars(data[i]); 
       } 
      } 
     } else { 
      if(data.indexOf('x') == -1) { 
       intCount = parseInt(data.split('x')[0]); 
      } else { 
       intCount = 0; 
      } 
     } 

     return intCount; 
    } 
} 
</script>