获取代数项系数 [英] Getting coefficients of algebraic term

查看:47
本文介绍了获取代数项系数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑到代数项的输入,我试图获取变量的系数.输入中唯一的运算符是+ -,并且只有一个变量.

Given a input of an algebraic term, I am trying to get the coefficients of the variables. The only operators in the input is + - and only one variable.

示例:

2x^2+3x+4 => [ 2, 3, 4 ]

3-x => [ -1, 3 ]

x^2+x => [ 1, 1, 0 ]

x+x^3 => [ 1, 0, 1, 0 ]

无效输入:

2x^2+2x^2

这是我第一次尝试:

var str = " 2x^4-1+9x^3-100x^2";

    function getCoeff(term) {

        var nterm = (term.replace(/[^0-9|-]x(?!\^)/g,"1x")).replace(/[^0-9|\+]x(?!\^)/g,"-1x"); // ==> Replace ‘-/x’ with ‘-/1x’

        for ( var i = 0; i < 10; i++ ) { // ==> Loop true the regexs to replace all ‘x^n’ to ‘1x^n’

            var re = new RegExp('[^0-9|\-]x\\^' + i); // ==> Regex for x^n
            var re2 = new RegExp('[^0-9|]x\\^' + i); // ==> Regex for -x^n

            nterm = (nterm.replace(re,"1x^" + i)).replace(re2,"-1x^" + i); }

        for ( var m = 10; m > 1; m--  ) { // ==> Get the coefficients of ax^n in descending order
            var re3 = new RegExp('\\W?\\d+(?=x\\^' + m + ')' ); 
            if ( nterm.match(re3) === null ) {
                var result = "";
            } else {
                result += ((nterm.match(re3)+', ').toString()).replace(/\+/g,""); }}

        if ( nterm.match(/\W?\d+(?=x(?!\^))/g) === null ) { // Regex for coefficient x
            var result2 = "";
        } else {
            result2 = ((nterm.match(/\W?\d+(?=x(?!\^))/g)).toString()).replace(/\+/g,"") + ',';  }

        if ( nterm.match(/[^\^]\d+(?!\d|x)/g) === null ) { // Regex for constant
            var result3 = "";
        } else {
            result3 = ((nterm.match(/[^\^]\d+(?!\d|x)/g)).toString()).replace(/\+/g,""); }

        console.log(('[' + ' ' + result + result2 + ' ' + result3 + ']' ).replace(/\s/g,"")); }

    getCoeff(str)

问题:

  • 缺少x term时不起作用.
  • Does not work when there is a missing x term.

例如:x^4 + x + 1 ==> Expected: [1, 0, 0, 1, 1] ==> Actual: [ 1, 1 ]

  • x应该返回[ 1,0 ],但是它返回[ 1, ]
  • x should return [ 1,0 ] , but it returns [ 1, ]

这是我第二次尝试.

var str = "-999x^2+x^3+x+3";
function getCoeff(string) {
if ( string.charAt(0) === 'x' ) { // If the first term is x, because of my regex it needs a space to match it
    string = ' ' + string;
}

for ( var i = 0; i < 10; i++ ) { // ==> Loop true the regexs to replace all ‘x^n’ to ‘1x^n’

    var re = new RegExp('[^0-9|\-]x\\^' + i);
    var re2 = new RegExp('[^0-9|]x\\^' + i);
    string = (string.replace(re,"+1x^" + i)).replace(re2," -1x^" + i); } 

var final = string.replace(/-/g,'+-'); // ==> Spilt(‘x’) later so to retain the -ve sign

final = (final.replace(/[^0-9|-]x(?!\^)/g,"+1x")).replace(/[^0-9|+]x(?!\^)/g,"-1x");  // ==> Replace ‘-/x’ with ‘-/1x’

final = final.replace(/[^\^](\d+(?!\d|x))/g,'+$1x^0'); // ==> Replace ‘c’ with ‘cx^0’
final = final.replace(/x(?!\^)/g, "x^1"); // ==> Replace ‘x’ with ‘x^1’
final = final.split('+'); // ==> Right now array looks something like this [ ax^(n), bx^(n-1), … yx^1,  zx^0]
final = final.filter(function(entry) { return entry.trim() !== ''; }); // Sorts array by the number behind in descending order

var reS = /^-?\d+/,
    reE = /\d+$/;
var result = final.sort(function(a, b) {
    a = reE.exec(a);
    b = reE.exec(b);
    return b - a;
}).reduce(function(res, str, i) {
    var gap = reE.exec(final[i - 1]) - reE.exec(str);
    if(gap > 0)
        while(--gap) res.push(0);
    res.push(+reS.exec(str));
    return res;
}, []); // Return the coefficients
console.log("Result:", result); 
}

getCoeff(str);

问题:

  1. 有没有一种方法可以在大多数情况下不使用正则表达式?

  1. Is there a way to do it without using regular expressions mostly?

如何解决此问题?如果没有常数项

How do I fix this problem? When no constant term is

getCoeff(x^3) ==> [ 1 ] , when it should give [ 1, 0, 0 ]

如何提高代码效率?

如何使用正则表达式匹配x^n术语而不匹配-x^n术语?这是我当前的名字:[^0-9|\-]x\\^' + i,但是它前面需要一个空格.

How to match x^n terms but not -x^n terms using regex? This is my current one: [^0-9|\-]x\\^' + i, but it needs a space in front of it.

参考:

如何根据中的数字对数组进行排序字符串?

推荐答案

function getCoef(str) {
  str = str.replace(/\s+/g, "");                   // remove spaces (optional)
  
  var parts = str.match(/[+\-]?[^+\-]+/g);         // get the parts: see explanation bellow

  // accumulate the results
  return parts.reduce(function(res, part) {        // for each part in parts
    var coef = parseFloat(part) || +(part[0] + "1") || 1;// the coeficient is the number at the begining of each part (34x => 34), if there is no number it is assumed to be +/-1 depending on the sign (+x^2 => +1)
    var x = part.indexOf('x');                     // the index of "x" in this part (could be -1 if there isn't)
    // calculating the power of this part
    var power = x === -1 ?                         // if the index of "x" is -1 (there is no "x")
                  0:                               // then the power is 0 (Ex: -2)
                  part[x + 1] === "^" ?            // otherwise (if there is an "x"), then check if the char right after "x" is "^", if so...
                    +part.slice(x + 2) :           // then the power is the number right after it (Ex: 55x^30)
                    1;                             // otherwise it's 1 (Ex: 55x)
    res[power] = (res[power] || 0) + coef;         // if we have already encountered this power then add this coeficient to that, if not then just store it 
    return res;
  }, {});
}

/** TESTS **/
[
  "-999x^2 + x^3 + x + 3", "5x + 3 - 10x", "55x^3 + 1", "55.12x^4 + 20x^4 - 120x^4"
].forEach(function(test) {
  console.log(test, "=>", getCoef(test));
});

输出:

函数getCoef的结果将是以下格式的对象:

The result of the function getCoef will be an object in this format:

{
    "power": "coeficient",
    "other power": "other coeficient",
    ...
}

说明:

  1. str = str.replace(/\s+/g, "");:

删除空格(明显).

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

将字符串分成几部分.字符串"-5x^2-3+10x"将返回["-5x^2", "-3", "+10x"].正则表达式将寻找:

Split the string into parts. The string "-5x^2-3+10x" will return ["-5x^2", "-3", "+10x"]. The regex will look for:

[+\-]?  : a "+" or "-" sign (if any)
[^+\-]+ : anything that isn't a "+" nor "-" (get everything up until the new + or - or the end is reached)
g       : to get all parts

  1. var coef = parseFloat(part) || +(part[0] + "1") || 1;:

使用以下方法获取该部分的系数:

Get the coeficient of this part using:

parseFloat     : for parts that have a number before "x" like: "+55x", "-34.22x^11", "5x", ...
+(part[0] + 1) : for parts that have only a sign like: "+x", "-x^2", ... (get the sign part[0] concatinate it with "1" and then cast the result into a number using binary +)
1              : for parts that doesn't have a number nor a sign like "x^3", "x", ...

请注意,使用上述方法,将假定像"0x^4"这样的零件的系数为1(但我不明白为什么无论如何都需要空系数)!

just note that parts like "0x^4" will be assumed as having a coeficient of 1 using the above (but I don't see why one will need a null coeficient anyway)!

  1. var x = part.indexOf('x');:

获取部分中字符"x"的索引,以区分具有"3x""x^11",...等字符的部分和不具有"+5",...的部分.

Get the index of the character "x" in the part to distinguish between parts that have it like "3x", "x^11", ... and parts that doesn't like "+5", ...

  1. var power = ...:

如果部件(x === -1)中没有"x",则该部件的功效为0.

If there isn't an "x" in the part (x === -1) then the power of this part is 0.

否则(存在"x"),然后我们检查"x"(part[x + 1])之后的字符是否为"^",如果是,则幂是其后的任意数字(将其切掉)字符串part.slice(x + 2)的一部分,并使用一元+将其转换为数字),如果"x"之后没有"^",则幂为1.

Otherwise (an "x" is present), then we check if the character right after "x" (part[x + 1]) is "^", if it is then the power is whaterver number that comes after it (cut that bit of the string part.slice(x + 2) and cast it to number using unary +), if there isn't a "^" after "x", then the power is 1.

  1. res[power] = (res[power] || 0) + coef;:

将刚刚计算出的系数coef添加到该功率的已累积系数中(如果没有累积,则使用0).

Add the coeficient coef that has just been calculated to the already accumulated coeficient of this power (if nothing is accumulated then use 0).

此行可以这样简化:

if(res[power])         // if we already encountered this power in other parts before
  res[power] += coef;  // then add this coeficient to the sum of those previous coeficients
else                   // otherwise
  res[power] = coef;   // start a new sum initialized with this coeficient

这使得在相同的字符串中多次包含相同的幂成为可能,例如:"5x + 10x + 1 + x",...

this makes it possible to include the same power more than one time in the same string like: "5x + 10x + 1 + x", ...

将生成的对象转换为所需的数组:

因此:

{
    "3": 7,
    "0": 19
}

将是:

[7, 0, 0, 19]

var ret = { "3": 7, "0": 19 }; // the returned object

var powers = Object.keys(ret); // get all the powers (in this case [3, 0])

var max = Math.max.apply(null, powers); // get the max power from powers array (in this case 3)

var result = [];
for(var i = max; i >= 0; i--)  // from the max power to 0
  result.push(ret[i] || 0);    // if that power has a coeficient then push it, otherwise push 0
  
console.log(result);

这篇关于获取代数项系数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆