Τετάρτη, 3 Φεβρουαρίου 2016

To goto or not to goto Αυτό είναι το ερώτημα!

Υπάρχουν περιπτώσεις που η χρήση goto δίνει πιο συμπαγή και κατανοητό κώδικα.

Από ένα αλφαριθμητικό θέλουμε να βγάλουμε τους αριθμούς. Έχουμε φτιάξει έναν parser..δηλαδή ένα πρόγραμμα που διαβάζει τους χαρακτήρες και βλέπει αν έχουν αριθμό. Αυτό που δεν κοιτάει εδώ είναι το πόσα ψηφία σε κάθε νούμερο δίνουμε. Δεν μας πειράζει γιατί απλά το εμφανίζουμε στην οθόνη. Ένας αριθμός μπορεί να έχει πρόσημο ή όχι, να έχει ή όχι μία μόνο τελεία που να δείχνει τα δεκαδικά που μπορεί να είναι σε οποιαδήποτε θέση, αλλά σίγουρα μετά το πρόσημο. Ακολουθεί αριθμός αν υπάρχει διάστημα ή κόμμα. Τα αρχικά διαστήματα τα αφαιρούμε αλλά δεν δεχόμαστε διαστήματα χωρίς να ακολουθεί αριθμός, όπως και κόμμα δεν δεχόμαστε αν δεν ακολουθεί αριθμός.!

Και τα δύο προγράμματα είναι ισοδύναμα (δοκιμάστηκε και στη υπό δοκιμή 151 στη κανονική 147)

Δείτε μια μικρή ανάλυση του προβλήματος: Αν θέλουμε να βάλουμε για παράδειγμα έναν ακόμα έλεγχο, π.χ. να κοιτάμε αν υπάρχει το e για να πάρουμε επιστημονική μορφή (με e και πρόσημο) το δεύτερο πρόγραμμα χωρίς goto μεγαλώνει πολύ! Όμως το πρώτο με τα goto δεν θέλει πολλές αλλαγές! Και η απόδειξη είναι στο τέλος!



Παράδειγμα με Goto  (38 γραμμές)

Α$=" +.12, 1324342,+342.3, -1123.,13123.12323,.456,-.23423"
      Κ=Μήκος(Α$)
      Αν Κ=0 τότε έξοδος
      ι=1 
πάλι:
      Β$=Μεσ$(Α$,ι,1)
      προ=ψευδές
      δεκ=ψευδές
      κενά=ι
οκ5:
      Αν Β$=" " τότε κενά++ : προς οκ0
οκ4:
      Αν προ η δεκ Αλλιώς Αν Β$ ~ "[+-]" τότε προ~ : προς οκ1
      προ=αληθές
οκ3:
      Αν δεκ Αλλιώς Αν Β$ = "." τότε δεκ~ : προς οκ1
οκ2:
      Αν Β$ ~ "[1234567890]"  Αλλιώς Αν  ι=κ ή όχι Β$ ~ "[ ,]"  Τότε { λαθος "οχι αριθμός"} Αλλιώς Προς Άλλο
οκ1:
      ι++
      Αν ι>κ τότε Προς Άλλο
      Β$=Μεσ$(Α$,Ι,1) 
      Αν προ και όχι δεκ τότε προς οκ3
      Αν προ και δεκ τότε προς οκ2
      προς οκ4
οκ0:
      Αν ι<κ τότε ι++ : Β$=Μεσ$(Α$,Ι,1) : Προς οκ5
Άλλο:      
      Αν ι=κενα+1 και δεκ τότε Λαθος "μόνο τελεία"
      Αν ι=κενα+1 και προ τότε Λαθος "μόνο πρόσημο"
      Αν ι=κενα+2 και δεκ και προ τότε Λάθος "Δεν έχω αριθμό"
      Αν ι<=κενα τότε Λάθος "Δεν έχω αριθμό"
      Τύπωσε "Σωστός Αριθμός", Μες$(Α$, κενά, ι-κενά)
      ι++
      Αν ι<=κ τότε προς πάλι



Περίπτωση χωρίς Goto (59 γραμμές)

Α$=" +2123, 13.24342,+342.3, -1123.,13123.12323,.456,-.23423"
Κ=Μήκος(Α$)
Αν Κ=0 τότε έξοδος
ι=1
Ενώ ι<κ {
      Β$=Μεσ$(Α$,ι,1)
      κενά=ι
      προ=ψευδές
      δεκ=ψευδές
      εξ1=Ψευδές  \\ ειδική μεταβλητή
      Ενω Β$=" " και ι<κ {
            κενά++
            ι++
            Β$=Μεσ$(Α$,ι,1)
      }
      Αν Β$ ~ "[-+]" τότε  {
            προ=αληθές
            αν ι<κ τότε {
                  ι++ : Β$=Μεσ$(Α$,ι,1)
            } Αλλιώς { 
                  Λαθος "μόνο πρόσημο" 
            }
      }
      Αν Β$ = "." τότε {
            δεκ=Αληθές
            αν ι<κ τότε { 
                  Επανέλαβε {
                        ι++ : Β$=Μεσ$(Α$,ι,1) 
                        Αν Β$ ~ "[1234567890]"  Τότε {
                        \\ τίποτα
                        } Αλλιώς.Αν  ι=κ ή όχι Β$ ~"[, ]" Τότε {
                              Λάθος "Δεν έχω αριθμό"
                        } Αλλιώς εξ1=Αληθές : Έξοδος
                  } Μέχρι ι>=κ
            } Αλλιώς {
                  αν προ Αλλιώς Λαθος "μόνο τελεία"
                  Λάθος  "Δεν έχω αριθμό"
            }
      } αλλιώς {
      ι--
      }
      αν ι<κ και όχι εξ1 τότε { 
            Επανέλαβε {
                  ι++ : Β$=Μεσ$(Α$,ι,1) 
                  Αν Β$="." και όχι δεκ Τότε { 
                        δεκ=Αληθές
                  } Αλλιώς.Αν Β$ ~ "[1234567890]"  Τότε {
                  \\ τίποτα
                  } Αλλιώς.Αν  ι=κ ή όχι Β$ ~"[, ]" Τότε {
                        Λάθος "Δεν έχω αριθμό"
                  } Αλλιώς Έξοδος
            } Μέχρι ι>=κ
      }
      Αν ι=κενά+1 και δεκ τότε Λαθος "μόνο τελεία" 
      Αν ι=κενά+1 και προ τότε Λαθος "μόνο πρόσημο" 
      Αν ι=κενά+2 και προ και δεκ τότε Λάθος "Δεν έχω αριθμό"
      Τύπωσε "Σωστός Αριθμός", Μες$(Α$, κενά, ι-κενά)
      ι++
}
Με 5 γραμμές (σύνολο 43) επεκτάθηκε το πρόγραμμα με το Goto για να διαβάζει και επιστημονική μορφή (δέχεται πρόσημο μετά το e αλλά όχι τελεία). Ούτε θέλω να φανταστώ πώς θα αλλάξει το πρόγραμμα χωρίς τα goto για να δέχεται και αριθμούς με επιστημονική μορφή!

      Α$=" +.12, 13.24e-32,+342.3, -1123.,13123.123e+23,.456,-.23423"
      Κ=Μήκος(Α$)
      Αν Κ=0 τότε έξοδος
      ι=1 
πάλι:
      εκθ=ψευδές
      αριθ=ψευδές
      δεκ=ψευδές     
      κενά=ι
πάλι1:
      Β$=Μεσ$(Α$,ι,1)
      προ=ψευδές
οκ5:
      Αν Β$=" " τότε κενά++ : προς οκ0
οκ4:
      Αν προ η ( δεκ και όχι εκθ ) Αλλιώς Αν Β$ ~ "[+-]" τότε προ~ : προς οκ1
      προ=αληθές
οκ3:
      Αν δεκ και όχι εκθ Αλλιώς Αν Β$ = "." τότε δεκ~ : προς οκ1
οκ2:
      Αν Β$="e" και αριθ και όχι εκθ Τότε {
            εκθ=αληθές 
            Αν ι>=κ Τότε { λαθος "οχι αριθμός"}  αλλιώς  ι++ : Πρός πάλι1
      }
      Αν Β$ ~ "[1234567890]"  Αλλιώς Αν  ι=κ ή όχι Β$ ~ "[ ,]"  Τότε { λαθος "οχι αριθμός"} Αλλιώς Προς Άλλο
      αριθ=αληθές
οκ1:
      ι++
      Αν ι>κ τότε Προς Άλλο
      Β$=Μεσ$(Α$,Ι,1) 
      Αν προ και όχι δεκ τότε προς οκ3
      Αν προ και δεκ τότε προς οκ2
      προς οκ4
οκ0:
      Αν ι<κ τότε ι++ : Β$=Μεσ$(Α$,Ι,1) : Προς οκ5
Άλλο:      
      Αν ι=κενα+1 και δεκ τότε Λαθος "μόνο τελεία"
      Αν ι=κενα+1 και προ τότε Λαθος "μόνο πρόσημο"
      Αν ι=κενα+2 και δεκ και προ τότε Λάθος "Δεν έχω αριθμό"
      Αν ι<=κενα τότε Λάθος "Δεν έχω αριθμό"
      Τύπωσε "Σωστός Αριθμός", Μες$(Α$, κενά, ι-κενά)
      ι++
      Αν ι<=κ τότε προς πάλι









Δεν υπάρχουν σχόλια:

Δημοσίευση σχολίου