Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[C++] Funkcja zliczająca dni robocze (początkujący)

Ostatnio zmodyfikowano 2014-12-11 16:35
Autor Wiadomość
Germaniero
Temat założony przez niniejszego użytkownika
[C++] Funkcja zliczająca dni robocze (początkujący)
» 2014-12-10 23:32:09
Dzień dobry,
to mój pierwszy post więc witam serdecznie Wszystkich! :)

Uczę się C++ od dwóch tygodni i mam spory problem związany z zadaniem nr 9.2 z kursu "Kuźnia Programistów" http:/​/www.kuzniaprogramistow.pl/
Kurs ten pozwala na przeprowadzanie testów automatycznych wykonanych zadań, ma to swoje wady i zalety. Napisałem program, który moim zdaniem działa poprawnie, ale nie przechodzi testów, natomiast gdy manualnie testuje program przy użyciu tych samych zmiennych, które pokazały błąd w testach automatycznych - wszystkie obliczenia są prawidłowe. Proszę by ktoś z Państwa prześledził mój kod i stwierdził czy błąd leży po mojej stronie? Ewentualne komentarze na temat usprawnień mile widziane. :)

Oto treść zdania:
Napisz funkcję int workingDay(int initYear, int initMonth, int initDay, int finalYear, int finalMonth, int finalDay);, która w wyniku swojego działania zwróci liczbę dni roboczych pomiędzy dwoma datami. Pisząc dni robocze mamy na myśli wszystkie dni z zakresu poniedziałek - piątek, nawet jeśli dla danej daty w taki dzień wypada święto. Np. 25 i 26 grudzień będą zaliczone do dni roboczych, jeśli wypadną pomiędzy poniedziałkiem a piątkiem.

Przykładowe wywołanie funkcji z następującymi parametrami: workingDay(2014, 1, 1, 2014, 1, 10); powinno w wyniku zwrócić liczbę 8.

Bierzemy pod uwagę lata 2000 - 2020. Można wykorzystać funkcję z zadania 8.1.

A to mój kod:
C/C++
#include<iostream>
using namespace std;
bool czyPrzestepny( int rok ) //funkcja sprawdza czy rok jest przestepny, przyda sie w lutym
{
    return(( rok % 4 == 0 && rok % 100 != 0 ) || rok % 400 == 0 );
}
//----------------------------------------------------------------------------------
int weekDay( int year, int month, int day ) //funkcja sprawdza jaki dzien tygodnia przypada na date w latach 2000-2020
{
    int zliczacz;
    int m;
    switch( year ) //instrukcja podajaca jaki dzien przypada jako pierwszy w danym roku
    {
    case 2000:
        zliczacz = 5; break;
    case 2001:
        zliczacz = 0; break;
    case 2002:
        zliczacz = 1; break;
    case 2003:
        zliczacz = 2; break;
    case 2004:
        zliczacz = 3; break;
    case 2005:
        zliczacz = 5; break;
    case 2006:
        zliczacz = 6; break;
    case 2007:
        zliczacz = 0; break;
    case 2008:
        zliczacz = 1; break;
    case 2009:
        zliczacz = 3; break;
    case 2010:
        zliczacz = 4; break;
    case 2011:
        zliczacz = 5; break;
    case 2012:
        zliczacz = 6; break;
    case 2013:
        zliczacz = 1; break;
    case 2014:
        zliczacz = 2; break;
    case 2015:
        zliczacz = 3; break;
    case 2016:
        zliczacz = 4; break;
    case 2017:
        zliczacz = 6; break;
    case 2018:
        zliczacz = 0; break;
    case 2019:
        zliczacz = 1; break;
    case 2020:
        zliczacz = 2; break;
    }
    for( m = 1; m <= month; m++ ) //tutaj do zliczacz dodawane sa kolejne dni do daty
    {
        if( m == month ) //jeżeli miesiąc to styczeń
        {
            zliczacz = zliczacz + day;
            break;
        }
        if( m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10 || m == 12 ) //miesiące mające 31 dni
        {
            zliczacz = zliczacz + 31;
        }
        if( m == 4 || m == 6 || m == 9 || m == 11 ) //miesiące mające 30 dni
        {
            zliczacz = zliczacz + 30;
        }
        if( m == 2 ) //luty, funkcja sprawdza czy dany rok jest przestępny
        {
            zliczacz = zliczacz + 28;
            if( czyPrzestepny( year ) == 1 )
            {
                zliczacz++;
            }
        }
    }
    zliczacz = zliczacz % 7; //reszta mowi nam jaki to dzien tygodnia
    return zliczacz;
}
//----------------------------------------------------------------------------------
int workingDay( int initYear, int initMonth, int initDay, int finalYear, int finalMonth, int finalDay ) //funkcja zlicza dni robocze
{
    int r, m, d, H;
    for( r = initYear; r <= finalYear; r++ ) //petla "roczna"
    {
        for( m = initMonth; m <= 12; m++ ) //petla "miesieczna"
        {
            initMonth = 1;
            if( m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10 || m == 12 ) //miesiące mające 31 dni
            {
                for( d = initDay; d <= 31; d++ ) //petla "dzienna"
                {
                    if( weekDay( r, m, d ) == 1 || weekDay( r, m, d ) == 2 || weekDay( r, m, d ) == 3 || weekDay( r, m, d ) == 4 || weekDay( r, m, d ) == 5 )
                    {
                        H++;
                        if( r == finalYear && m == finalMonth && d == finalDay )
                        {
                            return H;
                        }
                    }
                }
            }
            if( m == 4 || m == 6 || m == 9 || m == 11 ) //miesiące mające 30 dni
            {
                for( d = initDay; d <= 30; d++ ) //petla "dzienna"
                {
                    if( weekDay( r, m, d ) == 1 || weekDay( r, m, d ) == 2 || weekDay( r, m, d ) == 3 || weekDay( r, m, d ) == 4 || weekDay( r, m, d ) == 5 )
                    {
                        H++;
                        if( r == finalYear && m == finalMonth && d == finalDay )
                        {
                            return H;
                        }
                    }
                }
            }
            if( m == 2 ) //luty
            {
                if( czyPrzestepny( r ) == 1 )
                {
                    for( d = initDay; d <= 29; d++ ) //petla "dzienna"
                    {
                        if( weekDay( r, m, d ) == 1 || weekDay( r, m, d ) == 2 || weekDay( r, m, d ) == 3 || weekDay( r, m, d ) == 4 || weekDay( r, m, d ) == 5 )
                        {
                            H++;
                            if( r == finalYear && m == finalMonth && d == finalDay )
                            {
                                return H;
                            }
                        }
                    }
                }
                else
                {
                    for( d = initDay; d <= 28; d++ ) //petla "dzienna"
                    {
                        if( weekDay( r, m, d ) == 1 || weekDay( r, m, d ) == 2 || weekDay( r, m, d ) == 3 || weekDay( r, m, d ) == 4 || weekDay( r, m, d ) == 5 )
                        {
                            H++;
                            if( r == finalYear && m == finalMonth && d == finalDay )
                            {
                                return H;
                            }
                        }
                    }
                }
            }
            initDay = 1;
        }
    }
    return H;
}
//----------------------------------------------------------------------------------
int main()
{
    int a, b, c, x, y, z;
    cout << "Podaj poczatkowa date (rok, miesiac, dzien)" << endl;
    cin >> a >> b >> c;
    cout << "Podaj koncowa date (rok, miesiac, dzien)" << endl;
    cin >> x >> y >> z;
    cout << "Lczba dni roboczych miedzy tymi datami wynosi: " << workingDay( a, b, c, x, y, z );
    return 0;
}
P-122655
DejaVu
» 2014-12-10 23:46:29
Sprawdź czy standardowe wyjście programu jest sformatowane zgodnie z treścią zadania (włącznie z przejściami do nowego wiersza). Poza tym algorytmy weryfikujące poprawność działania aplikacji nie podają zbioru danych na których aplikacja jest testowana, więc prawdopodobnie to Twoja aplikacja działa źle.
P-122660
Germaniero
Temat założony przez niniejszego użytkownika
» 2014-12-11 00:49:37
Zgodnie z treścią zadania, testy sprawdzają co zwraca funkcja, a zwraca dni robocze, więc to jest dobrze. Akurat te testy podają jakie wartości były sprawdzane (i u mnie wychodzą prawidłowe wyniki), tutaj przykład loga:
* Blad! Dla daty poczatkowej: 2014.1.6 i daty koncowej: 2014.1.10 spodziewano sie wyniku: 5 a otrzymano: 7 *
* Blad! Dla daty poczatkowej: 2001.2.1 i daty koncowej: 2001.2.28 spodziewano sie wyniku: 20 a otrzymano: 28 *

*** Testy: 50% ***
P-122670
DejaVu
» 2014-12-11 02:37:48
Masz jawną informację, że masz błędny wynik, jawnie informuje Cię jaki powinien być wynik, więc znajdź błąd w swoim programie.

Napisałem program, który moim zdaniem działa poprawnie, ale nie przechodzi testów, natomiast gdy manualnie testuje program przy użyciu tych samych zmiennych, które pokazały błąd w testach automatycznych - wszystkie obliczenia są prawidłowe.
Zupełnie coś innego wynika z logów które przedstawiłeś. Program powinien się zachowywać deterministycznie, więc na Twoim komputerze zapewne również zwraca zły wynik.
P-122672
Monika90
» 2014-12-11 08:08:27
Niezdefiniowane zachowanie w linii 99
H++;

powód: zmienna H niezainicjalizowana
P-122673
Germaniero
Temat założony przez niniejszego użytkownika
» 2014-12-11 16:35:45
DejaVu, Monika90, wielkie dzięki za pomoc! Pogłówkowałem i znalazłem - w złym miejscu umieściłem wyjścia z funkcji w przypadku nastania końcowej daty. Temat do zamknięcia.
P-122692
« 1 »
  Strona 1 z 1