简体   繁体   English

C++ 提取多项式系数

[英]C++ extract polynomial coefficients

So I have a polynomial that looks like this: -4x^0 + x^1 + 4x^3 - 3x^4所以我有一个看起来像这样的多项式:-4x^0 + x^1 + 4x^3 - 3x^4
I can tokenize this by space and '+' into: -4x^0, x^1, 4x^3, -, 3x^4我可以通过空格和 '+' 将其标记为:-4x^0、x^1、4x^3、-、3x^4

How could I just get the coefficients with the negative sign: -4, 1, 0, 4, -3我怎么能得到带负号的系数:-4, 1, 0, 4, -3
x is the only variable that will appear and this will alway appear in order x 是唯一会出现的变量,它总是按顺序出现
im planning on storing the coefficients in an array with the array index being the exponent我计划将系数存储在数组中,数组索引为指数
so: -4 would be at index 0, 1 would be at index 1, 0 at index 2, 4 at index 3, -3 at index 4所以:-4 将位于索引 0,1 将位于索引 1,0 位于索引 2,4 位于索引 3,-3 位于索引 4

Start with "-4x^0 + x^1 + 4x^3 - 3x^4"
Split after ^number: "-4x^0", " + x^1", " + 4x^3", " - 3x^4"
Now everything behind an ^ is an exponent, everything before the x is an coefficient

EDIT: Simple method to get the coefficient (including the sign):编辑:获取系数(包括符号)的简单方法:

Init coefficient with 0, sign with '+'
Go through each character before the x from left to right
  If it's a number ('0'..'9'), coefficient = coefficient * 10 + number
  If it's '-', set sign to '-'

Once you have tokenized to "-4x^0", "x^1", etc. you can use strtol() to convert the textual representation into a number.标记为“-4x^0”、“x^1”等后,您可以使用 strtol() 将文本表示转换为数字。 strtol will automatically stop at the first non-digit character so the 'x' will stop it; strtol 将自动停止在第一个非数字字符处,因此 'x' 将停止它; strtol will give you a pointer to the character that stoped it, so if you want to be paranoid, you can verify the character is an x. strtol 会给你一个指向阻止它的字符的指针,所以如果你想变得偏执,你可以验证这个字符是一个 x。

You will need to treat implicit 1's (ie in "x^1" specially).您将需要处理隐式 1(即特别在“x^1”中)。 I would do something like this:我会做这样的事情:

long coeff;
if (*token == 'x')
{
   coeff = 1;
}
else
{
    char *endptr;
    coeff = strtol(token, &endptr, 10);
    if (*endptr != 'x')
    {
        // bad token
    }  
}

scan the string for an 'x', then go backward storing each character of the coefficient until you hit white space.扫描字符串中的“x”,然后向后存储系数的每个字符,直到遇到空格。 eg:例如:

for (int i=0; i<s.length(); ++i)
{
    if (s[i] == 'x')
    {
        string c;
        for (int j=i-1; j>=0 && s[j]!=' '; --j)
            c = s[j] + c;
        cout << "coefficient: " << c << endl;
    }
}

For a quick solution, my approach would be to write a recursive descent parser.为了快速解决,我的方法是编写一个递归下降解析器。 Move forward in the string and extract the components you want.在字符串中向前移动并提取所需的组件。 There are many examples around for writing a parser of an expression like this.有很多例子可以编写像这样的表达式的解析器。

If you want to use a library, you could use boost::regex or boost::spirit, depending on what kind of approach you want to take.如果你想使用一个库,你可以使用 boost::regex 或 boost::spirit,这取决于你想采取什么样的方法。

Write a simple tokenizer.编写一个简单的分词器。 Define a number token ( /[-0123456789][0123456789]+/ ), an exponent token ( /x^(::number::)/ ).定义一个数字标记( /[-0123456789][0123456789]+/ ),一个指数标记( /x^(::number::)/ )。 Ignore whitespace and + .忽略空格和+

Continually read tokens as you'd expect them until the end of the string.按照您的预期持续读取标记,直到字符串结束。 Then spit out the tokens in whatever form you want (eg integers).然后以您想要的任何形式(例如整数)吐出标记。

int readNumber(const char **input) {
    /* Let stdio read it for us. */
    int number;
    int charsRead;
    int itemsRead;

    itemsRead = sscanf(**input, "%d%n", &number, &charsRead);

    if(itemsRead <= 0) {
        // Parse error.
        return -1;
    }

    *input += charsRead;

    return number;
}

int readExponent(const char **input) {
    if(strncmp("x^", *input, 2) != 0) {
        // Parse error.
        return -1;
    }

    *input += 2;

    return readNumber(input);
}

/* aka skipWhitespaceAndPlus */
void readToNextToken(const char **input) {
    while(**input && (isspace(**input) || **input == '+')) {
        ++*input;
    }
}

void readTerm(const char **input. int &coefficient, int &exponent, bool &success) {
    success = false;

    readToNextToken(input);

    if(!**input) {
        return;
    }

    coefficient = readNumber(input);

    readToNextToken(input);

    if(!**input) {
        // Parse error.
        return;
    }

    exponent = readExponent(input);

    success = true;
}

/* Exponent => coefficient. */
std::map<int, int> readPolynomial(const char *input) {
    std::map<int, int> ret;

    bool success = true;

    while(success) {
        int coefficient, exponent;

        readTerm(&input, coefficient, exponent, success);

        if(success) {
            ret[exponent] = coefficient;
        }
    }

    return ret;
}

This would probably all go nicely in a class with some abstraction (eg read from a stream instead of a plain string).这可能会在具有一些抽象的类中很好地进行(例如,从流而不是纯字符串中读取)。

Example Equation: Str={"-X^10+4X^8-3X^2+3X^0=0"} 示例公式:Str = {“-X ^ 10 + 4X ^ 8-3X ^ 2 + 3X ^ 0 = 0”}

void Seperate_Coef_Exp(string str){ 
bool found=false;
string coef,exp;
int icoef,iexp;
int i=0;
while(1)  //Seperating  Coefficient
{
    coef="";exp="";
    if(found==true)
    break;
    for(;str[i]!='X'&&str[i+1]!='^';i++)
    {
        coef=coef+str[i];
    }
    i++; //For X
    i++; //For ^
    if(coef=="" || coef =="-" || coef =="+"  )
    coef=coef+"1";
    istringstream(coef)>>icoef; //To Convert String to Int

    while(1)     //Seperating  Exponent
    {
        if(str[i]=='=')
        {
            found=true;
            break;
        }
        if(str[i]=='+' || str[i]=='-')
        break;
        exp=exp+str[i];i++;     
    }
    if(exp=="" || exp =="-" || exp=="+")
    exp=exp+"1";
    istringstream(exp) >>iexp;
    cout<<"Coefficient=<<icoef<<"  Exp=<<iexp<<endl;
}
}   

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

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