2010-11-15 13 views
5

Estoy escribiendo un pequeño programa de línea de comandos que pide al usuario polinomios en la forma ax^2 + bx^1 + cx^0. Voy a analizar los datos más adelante, pero por ahora solo estoy tratando de ver si puedo hacer coincidir el polinomio con la expresión regular (\+|-|^)(\d*)x\^([0-9*]*) Mi problema es que no coincide con varios términos en el polinomio ingresado por el usuario a menos que cambie a ((\+|-|^)(\d*)x\^([0-9*]*))* (la diferencia es que toda la expresión está agrupada y tiene un asterisco al final). La primera expresión funciona si escribo algo como "4x^2" pero no "4x^2+3x^1+2x^0", ya que no se comprueba varias veces.¿Por qué Boost.Regex no encuentra coincidencias múltiples en una cadena?

Mi pregunta es, ¿por qué no Boost.Regex's regex_match() encuentra varias coincidencias dentro de la misma cadena? Lo hace en el editor de expresiones regulares que utilicé (Expresso) pero no en el código C++ real. ¿Se supone que debería ser así?

Avíseme si algo no tiene sentido e intentaré aclararlo. Gracias por la ayuda.

Edit1: Aquí está mi código (estoy siguiendo el tutorial aquí: http://onlamp.com/pub/a/onlamp/2006/04/06/boostregex.html?page=3)

int main() 
{ 
    string polynomial; 

    cmatch matches; // matches 

    regex re("((\\+|-|^)(\\d*)x\\^([0-9*]*))*"); 

    cout << "Please enter your polynomials in the form ax^2+bx^1+cx^0." << endl; 

    cout << "Polynomial:"; 
    getline(cin, polynomial); 

    if(regex_match(polynomial.c_str(), matches, re)) 
    { 
     for(int i = 0; i < matches.size(); i++) 
     { 
      string match(matches[i].first, matches[i].second); 
      cout << "\tmatches[" << i << "] = " << match << endl; 
     } 
    } 

    system("PAUSE"); 
    return 0; 
} 

Respuesta

7

Estás usando las cosas mal - regex_match está destinado a comprobar si una (única) expresión coincide con la totalidad de una secuencia de caracteres. Como tal, necesita especificar una expresión regular que coincida con toda la entrada, o usar otra cosa. Para su situación, es probablemente tiene más sentido modificar la expresión regular como ya lo hizo (agruparla y agregar una estrella Kleene). Si desea iterar sobre los términos individuales del polinomio, probablemente desee utilizar algo como un regex_token_iterator.

Editar: Por supuesto, ya que está incorporando esto en C++, también tiene que doblar todas las barras diagonales inversas. Mirándolo, también soy un pequeño confundido con la expresión regular que está usando, no me parece que realmente debería funcionar correctamente. Solo por ejemplo, parece que requiere un "+", "-" o "^" al comienzo de un término, pero el primer término normalmente no tendrá eso. También estoy algo inseguro de por qué habría un "^" al comienzo de un término. Como normalmente el exponente se omite cuando es cero, probablemente sea mejor permitir que se omita. Teniendo esto en cuenta, obtengo algo así como: "[- +]? (\ D *) x (\^([0-9]) *)".

incorporación que en algún código, podemos obtener algo como esto:

#include <iterator> 
#include <regex> 
#include <string> 
#include <iostream> 

int main() { 

    std::string poly = "4x^2+3x^1+2x"; 

    std::tr1::regex term("[-+]?(\\d*)x(\\^[0-9])*"); 

    std::copy(std::tr1::sregex_token_iterator(poly.begin(), poly.end(), term), 
     std::tr1::sregex_token_iterator(), 
     std::ostream_iterator<std::string>(std::cout, "\n")); 
    return 0; 
} 

Al menos para mí, que imprime cada término individual:

4x^2
+ 3x^1
+ 2x

Tenga en cuenta que, por el momento, acabo de imprimir cada término completo, y modifiqué su entrada para mostrar la capacidad de reconocer un término que no incluye un término poder (explícitamente, de todos modos).

Editar: para recoger los resultados en un vector en lugar de enviarlos a std::cout, que haría algo como esto:

#include <iterator> 
#include <regex> 
#include <string> 
#include <iostream> 

int main() { 
    std::string poly = "4x^2+3x^1+2x"; 

    std::tr1::regex term("[-+]?(\\d*)x(\\^[0-9])*"); 
    std::vector<std::string> terms; 

    std::copy(std::tr1::sregex_token_iterator(poly.begin(), poly.end(), term), 
     std::tr1::sregex_token_iterator(), 
     std::back_inserter(terms)); 

    // Now terms[0] is the first term, terms[1] the second, and so on. 

    return 0; 
} 
+0

He estado tratando de modificar la expresión regular, pero no ha estado trabajando . Coincidirá, pero la única información en la matriz de "coincidencias" es el material de la última subexpresión.Por ejemplo, si ingreso "4x^2 + 3x^1", mi salida dice: coincidencias [0] = 4x^2 + 3x^1 coincidencias [1] = + 3x^1 coincidencias [2] = + coincidencias [3 ] = 3 coincidencias [4] = 1 Solo obtengo el último término del polinomio; Necesito poder analizar todo el asunto. –

+0

@Zeebo: quizás sea útil la versión que he editado en la respuesta. –

+0

Lo siento, debería haber sido más claro. Solo necesito los coeficientes y los exponentes. Intento escribir un programa para realizar una división sintética, así que todo lo que necesito saber son los coeficientes (si son positivos o negativos), cuántos términos hay y los exponentes (porque 0x^n debe ser insertado si falta un término; por ejemplo, 4x^4 + 7x^2 necesita ser 4x^2 + 0x^3 + 7x^2.) –

Cuestiones relacionadas