26 / 46
Dec 2019

Nie rozumiem pytania - cin służy do wczytywania.

Problem polega między innymi na tym, że twoje rozwiązanie nie jest poprawne nawet dla testów przykładowych z zadania, więc będzie WA.

I tu pytanie, czy Ty testujesz swoje rozwiązanie i jeżeli tak to jak?

Można testować u siebie, albo na ideone.com6 - po wklejeniu przykładowego wejścia z zadania lub swojego/innego testu do okienka stdin : https://ideone.com/LE9LpC7 [podałeś błędny - nie kompilujący się kod, poprawiłem go, tylko tak aby się kompilował].

W twoim programie, wszystkie cout << "login...., cout << "register .... są zbędne i są błędem. Wczytywanie danych też masz błędne.
Poprawnie możesz tak jak zaproponował @hipcia:

int main () {
  // deklaracja potrzebnych zmiennych - 
while (cin >> command >> attemps) {//powtarzaj, dopóki są jeszcze dane do wczytania
     if (command == "register") {
           //twój kod obsługujący rejestrację powtórony attemps razy
          }
      else { 
          // twój kod obsługujący logowanie powtórzony attemps razy
          }
}

PS
Jeżeli wzorujesz się na stylu Stańczyka, to jego książka nie jest do nauki języka C++, a dodatkowo jest już nieco przestarzała.

Makra w C++ to spadek po języku C, i w C++14 np.: zamiast makra FOREACH:

 FOREACH(it, account){
        cout << it->first << " " << it->second << "\n";
    }

można i jest to dużo lepiej:

for (auto i : account)
        cout << i.first << ' ' << i.second << '\n';

itd.

@narbej Range-based for pojawił się w C++11. Dodałbym również referencję do deklaracji typu, ponieważ std::pair nie można trywialnie kopiować.

Ty to wiesz, ja to wiem, ale chodziło mi tylko i wyłącznie o to, że na spoju jest już dostępny właśnie C++14, a nie C++11, 17 czy 20.

Testuje swoje rozwiązania w cmd w visual studio code przy użyciu komendy a.exe, natomiast nie wiem jak dokładnie działa sędzia na spoju. Ten link który mi podałeś https://ideone.com/LE9LpC8 to w stdout sędzia otrzymuje takie wyjście?

Tak - przynajmniej starać się rezygnować.
Nie - makra, a szczególnie przedstawione w książce Algorytmika praktyczna … miały zwiększyć szybkość i wygodę kodowania, a nie szybkość samego wynikowego programu jako takiego. Oczywiście ktoś może twierdzić, że wstawienie kodu do programu [rozwijanie makr] daje szybszy kod, niż kod z wywołaniami funkcji - ale przecież są też funkcje inline…

Może nie dokładnie - w końcu, oprócz najprostszego sędziego [programu] są także czasami specjalne programy pisane przez autora zadania.
Ogólnie twój program “potraktowany” zostaje testem - przekierowanie pliku i produkuje odpowiedzi - też przekierowane zostaje do pliku. Potem już tylko porównanie pliku przygotowanego przez autora z twoim.

Czyli jeżeli testujesz u siebie w cmd - używając klawiatury, to jest to dobry sposób tylko dla prostych zadań. Dla trudniejszych, możesz przygotować plik/i testowe in.txt, oraz wynikowy out.txt [np kopijąc z zadania]
Potem:

C:\....> twój_program.exe < in.txt >twoj_out.txt [ENTER]

Poczytaj, o przekierowaniach.

Teraz pozostaje już tylko porównać [najlepiej programowo]:

c:\...> jakis_diff.exe  twoj_out.txt   out.txt  [ENTER]

Dodatkowo możesz “opakować” [samo] testowanie w automatyczny pomiar czasu, ale wtedy musisz przygotowywać swoje większe testy, bo dla małych nie ma to sensu.

Ja używam linuxa i czasami robię/robiłem podobnie …, teraz częściej korzystam z ideone.

Teraz zacząłem testować swój kod na stronie ideone.com1 i teraz spotkałem się z takim problemem, że nie wiem dlaczego na tym serwisie niepoprawnie porównuje mi tablice znaków tzn.

  • mam funkcje is_login_contain_illegal_char w której porównuje mi znaki z loginu do tablicy znaków AsciiSpecialCharacter z tymi specjalnymi znakami, które nie powinny znajdować się w loginie.
  • następnie funkcja ta dla każdego znaku zwraca informacje, że każda litera jest znakiem specjalnym.


Tutaj jest wynik programu
tablica AsciiSpecialChar znajduje się w 28 linicie,
a funkcja is_login_contain_special_character w 128 linijce.

Dodam jeszcze, że u mnie działa na komputerze tylko mam problem na tej stronie.

Krótko:
Linia 134 wtwoim kodzie jest błędna i powinna Cię dodatkowo skłonić do przemyślenia plusów i minusów używania makr.

Pochwała:
Skupiłem się tylko na tej jednej funkcji - w linii 128 i brawo, że sam potrafiłeś to zdiagnozować.

Maleńka krytyka:

  1. Twój program jest zdecydowanie za długi i twój sposób sprawdzania - pętla zagnieźdźona w pętli może okazać się za wolny.
  2. Masz dużo inkludów - wszystkichg potrzebujesz? - ogranicz ich liczbę tylko do potrzebnych, lub zastosuj:
    #include <bits/stdc++.h> <— lista wszystkich bibliotek w STL, ale czy działa pod windows? To też nie jest to dobre ale …
  3. To jak z tymi makrami? Rezygnujesz? :wink: Masz makra na first i last, a w programie ich nie wykorzystujesz:
    cout << it.first << " " << it.second << "\n";
    zamiast:
    cout << it.ST << " " << it.ND << "\n";
    Możliwe, że jest więcej - ale nie przęglądałem dokładnie twojego kodu.
  4. tablica: static char AsciiSpecialCharacters[32] = {'!', '"', '#', '$', '%', '&', '*', ..... jest globalna, więc nie musisz zaznaczać, static.
  5. można: char AsciiSpecjal[] = "!#$%&*@..........";
  6. Lepiej string AsciiSpecjal = "!#$%&*@..........";
  7. lub: string AsciiSpecjal {"!#$%&*@.........."};
  8. Można to sprawdzić łątwiej i krócej, ale miało być krótko :wink:
  9. No i jeszcze te śmieci [komentarze na końcu]
  10. Ale się nie przejmuj, walcz, a jak coś pytaj śmiało.

Dzięki za wszystkie rady @narbej oraz @hipcia w końcu dostałem AC.
Rezygnuje z makr, ponieważ gdybym z nich nie korzystał to bym program skończył około 2 tygodnie temu.

Gratuluję!!

Brawo, cieszy mnie to.

PS
Ale zdajesz sobie sprawę, że spoj nie potrafi ocenić jakości kodu? Mógłbym ewentualnie podać Ci trochę wskazówek i trochę krytyki twojego kodu, gdybyś chciał.

Ok
Potraktuj to jako swego rodzaju prezent pod choinkę :wink:

Dotyczy to twojego starego kodu, w nowym, może część rzeczy pozmieniałeś/usunąłeś.

  1. // https://p…content-available-to-author-only…j.com/problems/FR_07_03/ <-- ten link jest błędny :wink:
  2. Nadmiar importowanych bibliotek, na zapas nie jest dobry, ale jeżeli jednak chcesz to robić, to możesz wypróbować:
    #include <bits/stdc++.h> <— włączasz wszystkie/większość bibliotek.
  3. Używanie using namespace std; + pkt.1 ułatwia pisanie prostych - krótkich kodów, ale może spowodować konflikt/y nazw. Spróbuj na przykład użyć do swojej zmiennej nazwy time.
  4. Jeżeli dołączasz jawnie [nie bits/stdc++.h] wiele bibliotek, to czasami warto wiedzieć, jakie są tam ukryte skarby :wink: Np. <cctype> zawiera miedzy innymi isdigit(), isupper(), islower(), toupper()… itd.
  5. Pisałem już wcześniej o tablicy, ale jeszcze do samej nazwy: AsciiSpecialCharacters znaki i char to prawie zamienniki, albo to samo ale w różnych językach a dodatkowo natychmiast kojarzą się z tablicą kodów ASCII. W takim razie nazwa tablicy mogłaby brzmieć np: charSpecial, ale gdy dodamy typ zmiennej, to: char charSpecjal, wydaje się nadmiarowa i że nazwa char specjal[] wystarczy. Przecież, z załaczonego linku do zadania a i z samego kodu wynika, że nie chodzi tu przecież o piwo.
  6. map<string, string> account; <-- [wyjątkowo] można zrobić globalną, w przeciwieństwie do tablicy specjal, która potrzebna jest tylko funkcji register. Można też utworzyć i zamknąć to wszystko w klasie, ale to już inna bajka.
  7. …zostało jeszcze sporo, a może i tak to nie aktualne?

Łatwiej może będzie jak po prostu wyślę Ci mój pierwszy kod na PM i sam sobie spróbujesz porównać i się czegoś nauczyć?

        if(numberOccurence == false) FOR(n, 48, 57){
            if((char)(n) == password[i]){
                numberOccurence = true;
            }
        }

Powyższy blok, jeżeli chciałbym to robić w tym samym duchu, ja zapisałbym:

FOR (n, '0', '9')
   

a naprawdę należy inaczej przeprogramować pętlę np:

dla kolejnego znaku c w haśle:
      jeżeli jest to cyfra <np isdigit(c)> to zaznacz
      else jeżeli to wielka litera .... to zaznacz
      else jeżeli mała zaznacz
      w przeciwnym wypadku, jeżeli to nie cyfra, mała ani duża litera to jest znakiem specjalnym  zaznacz to

funkcje isdigit(), isupper(), islower() są bardzo proste, można skorzystać z biblioteki <cctype> lub napisać własne, np:

bool isdigit (char c) {
   return (c >= '0' and c <= '9')
}
char tolower (char c) {
       if (isupper (c)) c += 'a' - 'A';
       return c;
}
5 months later

Witam,
Zrobiłem kod, który działa u mnie dobrze lecz po przesłaniu do sędziego wywala mi komunikat: błąd wykonania (SIGXFSZ)

Nie jestem pewien też czy dobrze zrozumiem to zadanie.

Wejście składa się z nieokreślonej ilości wierszy. W pierwszej kolejności znajduje się jeden z dwóch napisów: “register” lub “login” oznaczających rejestrację i logowanie do konta.
Po określeniu czynności widnieje niewielka ilość x działań do wykonania przez program. W kolejnych x linijkach, znajdują się login i hasło.

Co to znaczy? Mam zrobić nieskończoną pętle tak jak zrobiłem? Kompletnie nie mam pojęcia jak to zinterpretować. A jeśli program miałby przerwać pętle i zakończyć działanie to jaka reakcja ma to wywołać?

Poniżej macie mój kod:

na ideone też się coś sypie, gdy ustawiam przykładowe wejście z zadania.

PS. Były dwa tematy odnośnie tego zadania. Mam nadzieję, że dobry odkopałem.

Ja wpisałem: “register & login” i znalazłem 4 wątki zawierające te dwa słowa.

Nie wystarczy odkopać i się dokleić. Potrzeba jeszcze spróbować przeczytać, zrozumieć i wykorzystać.

Nawet więcej, najpierw to co wyżej- przeczytać, a może się okazać zbednym, zadawanie pytania.

Możliwe, że tak nie lubisz czytać, jak ja nie lubię się powtarzać czy powtarzać tego, co inni już powiedzieli :wink:

Gdy podczas linijki
cin >> whatToDo >> how_many;
nie uda sie pobrac danych z powodu EOF to te 2 zmienne beda miec ta sama wartosc czy sie zmienią? (pytanie retoryczne)

Dzięki za odpowiedź.
Okazało się, że poza tym problem miałem też parę innych błędów w kodzie.

Już wydawało mi się, że wszystko rozwiązałem bo kod działa idealnie u mnie oraz na ideone.
Niestety sędzia dalej jest dla mnie bezlitosny ale tym razem pokazuje Błędna odpowiedź .

Wie ktoś może co przeoczyłem? Sporo się naszukałem błędów w kodzie i ponad 30 danych wejściowych przetestowałem. Wydaje mi się, że wszystko jest dobrze.

9 months later

Podepne się do tego komentarza, ponieważ nie znalazłem odpowiedzi. Czy macie jakieś podpowiedzi jak stworzyć pętle która wczytuje nieokreśloną liczbę wierszy i przerywa się kiedy nic nie podamy? Jak rozumiem, na przykładzie tego zadania while(cin>>whatToDo>>how_many) nie ma prawa działać? (wiem że sędzia nie uznaje tego za błąd, pytam z ciekawości)

Skąd wniosek, że tak się nie robi?

To jest jak najbardziej prawidłowe podejście.

Sądziłem że lepiej gdyby program kończył się po wpisaniu wszystkich danych. Tan program co przytoczyłeś da się chyba zakończyć jedynie wpisując coś co nie jest liczbą w miejsce attempts. Dopisanie jakiegoś “else break;” też nie działa gdy ktoś po prostu wciśnie enter. Jeśli tak się nie programuje to ok, nie znam się :smiley:po prostu mnie to ciekawiło