C++提取多项式系数

发布于 2024-08-12 12:14:44 字数 241 浏览 5 评论 0原文

所以我有一个如下所示的多项式:-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

So I have a polynomial that looks like this: -4x^0 + x^1 + 4x^3 - 3x^4
I can tokenize this by space and '+' into: -4x^0, x^1, 4x^3, -, 3x^4

How could I just get the coefficients with the negative sign: -4, 1, 0, 4, -3
x is the only variable that will appear and this will alway appear in order
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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

你的笑 2024-08-19 12:14:44

一旦您将其标记为“-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
    }  
}

Once you have tokenized to "-4x^0", "x^1", etc. you can use strtol() to convert the textual representation into a number. strtol will automatically stop at the first non-digit character so the 'x' will stop it; 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.

You will need to treat implicit 1's (i.e. in "x^1" specially). 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
    }  
}
沉溺在你眼里的海 2024-08-19 12:14:44
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 '-'
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 '-'
弃爱 2024-08-19 12:14:44

扫描字符串中的“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;
    }
}

scan the string for an 'x', then go backward storing each character of the coefficient until you hit white space. 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;
    }
}
爱的十字路口 2024-08-19 12:14:44

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

如果您想使用库,可以使用 boost::regex 或 boost::spirit,具体取决于您想要采用哪种方法。

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.

音盲 2024-08-19 12:14:44

编写一个简单的分词器。定义数字标记 (/[-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;
}

在具有一些抽象的类中,这可能一切都会很好(例如从流而不是普通字符串中读取)。

Write a simple tokenizer. Define a number token (/[-0123456789][0123456789]+/), an exponent token (/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 (e.g. 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 (e.g. read from a stream instead of a plain string).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文