扩展代数项

11 javascript math algebra

我试图扩展代数术语.

(x+1)(x+1)/x => x + 2 + x^-1
(x+1)^3 => x^3 + 3x^2 + 3x + 1
(x^2*x)(x^2) => x^5
Run Code Online (Sandbox Code Playgroud)

这是我的尝试.我尝试了很多方法来解决下面的问题.

问题:

  • 喜欢的术语应该加在一起

  • (x+1)(x+1)(x+1) 应该是有效的.

  • (x+1)^2 应该等于 (x+1)(x+1)

  • x(x+1) 应该是有效的

  • 1x^n 应该只是 x^n

  • 应该没有0x^n条款.

  • nx^0 条款应该是 n

代码片段:

function split(input) {

    return ((((input.split(")(")).toString()).replace(/\)/g, "")).replace(/\(/g, "")).split(','); }

function strVali(str) {
    str = str.replace(/\s+/g, "");

    var parts = str.match(/[+\-]?[^+\-]+/g);

    // accumulate the results
    return parts.reduce(function(res, part) {
        var coef = parseFloat(part) || +(part[0] + "1") || 1;
        var x = part.indexOf('x');
        var power = x === -1 ?
            0:
            part[x + 1] === "^" ?
                +part.slice(x + 2) :
                1;
        res[power] = (res[power] || 0) + coef;
        return res;
    }, {});
}

function getCoeff(coeff) {

    var powers = Object.keys(strVali(coeff));

    var max = Math.max.apply(null, powers);

    var result = [];
    for(var i = max; i >= 0; i--)
        result.push(strVali(coeff)[i] || 0);

    return result; }

function evaluate(expression) {
    var term1 = getCoeff(expression[0]);
    var term2 = getCoeff(expression[1]);
    var expand = "";
    for ( var j = 0; j < term1.length; j++ ) {
        for ( var i = 0; i < term2.length; i++ ) {
            expand += Number(term1[j] * term2[i]) + 'x^ ' + (Number(term1.length) - 1 - j + Number(term2.length) - 1 - i) + ' + ';
        }}
        var final = "";
    for ( var Z = 0; Z < getCoeff(expand).length; Z++) {
        final += ' ' + getCoeff(expand)[Z] + 'x^ {' + (getCoeff(expand).length - Z - 1) + '} +';
    }
    final = "$$" + ((((((final.replace(/\+[^\d]0x\^ \{[\d]+\}/g,'')).replace(/x\^ \{0}/g,'')).replace(/x\^ \{1}/g,'x')).replace(/[^\d]1x\^ /g,'+ x^')).replace(/\+ -/g,' - ')).slice(0, -1)).substring(1,(final.length)) + "$$";
    document.getElementById('result').innerHTML = final;
    MathJax.Hub.Queue(["Typeset", MathJax.Hub, document.getElementById('result')]);
}

function caller() {
    var input = document.getElementById('input').value;
    evaluate(split(input)); }
Run Code Online (Sandbox Code Playgroud)
div.wrapper {
    width: 100%;
    height:100%;
    border:0px solid black;
}

input[type="text"] {
    display: block;
    margin : 0 auto;
    padding: 10px;
    font-size:20px;
}

button{
    margin:auto;
    display:block;
    background-color: white;
    color: black;
    border: 2px solid #555555;
    padding-left: 20px;
    padding-right: 20px;
    font-size: 20px;
    margin-top:10px;
}

button:hover {
    box-shadow: 0 12px 16px 0 rgba(0,0,0,0.24),0 17px 50px 0 rgba(0,0,0,0.19);
}
Run Code Online (Sandbox Code Playgroud)
<script type="text/javascript" async
        src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-MML-AM_CHTML">
</script>
<div class='wrapper'><input id="input" title="Enter Expression" type="text" value="(x^2+x+1)(x^2+x+1)"></div>
<div> <button onclick="caller()">Click</button></div>
<div id="result">$$x^4 + 2x^3 + 3x^2 + 2x + 1$$</div>
Run Code Online (Sandbox Code Playgroud)

参考:

  1. 如何计算javascript中多项式展开的系数

  2. 获得代数项的系数

  3. 如何在角色前获得一个词?

小智 0

它可以处理+-/和隐式乘法。它相应地扩展括号并将它们添加到原始表达式中,同时删除括号ed版本。它相应地收集类似的术语。限制:它不能除以多项式,并且不支持*运算符。

function strVali(str) {
    str = str.replace(/\s+/g, "");
    var parts = str.match(/[+\-]?[^+\-]+/g);
    return parts.reduce(function(res, part) {
        var coef = parseFloat(part) || +(part[0] + "1") || 1;
        var x = part.indexOf('x');
        var power = x === -1 ?
            0:
            part[x + 1] === "^" ?
                +part.slice(x + 2) :
                1;
        res[power] = (res[power] || 0) + coef;
        return res;
    }, {});
}

function getCoeff(coeff) {
    var powers = Object.keys(strVali(coeff));
    var max = Math.max.apply(null, powers);
    var result = [];
    for(var i = max; i >= 0; i--)
        result.push(strVali(coeff)[i] || 0);
    return result; }

function format(str) {
    str = ' ' + str;
    str = str.replace(/-/g,'+-').replace(/x(?!\^)/g,'x^1').replace(/([+\/*)(])(\d+)([+\/*)(])/g,'$1$2x^0$3').replace(/([^\d])(x\^-?\d+)/g,'$11$2').replace(/(-?\d+x\^\d+)(?=\()/g,'($1)').replace(/(\))(-?\d+x\^\d+)/g,'$1($2)').replace(/([^\)\/])(\()([^\*\/\(\)]+?)(\))(?![(^\/])/g,'$1$3');
    str = str.replace(/(\([^\(\)]+?\))\/(\d+x\^-?\d+)/g,'$1/($2)').replace(/(\d+x\^-?\d+)\/(\d+x\^-?\d+)/g,'($1)/($2)').replace(/(\d+x\^-?\d+)\/(\(\d+x\^-?\d+\))/g,'($1)/$2');
    return str;
}

function expBrackets(str) {
    var repeats = str.match(/\([^\(\)]+?\)\^\d+/g);
    if ( repeats === null ) { return str; } else { var totalRepeat = '';
    for ( var t = 0; t < repeats.length; t++ ) { var repeat = repeats[t].match(/\d+$/); for ( var u = 0; u < Number(repeat); u++ ) { totalRepeat += repeats[t].replace(/\^\d+$/,''); }
        str = str.replace(/\([^\(\)]+?\)\^\d+/, totalRepeat); totalRepeat = ''; }
    return str; }
}

function multiply(str) {
    var pairs = str.match(/\([^\(\)]+?\)\([^\(\)]+?\)/g);
    if ( pairs !== null ) { while ( pairs !== null ) { var output = '';
        for (var i = 0; i < pairs.length; i++) { var pair = pairs[i].slice(1).slice(0, -1).split(')('); var firstCoeff = getCoeff(pair[0]); var secondCoeff = getCoeff(pair[1]);
            for (var j = 0; j < firstCoeff.length; j++) {
                for (var k = 0; k < secondCoeff.length; k++) { output += firstCoeff[j] * secondCoeff[k] + 'x^' + Number(firstCoeff.length - 1 - j + secondCoeff.length - 1 - k) + '+'; } }
            var regexp = new RegExp(pairs[i].replace(/\(/g,'\\(').replace(/\+/g,'\\+').replace(/\)/g,'\\)').replace(/\^/g,'\\^').replace(/\-/g,'\\-'));
            str = str.replace(regexp, '(' + (output.slice(0, -1).replace(/[^\d]0x\^\d+/g,'')) + ')');
            output = ''; }
        pairs = str.match(/\([^\(\)]+?\)\([^\(\)]+?\)/g); } }
        else { }
    str = str.replace(/\+/g,' + ');
    return str;
}

function divide(str) {
    if ( str.match(/\/(\(-?\d+x\^-?\d+.+?\))/g) === null && str.match(/\//g) !== null ) {
        while ( pairs !== null ) {
        var pairs = str.match(/\([^\(\)]+?\)\/\([^\(\)]+?\)/g);
        var output = '';
        for (var i = 0; i < pairs.length; i++) {
            var pair = pairs[i].slice(1).slice(0, -1).split(')/(');
            var firstCoeff = getCoeff(pair[0]);
            var secondCoeff = getCoeff(pair[1]);
            for (var j = 0; j < firstCoeff.length; j++) {
                for (var k = 0; k < secondCoeff.length; k++) {
                    output += firstCoeff[j] / secondCoeff[k] + 'x^' + Number(firstCoeff.length - 1 - j - secondCoeff.length + 1 + k) + '+';
                    output = output.replace(/([+-])Infinityx\^\-?\d+/g,'').replace(/([+-])NaNx\^\-?\d+/g,'');
                } }
            var regexp = new RegExp(pairs[i].replace(/\(/g,'\\(').replace(/\+/g,'\\+').replace(/\)/g,'\\)').replace(/\^/g,'\\^').replace(/\-/g,'\\-'));
            str = str.replace(regexp, '(' + (output.slice(0, -1).replace(/[^\d]0x\^-?\d+/g,'')) + ')');

            output = ''; }
        pairs = str.match(/\([^\(\)]+?\)\/\([^\(\)]+?\)/g); } }
    else { }
    return str;
}

function evaluate(str) {
    var result = format(divide(format(multiply(expBrackets(format((str)))))));
    var resultCollect = '';
    result = result.replace(/\s+/g, "").replace(/[^\d]0x\^-?\d+/g,'').replace(/\+/g,' + ');
    if ( result === '') {
        document.getElementById('result').innerHTML = '$$' + str + '$$'  + '$$ = 0 $$';
        MathJax.Hub.Queue(["Typeset", MathJax.Hub, document.getElementById('result')]);
    } else if ( result.match(/-?\d+x\^-\d+/g) === null && str.match(/\/(\(-?\d+x\^-?\d+.+?\))/g) === null) {
        for ( var i = 0; i < getCoeff(result).length; i++ ) {
        resultCollect += getCoeff(result)[i] + 'x^' + Number(getCoeff(result).length - 1 - i) + '+' ; }
        if ( resultCollect !== '')
        resultCollect = '$$ = ' + resultCollect.slice(0,-1).replace(/[^\d]0x\^-?\d+/g,'').replace(/\+/g,' + ').replace(/x\^0/g,'').replace(/x\^1(?!\d+)/g,'x').replace(/\^(-?\d+)/g,'\^\{$1\}').replace(/\+ -/g,' - ') + '$$';
        else
        resultCollect = 'Error: Trying to divide by a polynomial ';
        document.getElementById('result').innerHTML = '$$' + str.replace(/\^(-?\d+)/g,'\^\{$1\}') + '$$' + resultCollect;
        MathJax.Hub.Queue(["Typeset", MathJax.Hub, document.getElementById('result')]);
    } else {
        resultCollect = '$$ = ' + result.replace(/\^(-?\d+)/g,'\^\{$1\}') + '$$';
        document.getElementById('result').innerHTML = '$$' + str.replace(/\^(-?\d+)/g,'\^\{$1\}').replace(/\+ -/g,' - ') + '$$' + resultCollect;
        MathJax.Hub.Queue(["Typeset", MathJax.Hub, document.getElementById('result')]);
    }
}

function caller() {
    var input = document.getElementById('input').value;
    evaluate(input);
}
Run Code Online (Sandbox Code Playgroud)
div.wrapper {
    width: 100%;
    height:100%;
    border:0 solid black;
}

input[type="text"] {
    display: block;
    margin : 0 auto;
    padding: 10px;
    font-size:20px;
}

button{
    margin:auto;
    display:block;
    background-color: white;
    color: black;
    border: 2px solid #555555;
    padding-left: 20px;
    padding-right: 20px;
    font-size: 20px;
    margin-top:10px;
}

button:hover {
    box-shadow: 0 12px 16px 0 rgba(0,0,0,0.24),0 17px 50px 0 rgba(0,0,0,0.19);
}
Run Code Online (Sandbox Code Playgroud)
<script type="text/javascript" async
        src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-MML-AM_CHTML">
</script>
<input id="input" type="text" title="Enter Expression: ">
<button onclick="caller()">Click</button>
<div id="result"></div>
<div id="errors"></div>
Run Code Online (Sandbox Code Playgroud)