2014-02-08 36 views
3

我想構建可以爲傳統數學輸入生成MathML的代碼。我正在使用JavaScript進行編碼。是否有任何參考文獻或推薦的閱讀材料可以幫助我們掌握所需的算法?我正在閱讀MathML的W3C標準,這是標準的參考,但不適用於算法。Javascript的MathML生成算法。任何推薦的參考

例如,對於

sqrt 9 * 5 + 20 

樣本輸入我想要生成MATHML表達類似下面

<math xmlns='w3.org/1998/Math/MathML'>; <mrow> <mrow> <mn>5</mn> <mo>&#8290;</mo> <mn>9</mn> <mo>&#8290;</mo> <mi>SQRT</mi> </mrow> <mo>+</mo> <mn>20</mn> </mrow> </math> 
+0

你所說的 「數學公式」 是什麼意思?你的輸入格式是什麼?你認爲「算法」需要做什麼? – Bergi

+0

你考慮過mathjax嗎? – Bergi

+0

謝謝Bergi。我的意思是一個數學解析器,可以像MathML表達式那樣解析傳統數學,如「SQRT 9 * 5 + 20」,如 SQRT + user1998463

回答

1

我找到了一個不錯的教程MATHML這裏:http://rypress.com/tutorials/mathml/basic-algebra.html並着手製定一個非常基本的代數分析器(例如4*sqrt(x+6)=(5-z)*y/7),其中包含一個處理括號的粗堆棧和一個示例sqrt函數。這是你以後的方向嗎?

的jsfiddle這裏:http://jsfiddle.net/alhambra1/bSJyE/

JavaScript代碼:

<script> 
document.write('<p><input id="input" size=50>') 
document.write('<button onclick="convertToMathML()">Convert</button></p>') 
document.write('<div id="output"></div>') 

function lex(str,ptr){ 
    var ascii = str.charCodeAt(ptr), 
     lexeme = {string: "", type: ""}, 
     operators = {"+": "+" 
        , "-": "-" 
        , "*": "&times;" 
        , "/": "&divide;" 
        , "=": "="}, 
     functions = {sqrt: "msqrt"} 

    //identify type 
    if (ascii == 41) 
     lexeme.type = "closeBracket" 
    else if (ascii == 40){ 
     lexeme.type = "func" 
     lexeme.func = "mfenced" 
    } 
    else if (ascii > 45 && ascii < 58 && ascii != 47) 
     lexeme.type = "mn" 
    else if ((ascii > 64 && ascii < 91) || (ascii > 96 && ascii < 123)){ 
     for (i in functions){ 
      if (str.substr(ptr,i.length).toLowerCase() == i){ 
       lexeme.type = "func" 
       lexeme.func = functions[i] 
       ptr += i.length - 1 
      } else 
       lexeme.type = "mi" 
     } 
    } else if (!operators[str.charAt(ptr)]) 
     return {string: str.charAt(ptr), type: "error", pointer: ptr} 
    else 
     lexeme.type = "mo" 

    switch (lexeme.type){ 
     case "mo": 
      lexeme.string = operators[str.charAt(ptr++)] 
      break 
     default: 
      lexeme.string = str.charAt(ptr++) 
      break 
    } 

    ascii = str.charCodeAt(ptr) 

    //identify numbers and functions 
    if (lexeme.type == "mn"){ 
     while (ptr < str.length && ascii > 45 && ascii < 58 && ascii != 47){ 
      lexeme.string += str.charAt(ptr) 
      ascii = str.charCodeAt(++ptr) 
     } 
    } else if (lexeme.type == "func" && lexeme.func != "mfenced"){ 
     while (ptr < str.length && str.substr(ptr).match(/^\s/)){ 
      ascii = str.charCodeAt(++ptr) 
     } 
     if (str.charAt(ptr) != "(") 
      return {string: str.charAt(ptr), type: "error", pointer: ptr} 
     else 
      ptr++ 
    } 

    lexeme["pointer"] = ptr 

    return lexeme 
} 

function markup(lexeme){ 
    return "<" + lexeme.type + ">\n" 
      + lexeme.string + "\n" 
      + "</" + lexeme.type + ">\n" 
} 

function convertToMathML(){ 
    var str = document.getElementById('input').value, 
     expression = "", 
     ptr = 0, 
     stack = [] 

    while (ptr < str.length){ 
     var currLexeme = lex(str,ptr) 

     if (currLexeme.type == "closeBracket"){ 
      if (stack.length == 0) 
       expression = "Extra bracket at: " + (currLexeme.pointer - 1) 
      else 
       expression += "</" + stack.pop().func + ">\n" 
          + "</mrow>"   
      ptr = currLexeme.pointer 
     } else if (currLexeme.type == "error"){ 
      expression = "Cannot parse \"" + currLexeme.string 
         + "\" at " + currLexeme.pointer 
      break 
     } else if (currLexeme.type == "func"){ 
      expression += "<" + currLexeme.func + ">\n" 
         + "<mrow>\n" 
      stack.push(currLexeme) 
      ptr = currLexeme.pointer 
     } else { 
      expression += markup (currLexeme) 
      ptr = currLexeme.pointer 
     } 
    } 

    if (ptr >= str.length && stack.length > 0) 
     expression = "Missing " + stack.length + " closing bracket/s." 

    expression = "<math xmlns='http://www.w3.org/1998/Math/MathML'>" 
       + expression + "</math>" 

    document.getElementById('output').innerHTML = expression 
} 
</script> 
+0

謝謝Groovy。這有幫助,我會通過http://rypress.com/tutorials/mathml/basic-algebra.html。這將幫助我獲得我需要的算法! – user1998463

+0

我還有另一個問題,你會知道任何可以評估數學表達式的網頁嗎?到目前爲止,我已經設計了一個工作良好的工具,但我還想通過一些很好的算法來看看我所做的工作是否有改進的空間。 – user1998463

+0

@ user1998463對於數學表達式的評估,google.com或wolframalpha.com通常適用於我的目的,儘管它們的後端可能並不那麼明顯。從我所知道的很少,通常將數學表達式轉換爲前綴符號(http://en.wikipedia.org/wiki/Polish_notation),然後使用Shunting-yard算法(http:// en .wikipedia.org /維基/分流-yard_algorithm)。 JavaScript也有一個'eval'函數,可以返回JavaScript數學表達式作爲字符串輸入的值。 –