문제

그래서 나는 다음과 같이 보이는 다항식이 있습니다 : -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에 있고, 색인 3에서 4, 4는 색인 4에서 -3입니다.

도움이 되었습니까?

해결책

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

다른 팁

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

문자열을 '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;
    }
}

빠른 솔루션을 위해서는 재귀 적 출신 파서를 작성하는 것입니다. 문자열에서 앞으로 이동하여 원하는 구성 요소를 추출하십시오. 이와 같은 표현의 구식을 쓰는 데 주변에는 많은 예가 있습니다.

라이브러리를 사용하려면 어떤 종류의 접근 방식에 따라 Boost :: Regex 또는 Boost :: Spirit을 사용할 수 있습니다.

간단한 토 케이저를 작성하십시오. 숫자 토큰 정의 (/[-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;
}

이것은 아마도 약간의 추상화가있는 클래스에서 멋지게 갈 것입니다 (예 : 일반 문자열 대신 스트림에서 읽습니다).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top