C ++提取多项式系数

时间:2009-11-26 23:12:04

标签: c++ tokenize

所以我有一个如下所示的多项式:-4x ^ 0 + x ^ 1 + 4x ^ 3 - 3x ^ 4
我可以通过空格和'+'将其标记为:-4x ^ 0,x ^ 1,4x ^ 3, - ,3x ^ 4

我怎样才能得到带负号的系数:-4,1,0,4,-3 x是唯一会出现的变量,这将始终按顺序出现 我计划将系数存储在数组中,数组索引是指数
所以:-4将在索引0,1将在索引1,0在索引2,4在索引3,-3在索引4

5 个答案:

答案 0 :(得分:1)

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

编辑:获取系数的简单方法(包括符号):

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 '-'

答案 1 :(得分:1)

一旦您将其标记为“-4x ^ 0”,“x ^ 1”等,您可以使用strtol()将文本表示转换为数字。 strtol将自动停在第一个非数字字符处,这样'x'就会停止它; strtol会给你一个指向它的字符的指针,所以如果你想成为偏执狂,你可以验证字符是否为x。

您需要处理隐式1(即特别是“x ^ 1”)。我会做这样的事情:

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

答案 2 :(得分:1)

扫描字符串中的'x',然后向后存储系数的每个字符,直到你达到空白区域。例如:

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;
    }
}

答案 3 :(得分:0)

对于快速解决方案,我的方法是编写递归下降解析器。在字符串中向前移动并提取所需的组件。有很多例子可以编写像这样的表达式的解析器。

如果你想使用一个库,你可以使用boost :: regex或boost :: spirit,具体取决于你想采取什么样的方法。

答案 4 :(得分:0)

编写一个简单的标记生成器。定义数字标记(/[-0123456789][0123456789]+/),指数标记(/x^(::number::)/)。忽略空格和+

不断读取令牌,直到字符串结束为止。然后以你想要的任何形式吐出代币(例如整数)。

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;
}

这可能在一个抽象的类中很好(例如从流而不是普通字符串读取)。