2014-10-25 3 views
0

У меня есть строка, как это:Javascript - Пользовательские математическое выражение разборе

"2 + 3^4" 

То, что я хочу быть заменен:

"2 + Math.pow(3, 4)" 

Так просто, я хочу каре «^» знак работать как функция Math.pow в моих математических выражениях.

Тогда я мог бы оценить его:

eval("2 + Math.pow(3, 4)") -> 83 

Вот несколько примеров:

"4^3^2" -> "Math.pow(4, Math.pow(3, 2))" 
"4^(3^2)^2^1" -> "Math.pow(4, Math.pow(Math.pow(3, 2), Math.pow(2, 1)))" 
"4.^Math.sqrt(2)^3" -> "Math.pow(4., Math.pow(Math.sqrt(2), 3))" 
"2^3e-2" -> "Math.pow(2, 3e-2)" 
"-5^.2" -> "-Math.pow(5, .2)" 
"(-5)^2" -> "Math.pow(-5, 2)" 
".2^-Infinity" -> "Math.pow(.2, -Infinity)" 
"2.34^((3 + 2) * Math.sin(3))" -> "Math.pow(2.34, (3 + 2) * Math.sin(3))" 
"Math.cos(2)^(3 + 2)" -> "Math.pow(Math.cos(2), 3 + 2)" 

То, что я пробовал:

String.prototype.replaceAt = function(index, character) { 
     return this.substr(0, index) + character + this.substr(index+character.length); 
    } 

    str = str.replace(/ /g, ""); 

    str = str.replace(/((?:(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?|Infinity))/g, "($1)") 

    for (var i = str.length - 1; i >= 0; i--) { 
     var m = str.lastIndexOf("^"); 

     var c = 0; 
     for (var j = m + 1; j < str.length; j++) { 
      if (str[j] == "(") c++; 
      if (str[j] == ")") c--; 

      if (c == 0) { 
       str = str.replaceAt(j + 1, str[j + 1] + ")") 
       break 
      } 
     } 

     c = 0; 
     for (var j = m - 1; j >= 0; j--) { 
      if (str[j] == "(") c++; 
      if (str[j] == ")") c--; 

      if (c == 0) { 
       str = str.replaceAt(j - 1, "Math.pow(" + str[j - 1]) 
       break 
      } 
     } 

     str = str.replaceAt(m, ",") 
    } 

не работает на всех и Ужасный беспорядок.

+0

Звуки, как вам нужно узнайте о парсерах. – Barmar

+0

@Barmar Итак, вы знаете, как это сделать? – super

+0

Нет, это слишком сложно для меня. Большинство людей используют инструменты, такие как 'yacc' или' bison' для написания парсеров. Я не уверен, как это сделать в Javascript. – Barmar

ответ

0

Использование http://mathjs.org/

Это позволяет рассчитать такие выражения, как

print(math.eval('sqrt(3^2 + 4^2)')); 

Использования стеков вы можете создать класс, который может преобразовать математическое выражение в понятное выражение JS, но возможность достижения всех тестов случаев правильно требует много испытаний. SO лучше использовать библиотеки (у них есть хорошие документы и примеры, доступные в Интернете).

+0

Я знаю, что math.js существует, и я проверил его, это хорошо, но я хочу понять свой код, так что спасибо. – super

-1

Это пример того, как вы могли анализировать свои строки и форматировать их с помощью функции Math.pow.

Сначала я хотел бы указать, что это по запросу OP (собственный код) вместо использования проверенной библиотеки. Во-вторых, это пример кода, и ни один из них не оптимизирован. Это не «изменить() или перемещает знаки + -», как ОП, публикуемые в 2-х из приведенных примеров

// 
// resolves the formula (^ into Math.pow) 
// 
function resolve(formula) { 
    var result = ""; 

    // search for {operand}^{operatand} 
    var match = formula.match(/(.[^^]*)\^(.*)/); 

    // if matched, we have 3 entries. 
    if (match && match.length == 3) { 
     result += "Math.pow(" + resolve(match[1]) + "," + resolve(match[2]) + ")"; 
    } else { 
     result += formula; 
    } 
    return result; 
}; 

Вот рабочая скрипка, чтобы увидеть его в действии: http://jsfiddle.net/httb9945/

+0

4^((3^2)^2)^1: неправильный результат. – jewelnguyen8

+0

Ницца, но 4^((3^2)^2)^1 не работает, можете ли вы это исправить? – super

Смежные вопросы