błędna odp. / SPOJ

Odpowiedz Nowy wątek
2011-08-22 02:12
gubbi
0
#include<iostream>
#include<sstream>
#include<string>
using namespace std;
 
int main(){
  ios_base::sync_with_stdio(0);
  short i=0, j, k;
  string d[3], *w = d;
  string::iterator it;
  stringstream ss, ss2, ss3, ss4, ss5;
  while(cin>>*w>>*w>>*(w+1)>>*(w+1)>>*(w+2)>>*(w+2)>>*(w+2)){
   while(i<3){
    if(i<2){
      it = (*w).begin();
      if('A'>*it || *it>'Z'){
         cout<<i<<endl; break;
      }
      if('A'<=*it<='Z')
         for(it++; it != (*w).end(); it++)
                   if('a'>*it || *it>'z')
                          if(*it != ';'){
                              cout<<i<<endl;
                              i=3; break;
                          }
    }
    if(i==2){
          string mm(*w, 5, 2), dz(*w, 8, 2);
          stringstream ss, ss_, ss__;
          ss<<*w; ss>>j;
          if(1900>j || j>2000){ cout<<i<<endl; break; }
          ss_<<mm; ss_>>j;
          if(1>j || j>12){ cout<<i<<endl; break; }
          ss__<<dz; ss__>>j;
          if(1>j || j>31){ cout<<i<<endl; break; }
          cout<<3<<endl;
     }
      *w++; i++;
   }
   w=d; i = 0;                   
  }  
  return 0;                  
}

Wie ktoś może dlaczego spoj wywala błędną odp. dla zadania link
Myśle, że błąd pojawia się przy sprawdzaniu daty, chociaż ja uważam że wszystko jest okey, ale coś nie gra...

link nie działa - notexists 2011-08-22 02:51

Pozostało 580 znaków

2011-08-22 11:45
GUBBI
0

Tutaj jeszcze raz odnośnik do tego zadania

Pozostało 580 znaków

2011-08-22 11:51
0

IMHO, tutaj może być błąd:

if('A'<=*it<='Z')

Jeżeli to jest ok, to proszę mnie nie bić! ;)


składniowo jest poprawne, ale dział inaczej niż autor sobie planuje ;) - byku_guzio 2011-08-22 12:23

Pozostało 580 znaków

2011-08-22 12:44
GUBBI
0
Patryk27 napisał(a)

IMHO, tutaj może być błąd:

if('A'<=*it<='Z')

To jest akurat dobrze. Pozwoliłem się trochę pomęczyć i rozłożyłem date co odziwo zostało zaakceptowane :)

#include<iostream>
#include<sstream>
#include<string>
using namespace std;
 
int main(){
  ios_base::sync_with_stdio(0);
  short i=0, j, k;
  string d[3], *w = d;
  string::iterator it;
  stringstream ss, ss2, ss3, ss4, ss5;
  while(cin>>*w>>*w>>*(w+1)>>*(w+1)>>*(w+2)>>*(w+2)>>*(w+2)){
   while(i<3){
    if(i<2){
      it = (*w).begin();
      if('A'>*it || *it>'Z'){
         cout<<i<<endl; break;
      }
      if('A'<=*it<='Z'){
         for(it++; it != (*w).end(); it++){
                   if('a'>*it || *it>'z') {
                          if(*it != ';'){
                              cout<<i<<endl;
                              i=3; break;
                          }
                   }
         }
      }
    }
    if(i==2){
          stringstream ss, ss2, ss3, ss4, ss5;
          it = (*w).begin();
          ss<<*w; ss>>j;
          if(1900>j || j>2000){ cout<<i<<endl; break; }
          ss2<<*(it+5); ss2>>j;
          if(0>j || j>1) { cout<<i<<endl; break; }
          ss3<<*(it+6); ss3>>k;
          if(j==0)
           if(0>=k || k>9) { cout<<i<<endl; break; }
          if(j==1)
           if(0>k || k>2) { cout<<i<<endl; break; }
          ss4<<*(it+8); ss4>>j;
          if(0>j || j>3) { cout<<i<<endl; break; }
          ss5<<*(it+9); ss5>>k;
          if(j==0)
           if(0>=k || k>9) { cout<<i<<endl; break; }
          if(j==1)
           if(0>k || k>9) { cout<<i<<endl; break; }
          if(j==2)
           if(0>k || k>9) { cout<<i<<endl; break; }
          if(j==3)
           if(0>k || k>1) { cout<<i<<endl; break; }
          cout<<3<<endl;
     }
      *w++; i++;
   }
   w=d; i = 0;                   
  }  
  return 0;                  
}

Problem na 99% leży w dacie. Ale nie wiem dlaczego spoj nie chcę zaakceptować krótszej wersji?

to 'A'<=*it<='Z' NIE JEST dobrze, zapewniam cię... - Shalom 2011-08-22 12:47

Pozostało 580 znaków

2011-08-22 13:02
GUBBI
0

@Shalom, dlaczego tak uważasz? skoro spoj akceptuje to musi być okey

Pozostało 580 znaków

2011-08-22 13:08
0

Kod:

'A'<=*it<='Z'

Jest równoważny temu:

('A'<=*it)<='Z'

Język C/ C++ akceptuje różne dziwne rzeczy w ifie, pozwala porównywać wartości dowolnych typów np: if('a' < false), if(5 + true), if(a = false) itp itd To, że się coś w C/ C++ kompiluje nie oznacza, że działa tak jak wygląda :P

Przeanalizujmy sobie ten kawałek kodu:

if(i<2){
      it = (*w).begin();
      if('A'>*it || *it>'Z'){
         cout<<i<<endl; break;
      }
      if('A'<=*it<='Z'){
         for(it++; it != (*w).end(); it++){
                   if('a'>*it || *it>'z') {
                          if(*it != ';'){
                              cout<<i<<endl;
                              i=3; break;
                          }
                   }
         }
      }
    }

Jest tam coś takiego:

if('A'>*it || *it>'Z'){
         cout<<i<<endl; break;
      }

Oznacza to, iż gdy *it nie jest dużą literą to następuje break; a więc następujący po tym kod nie będzie wykonywany.

Następujący po tym kod jest taki:

if('A'<=*it<='Z'){
         for(it++; it != (*w).end(); it++){
                   if('a'>*it || *it>'z') {
                          if(*it != ';'){
                              cout<<i<<endl;
                              i=3; break;
                          }
                   }
         }
      }

Warunek:

'A'<=*it<='Z'

Dla zawsze true, ponieważ jest równoważny ('A'<=it)<='Z', czyli zależnie od wartości it dostaniemy true<='Z', albo false<='Z'. 'Z' jest większe zarówno od true (1) jak i false (0), tak więc warunek jako całość będzie zawsze równy true.

Mimo tego warunek wydaje się spełniać swoją rolę, ale to tylko dzięki temu, że wygląda jak przeciwieństwo warunku z poprzedniego ifa, a jeżeli warunek z poprzedniego ifa jest spełniony, to następny if nie będzie nawet wykonywany (tzn nawet sam warunek nie będzie sprawdzany).


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
edytowany 1x, ostatnio: Wibowit, 2011-08-22 13:22

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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