2014-02-26 69 views
1

在計算器我自己特別是4輸入類型=「數字」:掃描字符串運算 - 的javascript

<input type = "number" id ="mol" min="1" max="4"> 
<input type = "number" id ="div" min="1" max="4"> 
<input type = "number" id ="add" min="1" max="4"> 
<input type = "number" id ="min" min="1" max="4"> 

在文本框,我插入數學表達式爲延長。

<input type = "text" id = "exp" readonly> 

數值和操作符都經過了正常的按鈕。 因此,例如,在文本框中插入的表達式是這樣的:8 * 5-9/2 + 3

現在我希望當我按等價鍵時,基於客戶給予的優先級操作數,表達結果改變了。

乘法:1
除法:4
減法:2
此外:3

-> 40 - 9/2 + 3 
-> 31/2 + 3 
-> 31/5 
-> = 6.2 

我認爲這是非常難以實現的。 獲取文本框的值並根據操作數的優先級評估結果是非常極端的。你有什麼建議?

回答

0

嘗試使用split方法:與第一優先順序的算符http://msdn.microsoft.com/en-us/library/t5az126b(v=vs.94).aspx

分割,再由所述第二算子分裂每個組,然後由第三算子分裂每個子組,併爲每個這些子的 - 分組由第四個分組。然後將操作員應用於向上移動的組。

概念爲例(不完整的代碼,你需要的,但應該給一個想法):

var expression = "8*5-9/2+3"; // Get this from the data 
var operator1Groups = expression.split("*"); // Instead of hardcoding this, retrieve which operator has highest priority from the data 
for (var i in operator1Groups) { 
    var operator2Groups = operator1Groups[i].split("+"); // Similarly, don't hardcode the operator 
    // And so on... 
    // Once you get to the lowest operator, start applying the operator to each group 
} 
+0

這將如何處理具有相同優先級的兩個運算符? –

+0

OP沒有聲明兩個運營商可以具有相同的優先級。但是,它仍然有效。在這種情況下,你可以分割多個分隔符。這是一種方法:http://stackoverflow.com/questions/19313541/split-a-string-based-on-multiple-delimiters – mayabelle

+0

我創建了這個數組:var Array = ['+',' - ','* ','/']; 但我不明白你的代碼是如何工作的,你可以給我一個實際的例子,說明我之前輸入的規範嗎? – user3344186

0

做到這一點的方法是使用一個Operator Precedence Parser。它們通常使用Djikstra的Shunting-yard Algorithm實施。

function parse(inputExpression, operators) { 
    // Strip out anything that isn't a number or a math operator 
    var tokens = inputExpression 
       .replace(/[^0-9+\-*\/()]/g, '') 
       .split(/([+\-*\/()])/) 
       .filter(function(x) { return x != ""; }); 

    var outputQ = []; // push = push, pop = pop 
    var operStk = []; // enqueue = push, dequeue = shift 

    function top(stack) { return stack[stack.length-1]; } 

    while(tokens.length !== 0) { 
     var token = tokens.shift(); 
     if(!isNaN(Number(token))) { 
      outputQ.push(token); 
     } else if (operators.hasOwnProperty(token)) { 
      while(operators[token] >= operators[top(operStk)]) 
       outputQ.push(operStk.pop()); 
      operStk.push(token); 
     } else if (token == '(') { 
      operStk.push(token); 
     } else if (token == ')') { 
      while(top(operStk) != '(' && operStk.length != 0) 
       outputQ.push(operStk.pop()); 

      if(operStk.length == 0) 
       return null; 

      operStk.pop(); // Get rid of the l-paren 
     } else { 
      console.log("Bad token '" + token + "'"); 
      return null; 
     } 
    } 

    while(operStk.length > 0) 
     outputQ.push(operStk.pop()); 

    return outputQ; 
} 

function evaluate(parseResult) { 
    if (parseResult === null) return null; 

    var valueStack = []; 
    while(parseResult.length !== 0) { 
     var op = parseResult.shift(); 
     if(!isNaN(Number(op))) 
      valueStack.push(Number(op)); 
     else { 
      var val2 = valueStack.pop(); 
      var val1 = valueStack.pop(); 
      if(op == '+') { 
       valueStack.push(val1 + val2); 
      } else if(op == '-') { 
       valueStack.push(val1 - val2); 
      } else if(op == '*') { 
       valueStack.push(val1 * val2); 
      } else if(op == '/') { 
       valueStack.push(val1/val2); 
      } else { 
       console.log("Invalid operator '" + op + "'"); 
       return null; 
      } 
     } 
    } 

    if(valueStack.length !== 1) { 
     console.log("Invalid stack. Remaining: " + valueStack); 
     return null; 
    } 

    return valueStack.pop(); 
} 

用法:

var operators = { 
    "+": 3, 
    "-": 2, 
    "*": 1, 
    "/": 4 
}; 
evaluate(parse("40 - 9/2 + 3", operators)); // == 6.2 

注意,這將手柄元負,因爲它很難,你可以通過加載運營商和優先級到一個列表中,然後運行該算法指定優先級與調車場相關,並且因爲你沒有要求優先權。在光明的一面,它確實支持括號。

希望這會有所幫助!

Alex

+0

問題是我必須從文本框中讀取表達式。 我認爲這將是有用的做出4個循環,其中每個封閉用戶輸入的優先級。 所以我命令向量的元素。 我認爲這簡單得多。你幫我建立它? – user3344186

+0

我將把它作爲練習留給你 - 查閱jQuery文檔,以獲取閱讀文本框/表單字段值的好資源。 –