简体   繁体   English

如何输入2 ^ 3到Math.pow(2,3)?

[英]How do get input 2^3 to Math.pow(2, 3)?

I have this simple calculator script, but it doesn't allow power ^. 我有这个简单的计算器脚本,但它不允许电源^。

 function getValues() { var input = document.getElementById('value').value; document.getElementById('result').innerHTML = eval(input); } 
 <label for="value">Enter: </label><input id="value"> <div id="result">Results</div> <button onclick="getValues()">Get Results</button> 

I tried using input = input.replace( '^', 'Math.pow(,)'); 我尝试使用input = input.replace( '^', 'Math.pow(,)');

But I do not know how to get the values before '^' and after into the brackets. 但我不知道如何在'^'之前和之后的括号中获取值。

Example: (1+2)^3^3 should give 7,625,597,484,987 例如:(1 + 2)^ 3 ^ 3应给出7,625,597,484,987

Use a regular expression with capture groups: 使用带捕获组的正则表达式:

 input = '3 + 2 ^3'; input = input.replace(/(\\d+)\\s*\\^\\s*(\\d+)/g, 'Math.pow($1, $2)'); console.log(input); 

This will only work when the arguments are just numbers. 这仅在参数只是数字时才有效。 It won't work with sub-expressions or when you repeat it, like 它不适用于子表达式或重复它时,如

(1+2)^3^3

This will require writing a recursive-descent parser, and that's far more work than I'm willing to put into an answer here. 这将需要编写一个递归下降的解析器,这比我愿意在这里提出的答案要多得多。 Get a textbook on compiler design to learn how to do this. 获取有关编译器设计的教科书,以了解如何执行此操作。

I don't think you'll be able to do this with simple replace. 我不认为你能用简单的替换来做到这一点。

If you want to parse infix operators, you build two stacks, one for symbols, other for numbers. 如果要解析中缀运算符,可以构建两个堆栈,一个用于符号,另一个用于数字。 Then sequentially walk the formula ignoring everything else than symbols, numbers and closing parenthesis. 然后顺序走公式,忽略符号,数字和右括号之外的所有内容。 Put symbols and numbers into their stacks, but when you encounter closing paren, take last symbol and apply it to two last numbers. 将符号和数字放入堆栈中,但是当遇到关闭的paren时,请使用最后一个符号并将其应用于最后两个数字。 (was invented by Dijkstra, I think) (我认为是Dijkstra发明的)

 const formula = '(1+2)^3^3' const symbols = [] const numbers = [] function apply(n2, n1, s) { if (s === '^') { return Math.pow(parseInt(n1, 10), parseInt(n2, 10)) } return eval(`${n1} ${s} ${n2}`) } const applyLast = () => apply(numbers.pop(), numbers.pop(), symbols.pop()) const tokenize = formula => formula.split(/(\\d+)|([\\^\\/\\)\\(+\\-\\*])/).filter(t => t !== undefined && t !== '') const solver = (formula) => { const tf = tokenize(formula) for (let l of formula) { const parsedL = parseInt(l, 10) if (isNaN(parsedL)) { if (l === ')') { numbers.push(applyLast()) continue } else { if (~['+', '-', '*', '/', '^'].indexOf(l)) symbols.push(l) continue } } numbers.push(l) } while (symbols.length > 0) numbers.push(applyLast()) return numbers.pop() } console.log(solver(formula)) 

Get your input into a string and do... 将您的输入输入字符串并执行...

var input = document.getElementById('value').value;
var values = input.split('^'); //will save an array with [value1, value 2]
var result = Math.pow(values[0], values[1]);
console.log(result);

This only if your only operation is a '^' 这只有你唯一的操作是'^'

EDIT: Saw example after edit, this no longer works. 编辑:编辑后看到示例,这不再有效。

function getValues() {
    var input = document.getElementById('value').value;

    // code to make ^ work like Math.pow
    input = input.replace( '^', '**');

    document.getElementById('result').innerHTML = eval(input);

}

The ** operator can replace the Math.pow function in most modern browsers. **运算符可以替换大多数现代浏览器中的Math.pow函数。 The next version of Safari (v10.1) coming out any day supports it. 每天推出的下一个版本的Safari(v10.1)都支持它。

As said in other answers here, you need a real parser to solve this correctly. 正如在此处的其他答案中所述,您需要一个真正的解析器来正确解决这个问题。 A regex will solve simple cases, but for nested statements you need a recursive parser. 正则表达式将解决简单的情况,但对于嵌套语句,您需要一个递归解析器。 For Javascript one library that offers this is peg.js . 对于Javascript,提供此功能的库是peg.js。

In your case, the example given in the online version can be quickly extended to handle powers: 在您的情况下,可以快速扩展在线版本中给出的示例以处理权限:

Expression
  = head:Term tail:(_ ("+" / "-") _ Term)* {
      var result = head, i;

      for (i = 0; i < tail.length; i++) {
        if (tail[i][1] === "+") { result += tail[i][3]; }
        if (tail[i][1] === "-") { result -= tail[i][3]; }
      }

      return result;
    }

Term
  = head:Pow tail:(_ ("*" / "/") _ Pow)* { // Here I replaced Factor with Pow
      var result = head, i;

      for (i = 0; i < tail.length; i++) {
        if (tail[i][1] === "*") { result *= tail[i][3]; }
        if (tail[i][1] === "/") { result /= tail[i][3]; }
      }

      return result;
    }

// This is the new part I added
Pow
  = head:Factor tail:(_ "^" _ Factor)* {
      var result = 1;
      for (var i = tail.length - 1; 0 <= i; i--) {
          result = Math.pow(tail[i][3], result);
      }
      return Math.pow(head, result);
    }

Factor
  = "(" _ expr:Expression _ ")" { return expr; }
  / Integer

Integer "integer"
  = [0-9]+ { return parseInt(text(), 10); }

_ "whitespace"
  = [ \t\n\r]*

It returns the expected output 7625597484987 for the input string (1+2)^3^3 . 它返回输入字符串(1+2)^3^3的预期输出7625597484987

这是这个问题的基于Python的版本,使用pyparsing的解决方案: 使用解析将**运算符更改为幂函数?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM