Pregunta

Tengo un polinomio que se ve así: -4x ^ 0 + x ^ 1 + 4x ^ 3 - 3x ^ 4
Puedo tokenizar esto por espacio y '+' en: -4x ^ 0, x ^ 1, 4x ^ 3, -, 3x ^ 4

¿Cómo podría obtener los coeficientes con el signo negativo: -4, 1, 0, 4, -3? x es la única variable que aparecerá y esto siempre aparecerá en orden

Estoy planificando el almacenamiento de los coeficientes en una matriz con el índice de matriz como exponente
entonces: -4 estaría en el índice 0, 1 estaría en el índice 1, 0 en el índice 2, 4 en el índice 3, -3 en el índice 4

¿Fue útil?

Solución

Una vez que hayas tokenizado a " -4x ^ 0 " ;, " x ^ 1 " ;, etc. puedes usar strtol () para convertir la representación textual en un número. strtol se detendrá automáticamente en el primer carácter sin dígitos, por lo que la 'x' lo detendrá; strtol le dará un puntero al carácter que lo detuvo, por lo que si desea ser paranoico, puede verificar que el carácter es una x.

Deberá tratar los 1 implícitos (es decir, en " x ^ 1 " especialmente). Haría algo como esto:

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

Otros consejos

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

EDITAR: Método simple para obtener el coeficiente (incluido el signo):

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

escanee la cadena en busca de una 'x', luego vaya hacia atrás almacenando cada carácter del coeficiente hasta que toque el espacio en blanco. por ejemplo:

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

Para una solución rápida, mi enfoque sería escribir un analizador de descenso recursivo. Avanzar en la cadena y extraer los componentes que desee. Hay muchos ejemplos para escribir un analizador de una expresión como esta.

Si desea utilizar una biblioteca, puede usar boost :: regex o boost :: spirit, según el tipo de enfoque que desee adoptar.

Escribe un tokenizador simple. Defina un token de número ( / [- 0123456789] [0123456789] + / ), un token de exponente ( / x ^ (:: number ::) / ). Ignora los espacios en blanco y + .

Continúe leyendo los tokens como lo esperaría hasta el final de la cadena. Luego, escupe las fichas en la forma que desee (por ejemplo, enteros).

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

Probablemente, todo irá bien en una clase con algo de abstracción (por ejemplo, leer de un flujo en lugar de una cadena simple).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top