algorytm std::sort() powoduje błąd

0

Rozwiązuje sobie to zadanie ze spoja:
http://pl.spoj.com/problems/FR_02_16/

I oto mój (na razie częściowy) sposób rozwiązania:

 #include <iostream>
#include <string>
#include <cstdlib>
#include <vector>
#include <algorithm>
using namespace std;

struct Uczen{
    int rok;
    int miesiac;
    int dzien;
    int numer;
    Uczen(int a, int b, int c, int d) : rok(a), miesiac(b), dzien(c), numer(d) {}
};

bool funkcja(Uczen& a, Uczen& b);

int main() {

    int testy;
    cin >> testy;
    while(testy--){

        vector<Uczen> wekUczniowie;

        int uczniowie;
        cin >> uczniowie;
        while(uczniowie--){
            int numerek;
            string data;
            cin >> numerek >> data;
            string rokS = data.substr(0, 4);
            string miesiac = data.substr(5, 2);
            string dzienS = data.substr(8, 2);

            int r = atoi(rokS.c_str());
            int m = atoi(miesiac.c_str());
            int d = atoi(dzienS.c_str());

            Uczen uczen( r, m, d, numerek );

            wekUczniowie.push_back( uczen );
            
            cout << uczen.dzien << endl;
            cout << uczen.miesiac << endl;
            cout << uczen.rok << endl;
            cout << uczen.numer << endl;

        }

        sort(wekUczniowie.begin(), wekUczniowie.end(), funkcja);
    }

    return 0;
}

bool funkcja(Uczen& a, Uczen& b){
    if(a.rok < b.rok)
        return true;
    else if(a.rok == b.rok && a.miesiac < b.miesiac)
        return true;
    else if(a.rok == b.rok && a.miesiac == b.miesiac && a.dzien < b.dzien)
        return true;
    else if(a.rok == b.rok && a.miesiac == b.miesiac && a.dzien == b.dzien  && a.numer < b.numer)
        return true;
    else
        return false;
}

Problem w tym że wywala mi dziwny błąd:

 terminate called after throwing an instance of 'std::out_of_range'
  what():  basic_string::substr: __pos (which is 5) > this->size() (which is 0)

Błąd znika po wy-komentowaniu algorytmu sort(). I dodam że dane z klasy Uczen wyświetlają się poprawnie.

Co zrobiłem nie tak?

1

Jesteś pewien że dobrze podajesz dane?
Najpierw liczba testów, potem uczniów i następnie w pętli numerek i datę z 8 znaków. Źle też odczytujesz dzień z daty. Powinno być

string dzienS = data.substr(6, 2);
1

Błąd mówi że robisz substr() i podajesz tam pozycje numer 5 podczas gdy string jest krótszy.

4
bool funkcja(Uczen& a, Uczen& b){
    if(a.rok < b.rok)
        return true;
    else if(a.rok == b.rok && a.miesiac < b.miesiac)
        return true;
    else if(a.rok == b.rok && a.miesiac == b.miesiac && a.dzien < b.dzien)
        return true;
    else if(a.rok == b.rok && a.miesiac == b.miesiac && a.dzien == b.dzien  && a.numer < b.numer)
        return true;
    else
        return false;
}

Nie lepiej tak?

bool compare(Uczen const& l, Uczen const& r){
    return std::tie(l.rok, l.miesiac, l.dzien, l.numer) < std::tie(r.rok, r.miesiac, r.dzien, r.numer);
}
0
szweszwe napisał(a):

Jesteś pewien że dobrze podajesz dane?
Najpierw liczba testów, potem uczniów i następnie w pętli numerek i datę z 8 znaków. Źle też odczytujesz dzień z daty. Powinno być

string dzienS = data.substr(6, 2);

To przykładowa data:
2007-12-15

Miesiac zaczyna sie elementem na pozycji 5 a dzień na pozycji 8.

Shalom napisał(a):

Błąd mówi że robisz substr() i podajesz tam pozycje numer 5 podczas gdy string jest krótszy.

I tego błędu własnie nie rozumiem. Jak może mieć mniej niż 5 znaków skoro poprawnie wczytuje dane do miesiac i dzienS które są na dalszych pozycjach

0

Jesteś pewien, że przykładowa data to nie np. 2007 12 15?

0
kq napisał(a):

Jesteś pewien, że przykładowa data to nie np. 2007 12 15?

Tak. Tu jest treść zadania: http://pl.spoj.com/problems/FR_02_16/

0

Może do testów podajesz niepoprawne dane wejściowe? SOA#1 - "u mnie działa": http://melpon.org/wandbox/permlink/DgDciNfeXwjCZVMD

0
kq napisał(a):

Może do testów podajesz niepoprawne dane wejściowe? SOA#1 - "u mnie działa": http://melpon.org/wandbox/permlink/DgDciNfeXwjCZVMD

Ja dostaje ten błąd podczas kompilacji...

0

Niemożliwe, to jest przecież wyjątek rzucony w czasie wykonania...

0

U mnie ten wyjątek występuje kiedy poda się ilość testów oraz ilość uczniów, ale nie poda się numerka. Przy poprawnych danych wejściowych wszystko jest ok.

cin >> testy;
[...]
cin >> uczniowie;
[..]
cin >> numerek >> data;
0

ta przypadlosc sie nazywa 'primitive obsession', ale ja bym wywalila tego ucznia i jak juz musi byc to c++:

#include <iostream>
#include <algorithm>
using namespace std;
 
int main() {
 
    int testy;
    cin >> testy;
    while(testy--){
 
        long long wekUczniowie[10000];
 
        int uczniowie;
        cin >> uczniowie;
        for(int i=0;i<uczniowie;i++){
        	char c;
            long long numerek, r, m, d;
            cin >> numerek >> r >> c >> m >> c >> d;
            wekUczniowie[i] = ((r*10000+m*100+d)<<32)+numerek;
        }
 
        sort(wekUczniowie, wekUczniowie + uczniowie);
        
        for(int i=0;i<uczniowie;i++){
            cout << (wekUczniowie[i] & 0xffff) << ' ';
        }
    }
 
    return 0;
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1