8

私は 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>
4

2 に答える 2

8

演算子優先パーサーを作成 (または使用) する必要があります。

アイデアは、方程式をツリーに変換することです。

x + 3 = 3x - 2

本当に構造なのか

        =
     /     \
    +       -
   / \     / \
  x   3   *   2
         / \
        3   x

各演算子は、ツリーの 2 つの「ブランチ」間の操作を記述します。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
  • 正しくなる
  • かわいいプリント
  • 評価
  • evaluate("x",5) // x=5、今度は評価 ...

このように「解析」できるのは線形操作だけではありません。より良いパーサーには、=*/+- だけでなく単項演算子も含む演算子のリストがあります: - ( ) sin cos...

JavaScript で演算子優先パーサーを使用したことはありませんが、いくつかは事前に作成されている必要があります。確かに、このサイトの親切な魂は、私の答えに良いリンクを1つまたは2つ追加します.

ところで、ツリー アプローチには多くのアプリケーションがあります。スプレッドシートで:

A2 = A1+B1

ブールソルバーでは:

A = not (B or C)
C = true

XML 解析では:

<main>
  <part>A</part>
  <part>B</part>
</main> 
于 2013-01-07T16:18:22.667 に答える
0

私は2つの関数を定義しました:

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>
于 2013-01-07T08:21:36.473 に答える