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 になります。

4

5 に答える 5

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;
    }
}
于 2009-11-27T03:04:44.540 に答える
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 '-'
于 2009-11-26T23:18:16.713 に答える
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
    }  
}
于 2009-11-26T23:32:04.507 に答える
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;
}

これはおそらく、抽象化されたクラス (たとえば、単純な文字列ではなくストリームから読み取る) ですべてうまくいくでしょう。

于 2009-11-27T04:14:06.040 に答える
0

迅速な解決策として、私のアプローチは再帰降下パーサーを作成することです。文字列を前方に移動し、必要なコンポーネントを抽出します。このような式のパーサーを書くための多くの例があります。

ライブラリを使用する場合は、どのようなアプローチを取りたいかに応じて、boost::regex または boost::spirit を使用できます。

于 2009-11-26T23:25:52.860 に答える