• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

na wejściu niekreślona liczba zestawów danych

Object Storage Arubacloud
0 głosów
477 wizyt
pytanie zadane 1 listopada 2016 w C i C++ przez Kuba321 Użytkownik (730 p.)
Witam!

Nie mogę sobie poradzić z żadnym zadaniem ze SPOJ'a, w którym na wejściu pojawia się nieokreślona liczba danych/zestawów danych. Próbowałem rozwiązywać tego typu zadania nieskończoną pętlą for, ale otrzymuję (zresztą słusznie) komunikat "Przekroczono limit czasu". Kombinowałem też z pętlą while, w której warunku umieściłem cin. Powyższe rozwiązanie działało na SPOJ'u, ale nie rozumiem, dlaczego, kiedy próbowałem testować to na swoim komputerze, nie działało. Proszę o wytłumaczenie mi, w jaki sposób należy rozwiązywać takie zadania, ewentualnie, w jaki sposób SPOJ sygnalizuje koniec zestawów danych.

Pozdrawiam,

Kuba
komentarz 1 listopada 2016 przez niezalogowany
Podaj przykład zadania, które ma takie wymaganie
komentarz 1 listopada 2016 przez DragonCoder Nałogowiec (36,500 p.)
I podaj przyklad rozwiazania, jako przyklad moze w kodzie znajdziemy blad
komentarz 1 listopada 2016 przez Kuba321 Użytkownik (730 p.)

Na problem natknąłem się rozwiązując zadanie stos, choć z tego samego powodu nie potrafiłem rozwiązać zadania tablica i kolejka. Przykładowy kod, który przyjął spoj:

#include <cstdio>
#include <iostream>

using namespace std;

char znak;
int liczba, adres = 0;

int main()
{
    int *tab;
    tab = new int [10];
    while(cin >> znak)
    {
        if(znak=='+')
        {
            scanf("%d", &liczba);
            if(adres<10)
            {
                printf(":)\n");
               *(tab+adres)=liczba;
               adres++;
            }
            else printf(":(\n");
        }
        else if(znak=='-')
        {
            if(adres>0)
            {
                printf("%d\n",*(tab+adres-1));
                adres--;
            }
            else printf(":(\n");
        }
    }
    delete [] tab;

    return 0;
}

A to kod, którego SPOJ nie przyjął, choć wydaje mi się, że działa tak samo:

#include <cstdio>
#include <iostream>

using namespace std;

char znak;
int liczba, adres = 0;

int main()
{
    int *tab;
    tab = new int [10];
    for(;;)
    {
        scanf("%c", &znak);
        if(znak=='+')
        {
            scanf("%d", &liczba);
            if(adres<10)
            {
                printf(":)\n");
               *(tab+adres)=liczba;
               adres++;
            }
            else printf(":(\n");
        }
        else if(znak=='-')
        {
            if(adres>0)
            {
                printf("%d\n",*(tab+adres-1));
                adres--;
            }
            else printf(":(\n");
        }
    }
    delete [] tab;

    return 0;
}

 

1 odpowiedź

0 głosów
odpowiedź 1 listopada 2016 przez niezalogowany
wybrane 1 listopada 2016 przez Kuba321
 
Najlepsza
Nie działa tak samo. Nieskończona pęta jest nieskończona. A pętla WHILE

while(cin >> znak)

 

działa DOPÓKI( wczytanie znaku udało się)

Są robione dwie rzeczy na raz. Wczytanie znaku oraz sprawdzenie, czy się udało. Choć mieszanie scanf() pochodzącego z C oraz cina z C++ pomysłem jest takim sobie. Raczej stosuj CIN wszędzie zamiast scanf, a w while możesz dać

 

while ( !cin.eof() )

który zbada, czy dotarł do końca
komentarz 1 listopada 2016 przez Kuba321 Użytkownik (730 p.)
Stosuję mieszane cin i scanf, bo dowiedziałem się, że scanf jest szybsze od cin'a i rzeczywiście w paru poprzednich zadaniach dodanych przeze mnie na spoj'a różnica wynosiła około 0,02s, a to już coś ;). Nie wiem natomiast, czy stosowanie ich na raz grozi jakimiś konsekwencjami. Chciałem się jeszcze zapytać, o co chodzi z tym końcem i w jaki sposób jest to sygnalizowane, bo np. ja mogę wklepywać w ten program przyjęty przez spoj'a masę enterów, liczb, plusów, minusów, a i tak nie chce się skończyć.
komentarz 1 listopada 2016 przez niezalogowany
No jest szybsze, bo to język C, niskopoziomowy język i scanf pewnie prosto czyta z wejścia i już. A cin to obiekt w języku C++, wysokopoziomowy obiekt. Tyle, że jak potrzebujesz C to pisz w C, zwłaszcza na tym etapie nauki. Jak zostaniesz mistrzem, zastanowisz się, jak zaoszczędzić 0,02s w SPOJ.

EOF w linuksie/macosie wywołuje się przez Ctrl+D. W DOSie było bodajże Ctrl+Z, ale jednemu z moich uczniów nie działało w Windows, więc nie wiem, może w CMD zmienili. Choć internet wskazuje, że powinno działać.

Jak coś, użyj po prostu konsoli:

type plik_z_danymi.txt | twoj_program.exe

Podobne pytania

0 głosów
2 odpowiedzi 381 wizyt
0 głosów
0 odpowiedzi 389 wizyt
pytanie zadane 10 listopada 2019 w Python przez xvisox Nowicjusz (140 p.)
0 głosów
2 odpowiedzi 4,330 wizyt
pytanie zadane 22 lipca 2015 w C i C++ przez Lucek1906 Nowicjusz (240 p.)

92,579 zapytań

141,429 odpowiedzi

319,657 komentarzy

61,962 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...