2010-11-15 10 views
5

Piszę mały program wiersza poleceń, który pyta użytkownika o wielomiany w postaci ax^2 + bx^1 + cx^0. Mam zamiar parsować dane później, ale na razie próbuję tylko sprawdzić, czy mogę dopasować wielomian do wyrażenia regularnego. (\+|-|^)(\d*)x\^([0-9*]*) Moim problemem jest to, że nie pasuje do wielu terminów w wielomianu wprowadzonym przez użytkownika, chyba że zmienię to do ((\+|-|^)(\d*)x\^([0-9*]*))* (różnica jest całe wyrażenie jest pogrupowane i ma gwiazdkę na końcu). Pierwsze wyrażenie działa, jeśli wpisuję coś takiego jak "4x^2", ale nie "4x^2+3x^1+2x^0", ponieważ nie sprawdza ono wiele razy.Dlaczego funkcja Boost.Regex nie znajduje wielu dopasowań w jednym ciągu?

Moje pytanie brzmi: dlaczego nie zwiększyć Boot.Regex regex_match() znaleźć wiele dopasowań w obrębie tego samego ciąg? Robi to w edytorze wyrażeń regularnych, którego użyłem (Expresso), ale nie w aktualnym kodzie C++. Czy to ma być tak?

Daj mi znać, jeśli coś nie ma sensu, a ja postaram się wyjaśnić. Dzięki za pomoc.

Edit1: Oto mój kod (Obserwuję tutorial tutaj: 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; 
} 

Odpowiedz

7

Używasz źle - regex_match ma na celu sprawdzenie, czy (single) regex pasuje do całości sekwencji znaków. W związku z tym należy podać wyrażenie regularne, które pasuje do całego wejścia lub użyć czegoś innego. Dla twojej sytuacji, prawdopodobnie ma sens, aby zmodyfikować wyrażenie regularne tak jak już zrobiłeś (pogrupuj je i dodaj gwiazdkę Kleene). Jeśli chciałbyś powtórzyć poszczególne warunki wielomianu, prawdopodobnie chciałbyś użyć czegoś takiego jak regex_token_iterator.

Edycja: Oczywiście, od kiedy osadzasz to w C++, musisz również podwoić wszystkie backslawy. Patrząc na to, jestem też niezbyt pewny, jeśli chodzi o wyrażenie regularne, którego używasz - nie wygląda na to, że powinien naprawdę dobrze działać. Na przykład, wydaje się, że na początku terminu wymaga się "+", "-" lub "^", ale pierwszy termin zwykle go nie zawiera. Nie jestem też pewien, dlaczego na początku semestru będzie "^". Ponieważ wykładnik jest zwykle pomijany, gdy wynosi zero, prawdopodobnie lepiej jest go pominąć. Biorąc to pod uwagę, otrzymuję coś takiego: "[- +]? (\ D *) x (\^([0-9]) *)".

Zawierające że w niektórych kodu, możemy uzyskać coś takiego:

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

Przynajmniej dla mnie, że wypisuje każdy termin indywidualnie:

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

Zwróć uwagę, że w tej chwili właśnie wydrukowałem wszystkie pełne terminy i zmodyfikowałem Twój wkład, aby pokazać zdolność do rozpoznawania terminu, który nie zawiera moc (jawnie, tak czy inaczej).

Edit: zebrać wyniki do wektora zamiast wysyłać je do std::cout, chcesz zrobić coś takiego:

#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

Próbowałem zmodyfikować regex, ale nie działa . Będzie pasować, ale jedyną informacją w tablicy "mecze" są rzeczy z ostatniego podwyrażenia.Na przykład, jeśli wpiszesz "4x^2 + 3x^1", moje wyjście odczytuje: mecze [0] = 4x^2 + 3x^1 mecze [1] = + 3x^1 mecze [2] = + dopasowania [3 ] = 3 dopasowania [4] = 1 Otrzymuję tylko ostatni człon wielomianu; Muszę móc przeanalizować całą sprawę. –

+0

@Zeebo: Być może wersja, którą edytowałem w odpowiedzi, będzie pomocna. –

+0

Przepraszam, powinienem być bardziej zrozumiały. Potrzebuję tylko współczynników i wykładników. Próbuję napisać program do przeprowadzania syntetycznego podziału, więc wszystko, co muszę wiedzieć, to współczynniki (i to, czy są pozytywne czy negatywne), ile jest ich terminów i wykładników (ponieważ 0x^n musi być wstawiony, jeśli brakuje terminu, np. 4x^4 + 7x^2 musi być 4x^2 + 0x^3 + 7x^2.) –

Powiązane problemy