使用 javascript 中的数学方程拆分变量

Posted

技术标签:

【中文标题】使用 javascript 中的数学方程拆分变量【英文标题】:Split a variable using mathematical equations in javascript 【发布时间】:2015-11-23 06:29:39 【问题描述】:

其实我有两个问题。 我要做的是首先检查用户输入的值是否是正确的数学方程。例如,如果用户输入x + y ( z,这应该检测为无效公式,x + y ( z ) 为正确公式,

我要做的第二件事是将公式与+ - * / () 符号分开,所以上面的公式将返回为x, y, z

我所做的如下

var arr = [];

var s = 'x + y ( z )';

arr = s.split("(?<=[-+*/])|(?=[-+*/])");

console.log(arr);

这会返回一个数组,其中只有一个数据,例如 [x + y ( z )]

另外,变量不是单个字母。他们可能是 年价、收盘价等词

谁能帮我解决这个问题。提前致谢

更新:我也试过"/[^+/*()-]+/g"

【问题讨论】:

javascript 中没有lookbehind @anubhava 我也试过 /[^+/*()-]+/g,没用 为什么不首先根据一些规则验证它是否是一个有效的数学表达式,然后解析出其中的所有字母? P.S.将您的问题分成两个不同的帖子可以更有效地获得答案。 【参考方案1】:

第二部分:

var s = 'x + y ( z )';
var arr = s.match(/(\w)/g);
console.log(arr);
document.write(JSON.stringify(arr));

当然,你要先检查输入的有效性。

编辑:使用 Tomer W 的回答建议 eval()

function checkExpression(str) 
    // check for allowed characters only
    if (/[^\w\d\(\)\+\*\/\-\s]/.exec(s) != null)
        return false;

    // extract variable names, assuming they're all one letter only
    var arr = s.match(/(\w+)/g);

    // instantiate the variables
    arr.forEach(function (variable) 
        eval(variable + '= 1');
    );

    // ( is alone, replace it by * (
    str = str.replace(/\(/g, '* (');

    try 
        eval(str);
        return true;
    
    catch (ex) 
        console.log(ex);
        return false;
    

它很脏,但大部分时间都有效(Tomer W 指出了一些边缘情况,例如 ++62+554++++6 可以通过另一个正则表达式检查来避免),你有更复杂的例子要测试吗?

【讨论】:

上面的表达式也会将 arr 从 % 符号中拆分出来,我想要的只是从 / * - + ( ) 拆分出来 是的,您必须先检查有效性。这里的“惰性”解决方案是生成解析器,此处给出的示例正是您想要的,但生成的代码是 18Ko:pegjs.org/online 我无法使用解析器,因为公式中的变量没有有效值。它只是变量。我只是想确保它是一个有效的公式 其实是的。由于公式是用户输入的,它可以是任何东西。这就是我要检查公式有效性的原因。用户可以输入公式,例如 x*2+y(4 . 不正确。缺失 )。我应该验证这种公式并给出错误 另一件事,变量不是单个字母。它们可以是诸如年价、收盘价等词【参考方案2】:

警告词

非常非常非常危险的方法!!!

我发布这个是因为它是一个有效的答案,但你应该非常小心地这样做,因为用户可能会完全搞砸你的网站。不要让一个用户输入用于 eval给另一个用户!!!永远!!!

实际答案

可以使用浏览器自带的java-script编译器,使用eval()

function checkEq(equ)

  for(ch in equ)
    // check that all characters in input are "equasion usable"
    if(" +-*/1234567890e^&%!=".indexOf(ch) === -1)
     // if there are invalid chars
      return false;
    
  
  try
    // try running the equ, will throw an exception on a syntax error.
    eval(equ);
    return true; // no exception
  
  catch(ex)
    return false; // syntax error
  

Plunker example

正如我之前提到的!非常小心!

【讨论】:

我尝试消除eval 中大多数字符的使用,但一个漂亮的黑客可能能够使用&amp;###; 制作一些艺术作品(尽管他没有; 除了输入中填充了变量名,所以它总是会失败(到处都是引用错误),但是使用我的答案来获取变量名,然后在使用你的 eval 之前创建它们可以工作。这是危险的聪明:D 你也可以允许变量为x y z,但这会让用户写出my_nasty_function();这样的东西:) 发现另一个需要注意的问题 :) 因为54+++6 是有效的并导致60,同样++62+5 导致68 :) 我用你的输入更新了我的答案,使用 eval() 很脏,但它对这么少的行效果很好(只要输入是安全的)。不过,我仍然会使用真正的解析器来涵盖所有情况。【参考方案3】:

使用@ShanShan 和@Tomer W 的答案,我编写了一个公式验证器。代码如下。在这个验证器中,我检查左括号和右括号、额外的 / * - + 符号、不需要的符号等。

如果用户想要使用 x,y,z 创建和验证公式 变量,用户必须将变量添加到数组并将其传递给 这个验证器写了公式,所以验证器接受 不是数字的变量。

我还使用了这篇文章中提到的自定义集。 https://***.com/a/4344227/918277

重要提示:此 java 脚本函数无法验证包含 sin、cos、tan、log 等的非常复杂的公式。脚本会将它们识别为字母并返回 false。

function StringSet() 
    var setObj = , val = ;

    this.add = function(str) 
        setObj[str] = val;
    ;

    this.contains = function(str) 
        return setObj[str] === val;
    ;

    this.remove = function(str) 
        delete setObj[str];
    ;

    this.values = function() 
        var values = [];
        for ( var i in setObj) 
            if (setObj[i] === val) 
                values.push(i);
            
        
        return values;
    ;


/**
 * 
 * @param _formulaInputs
 *            Array of use entered inputs to be use in formula
 * @param _formula
 *            User entered formula
 * @returns Boolean
 */
function validateFormula(_formulaInputs, _formula) 

    var formula = _formula;

    var bracketStack = new Array();

    var formulaDescArray = [];

    var formulaDescInForm = new StringSet();

    for (var i = 0; i < _formulaInputs.length; i++) 

        formulaDescInForm.add(_formulaInputs[i]);
    

    /* Regex to check for unwanted symbols(! @ # $ etc.) */
    if (/[^\w\d\(\)\+\*\/\-\s]/.exec(formula) != null) 
        return false;
    

   for (var i = 0; i < _formula.length; i++) 
            if ((_formula.charAt(i) == '/' || _formula.charAt(i) == '*'
                    || _formula.charAt(i) == '-' || _formula.charAt(i) ==   '+')
                    && (_formula.charAt(i + 1) == '/'
                            || _formula.charAt(i + 1) == '*'
                            || _formula.charAt(i + 1) == '-' || _formula
                            .charAt(i + 1) == '+')) 
                return false;
            
    

    var lastChar = formula.charAt(formula.length - 1);

    if (lastChar == '/' || lastChar == '*' || lastChar == '-'
            || lastChar == '+') 
        return false;
    

    formulaDescArray = formula.split(/[\/\*\-\+\()]/g);

    /* Remove unwanted "" */
    for (var i = 0; i < formulaDescArray.length; i++) 
        if (formulaDescArray[i].trim().length == 0) 
            formulaDescArray.splice(i, 1);
            i--;
        
    

    /* Remove unwanted numbers */
    for (var i = 0; i < formulaDescArray.length; i++) 

        if (!isNaN(formulaDescArray[i])) 
            formulaDescArray.splice(i, 1);
            i--;
        
    

    for (var i = 0; i < formulaDescArray.length; i++) 
        if (!formulaDescInForm.contains(formulaDescArray[i].trim())) 
            return false;
        
    

    for (var i = 0; i < formula.length; i++) 
        if (formula.charAt(i) == '(') 
            bracketStack.push(formula.charAt(i));
         else if (formula.charAt(i) == ')') 
            bracketStack.pop();
        
    

    if (bracketStack.length != 0) 
        return false;
    

    return true;


【讨论】:

以上是关于使用 javascript 中的数学方程拆分变量的主要内容,如果未能解决你的问题,请参考以下文章

在Android中执行数学方程

组合数学经典方程的对偶方程一个不等式问题(例题:acwing1312 序列统计)

C++ 数学与算法系列之高斯消元法求解线性方程组

SOR迭代法实验报告c语言,数学实验“线性方程组的J-迭代,GS-迭代,SOR-迭代解法”实验报告(内含matlab程序代码).doc...

睡前1小时数学之矩阵及其应用

数学笔记12——常微分方程和分离变量