Παρασκευή 9 Φεβρουαρίου 2018

Γρήγορη Ταξινόμηση ΙΙ (χρήση ρουτινών, προχωρημένο)

Η γρήγορη ταξινόμηση όπως δόθηκε σε προηγούμενη ανάρτηση έχει γραφτεί πιο κοντά σε άλλες γλώσσες προγραμματισμού. Στη Μ2000 μπορούμε να επιλέξουμε τι μεταβλητές θα σκιάσουμε. Εκτός από την "κλήση τοπικά" για μια συνάρτηση έχουμε και την κλήση ρουτίνας. Οι ρουτίνες έχουν εξ ορισμού θέαση μεταβλητών στο τμήμα που καλούνται. Επιπλέον επειδή είναι "ελαφρύτερες" από μια συνάρτηση ή ένα τμήμα, μπορούν να κληθούν με χρήση της μνήμης ως "στοίβα επιστροφής". Έτσι το όριο αναδρομής μπορεί να μεγαλώσει (αφού ουσιαστικά η στοίβα είναι δομή στη μνήμη με "τεμάχια" και όχι συνεχόμενη). Ορίζουμε όριο αναδρομής μόνο για τυπικούς λόγους, δηλαδή να υπάρχει τρόπος αν έχουμε λάθος στο πρόγραμμα να τερματίσει με λάθος, και όχι όταν πάρει όλη την μνήμη!

Αν προσέξουμε λίγο το κώδικα θα δούμε ότι μόνο δυο μεταβλητές, η Μ1 και Λ, δηλαδή τα σημεία που ορίζουν το άνω όριο στις δυο λίστες που χωρίζουν την λίστα, χρειάζεται να μπαίνουν σε σκίαση. Σκίαση σημαίνει ότι αποθηκεύονται ενώ δημιουργούνται στην ίδια θέαση νέες μεταβλητές. Οι ρουτίνες όταν τερματίζουν διαγράφουν ότι νέο φτιάχτηκε, έτσι επαναφέρουν τις προηγούμενες τιμές.

Μέσα στη ρουτίνα ΓρήγορηΤαξινόμηση(λ) το π είναι ένα και μοναδικό. Προς το τέλος καλούμε πάλι τη ρουτίνα, σε δυο φάσεις. Στην πρώτη το π το αφήνουμε ως έχει, και μας ενδιαφέρει μόνο μια φορά να είναι το σωστό μέχρι να καλέσουμε πάλι τη πρώτη εσωτερική. Στη δεύτερη το Μ1 έχει ξεκινήσει από το π και κοιτάμε αν είναι μικρότερο του λ και αν είναι τότε καλούμε τη συνάρτηση με την λ, άρα και εδώ η σκίαση της λ είναι πλεονασμός και θα μπορούσαμε να είχαμε μια δεύτερη ρουτίνα (ίδια με την ΓρήγορηΤαξινόμηση αλλά χωρίς να παίρνει το λ, δεν βάζω αυτή την ρουτίνα και την αφήνω να το κάνει ο αναγνώστης, και να αλλάξει κατάλληλα τη δεύτερη κλήση και στις δυο πια ρουτίνες)



\\ Πρόγραμμα Γρήγορη Ταξινόμηση  ΙΙ
\\ 1) Χρήση του συστήματος σκίασης, έτσι ώστε μόνο ορισμένες μεταβλητές να σκιάζονται
\\ 2) Χρήση ρουτινών για αναδρομή
\\ Για τις ρουτίνες το όριο αναδρομής ξεφεύγει από τις μερικές χιλιάδες και φτάνει στα εκατομμύρια.
Όριο.Αναδρομής 1000000 'μπορούμε να ορίσουμε όριο ακόμα και ένα εκατομμύριο κλήσεις.

Κλάση ΑντικείμενοΤαξινόμησης {
      Γεγονός ΣύγκρινεΣτοιχείο {Διάβασε Νέο κ,}
      Γεγονός ΆλλαξεΣτοιχείο {Διάβασε Νέο Μ1, κ}
      Γεγονός ΘέσεΈνα {Διάβασε Νέο Μ1}
      πόσα=0
      Τμήμα ΓρήγορηΤαξινόμηση {
            \\ τα Μ, Ν, Μ2, ρ είναι κοινά επειδή καλούμε τοπικά!
            Τοπικές Μ2, ρ, π
            ' όλα τα ρ τα ελέγχουμε επιτόπου
            ' όλα τα Μ2 σχετίζονται με το Λ και τα δημιουργούμε πριν την αναδρομή
            ' Τα π ξεκινούν από το 0 και μετά παίρνουν τιμές μια φορά ως έχει και μια φορά από το Μ1
            Τρόπος$="ΑΥΞΟΥΣΑ"
            ' αν δώδουμε ? τότε θα παραμείνει η τιμή ως έχει
            ' ακόμα και αν δεν δώσουμε κάτι δεν πειράζει την Μ2000, αρκεί να μη έχει κάτι άλλο ο σωρός τιμών.
            ' για το λόγο αυτό καλό είναι αν θέλουμε την εξ ορισμού τιμή να δώσουμε το ? στην κλήση
            ' Στις συναρτήσεις όταν καλούνται ως συναρτήσεις δεν υπάρχει θέμα γιατί έχουν δικό τους σωρό τιμών
            ' εδώ όμως είναι τμήμα και το τμήμα κληρονομεί το σωρό τιμών αυτού που το καλεί.
            Διάβασε ? Τρόπος$
            Τρόπος$=Κεφ$(Τρόπος$)
            Αν Τρόπος$="ΑΥΞΟΥΣΑ" Τότε {
                  Ν=1
            } Αλλιώς.Αν Τρόπος$="ΦΘΙΝΟΥΣΑ" Τότε {
                  Ν=-1
            } Αλλιώς {
                  Λάθος "Άγνωστη Επιλογή"
            }
            Μ=-Ν
            Αν .πόσα>1 Τότε ΓρήγορηΤαξινόμηση(.πόσα-1)

            \\ υπάρχει μια ρουτίνα εδώ, και όταν ο διερμηνευτής φτάσει στον ορισμό τότε κάνει έξοδο!
            \\ οι ρουτίνες γράφονται στο τέλος του τμήματος.
            \\ Γίνεται αναζήτηση μια φορά και μετά καταγράφεται για να τρέχει άμεσα.
            \\ Οι ρουτίνες έχουν μεγάλο αριθμό κλήσεων με αναδρομή γιατί χρησιμοποιούν την μνήμη, και όχι το σωρό επιστροφής.
            \\ αρκεί να μην μεσολαβούν μπλοκ μνήμης.
            \\ εδώ δεν υπάρχει μπλοκ, οι κλήσεις γίνονται απ΄ευθείας μετά από μια Αν Τότε.
            Ρουτίνα ΓρήγορηΤαξινόμηση(λ)
                  '  το (λ)  στο όνομα ισοδυναμεί με αυτό: Διάβασε Νέο λ
                  ' το οποίο σκιάζει την υπάρχουσα λ με την χρήση του Νέο
                  Αν λ-π=1 Τότε {
                        Κάλεσε Γεγονός .ΘέσεΈνα λ
                        Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο π,
                        Αν ρ=Ν Τότε Κάλεσε Γεγονός .ΆλλαξεΣτοιχείο π, λ
                        Έξοδος Ρουτίνας ' βγαίνουμε από την ρουτίνα με την Έξοδο Ρουτίνας παρόλο που είμαστε σε μπλοκ.
                  }
                  Κάλεσε Γεγονός .ΘέσεΈνα (λ+π) δια 2
                  Τοπική Μ1=π ' σκιάζει την υπάρχουσα Μ1 όταν ορίζεται ως Τοπική
                  Μ2=λ
                  \\ εδώ ξεκινάει ο αλγόριθμος για να βρούμε τα Μ1 και Μ2
                  Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ1,
                  Ενώ ρ=Μ {
                        Μ1++
                        Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ1,
                  }
                    Επανέλαβε {
                       Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ2,
                         Ενώ ρ=Ν {
                               Μ2--
                              Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ2,
                        }
                        Αν Μ1<=Μ2 Τότε {
                              Κάλεσε Γεγονός .ΆλλαξεΣτοιχείο Μ1, Μ2
                              Μ1++
                              Μ2--
                        }
                        Αν Μ1>Μ2 Τότε Έξοδος
                        Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ1,
                        Ενώ ρ=Μ {
                              Μ1++
                              Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ1,
                        }
                 } Πάντα
                  ' Εδώ τα βρήκαμε!
                  Αν π<Μ2 Τότε ΓρήγορηΤαξινόμηση(Μ2)
                  π=Μ1 ' δεν μας ενδιαφέρει να κρατήσουμε το π
                  Αν Μ1<λ Τότε ΓρήγορηΤαξινόμηση(λ)
      Τέλος Ρουτίνας
      }
}
Φόρμα 80,50
Πίνακας πινακ$(10), παλιός$()
πινακ$(0)="Πρέβεζα","Πάτρα","Θάσος","Βόλος","Κέρκυρα" ,"Αθήνα" ,"Καρδίτσα","Καβάλα","Κάρπαθος","Κάρυστος"
παλιός$()=πινακ$()
\\ Φτιάχνουμε το αντικείμενο Ταξινόμησε
Ταξινόμησε=ΑντικείμενοΤαξινόμησης()
Ένα$=""
\\ Οι συναρτήσεις θα κληθούν με Κάλεσε Τοπικά
\\ ως κλήσεις προς τα πίσω, στο τμήμα
\\ έτσι θα έχουν θέαση στους πίνακες και την Ένα$
Συνάρτηση ΘέσεΈνα {
        Διάβασε Νέο κ
        Ένα$=πινακ$(κ)
}
Συνάρτηση ΣυγκρινεΣτοιχεία {
        Διάβασε Νέο κ ,
        μ=Τάξη(πινακ$(κ), Ενα$) ' Εδώ μπορεί να χρησιμοποιηθεί και η Σύγκρινε()
}
Συνάρτηση ΆλλαξεΣτοιχεία {
        Διάβασε Νέο Μ1, κ
        Αν Μ1<>Κ Τότε Άλλαξε πινακ$(Μ1), πινακ$(κ)
}
\\ Τώρα τροφοδοτούμε το αντικείμενο με τις συναρτήσεις
Για Ταξινόμησε {
      Γεγονός .ΘέσεΈνα Νέο Οκν$(&ΘέσεΈνα())
      Γεγονός .ΣύγκρινεΣτοιχείο Νέο Οκν$(&ΣυγκρινεΣτοιχεία())
      Γεγονός .ΆλλαξεΣτοιχείο Νέο Οκν$(&ΆλλαξεΣτοιχεία())
      .πόσα=10 ' δηλώνουμε ότι θα ταξινομηθούν τα δέκα πρώτα στοιχεία
}
Αναλυτής
      Ταξινόμησε.ΓρήγορηΤαξινόμηση ? ' το ? δηλώνει απροσδιόριστη είσοδο
Τύπωσε Γραφή$(Φόρτος,"0")
     Αναλυτής
           Ταξινόμησε.ΓρήγορηΤαξινόμηση ?
    Τύπωσε Γραφή$(Φόρτος,"0") , " χρόνος για ταξινόμηση ήδη ταξινομημένου πίνακα"
Για Μ1=0 Έως 9
      Τύπωσε πινακ$(Μ1), παλιός$(Μ1)
Επόμενο Μ1
παλιός$()=πινακ$()
Αναλυτής
      Ταξινόμησε.ΓρήγορηΤαξινόμηση "ΦΘΙΝΟΥΣΑ"
Τύπωσε Γραφή$(Φόρτος,"0")
Αναλυτής
      Ταξινόμησε.ΓρήγορηΤαξινόμηση "ΦΘΙΝΟΥΣΑ"
Τύπωσε Γραφή$(Φόρτος,"0") , " χρόνος για ταξινόμηση ήδη ταξινομημένου πίνακα"
Για Μ1=0 Έως 9
      Τύπωσε πινακ$(Μ1), παλιός$(Μ1)
Επόμενο Μ1
Πίνακας πινακ$(10)="Αθήνα"
παλιός$()=πινακ$()
Αναλυτής
      Ταξινόμησε.ΓρήγορηΤαξινόμηση "ΦΘΙΝΟΥΣΑ"
Τύπωσε Γραφή$(Φόρτος,"0") , " χρόνος για ταξινόμηση με όλα τα στοιχεία ίδια"
' Η Για είναι πιο γρήγορη αν την δηλώσουμε με μπλοκ εντολών
Για Μ1=0 Έως 9 {
            Τύπωσε πινακ$(Μ1), παλιός$(Μ1)
}

Με αναδρομή με χρήση απλών ρουτινών. Οι απλές ρουτίνες καλούνται με όνομα ή με αριθμό και επιστρέφουν με την Επιστροφή. Η βασική διαφορά τους με τις ρουτίνες με παρενθέσεις είναι ότι δεν σβήνουν ότι δημιουργούν άρα δεν μπορούμε να χρησιμοποιήσουμε σκίαση μεταβλητών. Εδώ λοιπόν φτιάχνουμε δυο μεταβλητές ως δείκτες σε σωρούς τιμών. Αντί να κάνουμε σκίαση τιμών, κάνουμε καταχώρηση σε σωρούς τιμών (ειδικές στοίβες), όπου με Βάλε βάζουμε στην κορυφή και με Διάβασε διαβάζουμε από τη κορυφή - αφαιρώντας αυτό που διαβάζουμε.
Εδώ η αναδρομή συνίσταται στο ότι καλεί η ρουτίνα τον εαυτό της. Η στοίβα επιστροφής τώρα είναι μικρότερη γιατί έχει μόνο την θέση επιστροφής, και όχι τα στοιχεία (δυο νούμερα στην ουσία επιπλέον) που διαγράφουν από ένα σημείο και μετά τα στοιχεία στις λίστες μεταβλητών και τμημάτων/συνάρτησεων (έτσι αφαιρεί την σκίαση η κλήση ρουτίνας με παρενθέσεις, ενώ η συνάρτηση και το τμήμα κρατούν στην πραγματική στοίβα επιστροφής τα στοιχεία αυτά. Η πραγματική στοίβα επιστροφής είναι αυτή του εκτελέσιμου αρχείου, του διερμηνευτή, της γλώσσας μηχανής δηλαδή).



Κλάση ΑντικείμενοΤαξινόμησης {
      Γεγονός ΣύγκρινεΣτοιχείο {Διάβασε Νέο κ,}
      Γεγονός ΆλλαξεΣτοιχείο {Διάβασε Νέο Μ1, κ}
      Γεγονός ΘέσεΈνα {Διάβασε Νέο Μ1}
      πόσα=0
      Τμήμα ΓρήγορηΤαξινόμηση {
            \\ τα Μ, Ν, Μ2, ρ είναι κοινά επειδή καλούμε τοπικά!
            Τοπικές Μ1, Μ2, ρ, π, λ, σΜ1, σλ
            σΜ1=Σωρός
            σλ=Σωρός
            Τρόπος$="ΑΥΞΟΥΣΑ"
            Διάβασε ? Τρόπος$
            Τρόπος$=Κεφ$(Τρόπος$)
            Αν Τρόπος$="ΑΥΞΟΥΣΑ" Τότε {
                  Ν=1
            } Αλλιώς.Αν Τρόπος$="ΦΘΙΝΟΥΣΑ" Τότε {
                  Ν=-1
            } Αλλιώς {
                  Λάθος "Άγνωστη Επιλογή"
            }
            Μ=-Ν
            Αν .πόσα>1 Τότε λ=.πόσα-1: Διαμέσου ΓρήγορηΤαξινόμηση
            Έξοδος
ΓρήγορηΤαξινόμηση:
                  Αν λ-π=1 Τότε Διαμέσου 3000 : Επιστροφή
                  Κάλεσε Γεγονός .ΘέσεΈνα (λ+π) δια 2
                  Σωρός σΜ1 { Βάλε Μ1}
                  Μ1=π
                  Μ2=λ
                  \\ εδώ ξεκινάει ο αλγόριθμος για να βρούμε τα Μ1 και Μ2
                  Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ1,
                  Ενώ ρ=Μ {
                        Μ1++
                        Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ1,
                  }
                    Επανέλαβε {
                       Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ2,
                         Ενώ ρ=Ν {
                               Μ2--
                              Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ2,
                        }
                        Αν Μ1<=Μ2 Τότε {
                              Κάλεσε Γεγονός .ΆλλαξεΣτοιχείο Μ1, Μ2
                              Μ1++
                              Μ2--
                        }
                        Αν Μ1>Μ2 Τότε Έξοδος
                        Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ1,
                        Ενώ ρ=Μ {
                              Μ1++
                              Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ1,
                        }
                 } Πάντα
                  ' Εδώ τα βρήκαμε!
                  Αν π<Μ2 Τότε Σωρός σλ { Βάλε λ} : λ=Μ2: Διαμέσου ΓρήγορηΤαξινόμηση : Σωρός σλ { Διάβασε λ}
                  π=Μ1 ' δεν μας ενδιαφέρει να κρατήσουμε το π
                  Αν Μ1<λ Τότε Διαμέσου ΓρήγορηΤαξινόμηση
                  Σωρός σΜ1 { Διάβασε Μ1}
                  Επιστροφή
      3000 Κάλεσε Γεγονός .ΘέσεΈνα λ
                  Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο π,
                  Αν ρ=Ν Τότε Κάλεσε Γεγονός .ΆλλαξεΣτοιχείο π, λ
               Επιστροφή
      }
}
Φόρμα 80,50
Πίνακας πινακ$(10), παλιός$()
πινακ$(0)="Πρέβεζα","Πάτρα","Θάσος","Βόλος","Κέρκυρα" ,"Αθήνα" ,"Καρδίτσα","Καβάλα","Κάρπαθος","Κάρυστος"
παλιός$()=πινακ$()
\\ Φτιάχνουμε το αντικείμενο Ταξινόμησε
Ταξινόμησε=ΑντικείμενοΤαξινόμησης()
Ένα$=""
\\ Οι συναρτήσεις θα κληθούν με Κάλεσε Τοπικά
\\ ως κλήσεις προς τα πίσω, στο τμήμα
\\ έτσι θα έχουν θέαση στους πίνακες και την Ένα$
Συνάρτηση ΘέσεΈνα {
        Διάβασε Νέο κ
        Ένα$=πινακ$(κ)
}
Συνάρτηση ΣυγκρινεΣτοιχεία {
        Διάβασε Νέο κ ,
        μ=Τάξη(πινακ$(κ), Ενα$) ' Εδώ μπορεί να χρησιμοποιηθεί και η Σύγκρινε()
}
Συνάρτηση ΆλλαξεΣτοιχεία {
        Διάβασε Νέο Μ1, κ
        Αν Μ1<>Κ Τότε Άλλαξε πινακ$(Μ1), πινακ$(κ)
}
\\ Τώρα τροφοδοτούμε το αντικείμενο με τις συναρτήσεις
Για Ταξινόμησε {
      Γεγονός .ΘέσεΈνα Νέο Οκν$(&ΘέσεΈνα())
      Γεγονός .ΣύγκρινεΣτοιχείο Νέο Οκν$(&ΣυγκρινεΣτοιχεία())
      Γεγονός .ΆλλαξεΣτοιχείο Νέο Οκν$(&ΆλλαξεΣτοιχεία())
      .πόσα=10 ' δηλώνουμε ότι θα ταξινομηθούν τα δέκα πρώτα στοιχεία
}
Αναλυτής
      Ταξινόμησε.ΓρήγορηΤαξινόμηση ? ' το ? δηλώνει απροσδιόριστη είσοδο
Τύπωσε Γραφή$(Φόρτος,"0")
     Αναλυτής
           Ταξινόμησε.ΓρήγορηΤαξινόμηση ?
    Τύπωσε Γραφή$(Φόρτος,"0") , " χρόνος για ταξινόμηση ήδη ταξινομημένου πίνακα"
Για Μ1=0 Έως 9
      Τύπωσε πινακ$(Μ1), παλιός$(Μ1)
Επόμενο Μ1
παλιός$()=πινακ$()
Αναλυτής
      Ταξινόμησε.ΓρήγορηΤαξινόμηση "ΦΘΙΝΟΥΣΑ"
Τύπωσε Γραφή$(Φόρτος,"0")
Αναλυτής
      Ταξινόμησε.ΓρήγορηΤαξινόμηση "ΦΘΙΝΟΥΣΑ"
Τύπωσε Γραφή$(Φόρτος,"0") , " χρόνος για ταξινόμηση ήδη ταξινομημένου πίνακα"
Για Μ1=0 Έως 9
      Τύπωσε πινακ$(Μ1), παλιός$(Μ1)
Επόμενο Μ1
Πίνακας πινακ$(10)="Αθήνα"
παλιός$()=πινακ$()
Αναλυτής
      Ταξινόμησε.ΓρήγορηΤαξινόμηση "ΦΘΙΝΟΥΣΑ"
Τύπωσε Γραφή$(Φόρτος,"0") , " χρόνος για ταξινόμηση με όλα τα στοιχεία ίδια"
' Η Για είναι πιο γρήγορη αν την δηλώσουμε με μπλοκ εντολών
Για Μ1=0 Έως 9 {
            Τύπωσε πινακ$(Μ1), παλιός$(Μ1)
}



Χωρίς καμία αναδρομή. Χρησιμοποιούμε ένα αντικείμενο σωρός για να κρατήσουμε το που θα ανακατευθύνουμε την ροή εκτέλεσης, με Από Προς (On Goto). Στο Τμήμα ΓρήγορηΤαξινόμηση έχουμε ένα σύστημα με τρεις σωρούς τιμών (κάθε σωρός είναι μια ειδική στοίβα και στην ουσία μια λίστα συνδεδεμένων στοιχείων), και όλες οι αλλαγές ροής γίνονται με Προς ετικέτα (παραμένει μια Διαμέσου για ευκολία). Ουσιαστικά εδώ δεν υπάρχει αναδρομή. Σε κάθε περίπτωση αυτό που θα λέγαμε βάθος κλήσης, είναι στην ουσία το μέγεθος του αντικειμένου που δείχνει ο δείκτης επ, ο σωρός επιστροφής. Εκεί αντί να βάζουμε τα νούμερα 5000, 1000, 2000, βάζουμε έμμεσα νούμερα, τα 1, 2 και 3 (επειδή η Μ2000 δεν έχει άλμα με μεταβλητή, χρησιμοποιούμε τον έμμεσο τρόπο τα 1,2,3 που γίνονται 5000,1000,2000 με την Από αριθμός Προς. Υπάρχει και η Από Αριθμός Διαμέσου για απλές ρουτίνες με επιστροφή).


 
Κλάση ΑντικείμενοΤαξινόμησης {
      Γεγονός ΣύγκρινεΣτοιχείο {Διάβασε Νέο κ,}
      Γεγονός ΆλλαξεΣτοιχείο {Διάβασε Νέο Μ1, κ}
      Γεγονός ΘέσεΈνα {Διάβασε Νέο Μ1}
      πόσα=0
      Τμήμα ΓρήγορηΤαξινόμηση {
            \\ τα Μ, Ν, Μ2, ρ είναι κοινά επειδή καλούμε τοπικά!
            Τοπικές Μ1, Μ2, ρ, π, λ, σΜ1, σλ, επ, επ1
            σΜ1=Σωρός
            σλ=Σωρός
            επ=Σωρός:=1
            Τρόπος$="ΑΥΞΟΥΣΑ"
            Διάβασε ? Τρόπος$
            Τρόπος$=Κεφ$(Τρόπος$)
            Αν Τρόπος$="ΑΥΞΟΥΣΑ" Τότε {
                  Ν=1
            } Αλλιώς.Αν Τρόπος$="ΦΘΙΝΟΥΣΑ" Τότε {
                  Ν=-1
            } Αλλιώς {
                  Λάθος "Άγνωστη Επιλογή"
            }
            Μ=-Ν
            Αν .πόσα>1 Τότε λ=.πόσα-1: Προς ΓρήγορηΤαξινόμηση
            Έξοδος
ΓρήγορηΤαξινόμηση:
                  Αν λ-π=1 Τότε Διαμέσου 4000 : Σωρός επ {Διάβασε επ1} : Από επ1 Προς 5000, 1000, 3000
                  Κάλεσε Γεγονός .ΘέσεΈνα (λ+π) δια 2
                  Σωρός σΜ1 { Βάλε Μ1}
                  Μ1=π
                  Μ2=λ
                  \\ εδώ ξεκινάει ο αλγόριθμος για να βρούμε τα Μ1 και Μ2
                  Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ1,
                  Ενώ ρ=Μ {
                        Μ1++
                        Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ1,
                  }
                    Επανέλαβε {
                       Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ2,
                         Ενώ ρ=Ν {
                               Μ2--
                              Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ2,
                        }
                        Αν Μ1<=Μ2 Τότε {
                              Κάλεσε Γεγονός .ΆλλαξεΣτοιχείο Μ1, Μ2
                              Μ1++
                              Μ2--
                        }
                        Αν Μ1>Μ2 Τότε Έξοδος
                        Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ1,
                        Ενώ ρ=Μ {
                              Μ1++
                              Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο Μ1,
                        }
                 } Πάντα
                  Αν π>=Μ2 Τότε 2000
                  Σωρός σλ { Βάλε λ} : λ=Μ2
                  Σωρός επ {Βάλε 2} : Προς ΓρήγορηΤαξινόμηση
      1000 Σωρός σλ { Διάβασε λ}
      2000 π=Μ1
                  Αν Μ1<λ Τότε Σωρός επ {Βάλε 3} : Προς ΓρήγορηΤαξινόμηση
      3000 Σωρός σΜ1 {Διάβασε Μ1}
                  Σωρός επ {Διάβασε επ1}
                  Από επ1 Προς 5000, 1000, 3000
      4000 Κάλεσε Γεγονός .ΘέσεΈνα λ
                  Κάλεσε Γεγονός .ΣύγκρινεΣτοιχείο π,
                  Αν ρ=Ν Τότε Κάλεσε Γεγονός .ΆλλαξεΣτοιχείο π, λ
                  Επιστροφή
        5000  ' τερματισμός
      }
}
Φόρμα 80,50
Πίνακας πινακ$(10), παλιός$()
πινακ$(0)="Πρέβεζα","Πάτρα","Θάσος","Βόλος","Κέρκυρα" ,"Αθήνα" ,"Καρδίτσα","Καβάλα","Κάρπαθος","Κάρυστος"
παλιός$()=πινακ$()
\\ Φτιάχνουμε το αντικείμενο Ταξινόμησε
Ταξινόμησε=ΑντικείμενοΤαξινόμησης()
Ένα$=""
\\ Οι συναρτήσεις θα κληθούν με Κάλεσε Τοπικά
\\ ως κλήσεις προς τα πίσω, στο τμήμα
\\ έτσι θα έχουν θέαση στους πίνακες και την Ένα$
Συνάρτηση ΘέσεΈνα {
        Διάβασε Νέο κ
        Ένα$=πινακ$(κ)
}
Συνάρτηση ΣυγκρινεΣτοιχεία {
        Διάβασε Νέο κ ,
        μ=Τάξη(πινακ$(κ), Ενα$) ' Εδώ μπορεί να χρησιμοποιηθεί και η Σύγκρινε()
}
Συνάρτηση ΆλλαξεΣτοιχεία {
        Διάβασε Νέο Μ1, κ
        Αν Μ1<>Κ Τότε Άλλαξε πινακ$(Μ1), πινακ$(κ)
}
\\ Τώρα τροφοδοτούμε το αντικείμενο με τις συναρτήσεις
Για Ταξινόμησε {
      Γεγονός .ΘέσεΈνα Νέο Οκν$(&ΘέσεΈνα())
      Γεγονός .ΣύγκρινεΣτοιχείο Νέο Οκν$(&ΣυγκρινεΣτοιχεία())
      Γεγονός .ΆλλαξεΣτοιχείο Νέο Οκν$(&ΆλλαξεΣτοιχεία())
      .πόσα=10 ' δηλώνουμε ότι θα ταξινομηθούν τα δέκα πρώτα στοιχεία
}
Αναλυτής
      Ταξινόμησε.ΓρήγορηΤαξινόμηση ? ' το ? δηλώνει απροσδιόριστη είσοδο
Τύπωσε Γραφή$(Φόρτος,"0")
     Αναλυτής
           Ταξινόμησε.ΓρήγορηΤαξινόμηση ?
    Τύπωσε Γραφή$(Φόρτος,"0") , " χρόνος για ταξινόμηση ήδη ταξινομημένου πίνακα"
Για Μ1=0 Έως 9
      Τύπωσε πινακ$(Μ1), παλιός$(Μ1)
Επόμενο Μ1
παλιός$()=πινακ$()
Αναλυτής
      Ταξινόμησε.ΓρήγορηΤαξινόμηση "ΦΘΙΝΟΥΣΑ"
Τύπωσε Γραφή$(Φόρτος,"0")
Αναλυτής
      Ταξινόμησε.ΓρήγορηΤαξινόμηση "ΦΘΙΝΟΥΣΑ"
Τύπωσε Γραφή$(Φόρτος,"0") , " χρόνος για ταξινόμηση ήδη ταξινομημένου πίνακα"
Για Μ1=0 Έως 9
      Τύπωσε πινακ$(Μ1), παλιός$(Μ1)
Επόμενο Μ1
Πίνακας πινακ$(10)="Αθήνα"
παλιός$()=πινακ$()
Αναλυτής
      Ταξινόμησε.ΓρήγορηΤαξινόμηση "ΦΘΙΝΟΥΣΑ"
Τύπωσε Γραφή$(Φόρτος,"0") , " χρόνος για ταξινόμηση με όλα τα στοιχεία ίδια"
' Η Για είναι πιο γρήγορη αν την δηλώσουμε με μπλοκ εντολών
Για Μ1=0 Έως 9 {
            Τύπωσε πινακ$(Μ1), παλιός$(Μ1)
}


Παράρτημα Σύγκριση Αλφαριθμητικών

Εδώ είναι μερικά παραδείγματα για τη σύγκριση αλφαριθμητικών. Έχει σημασία η θέση των διακοπτών. Στα προγράμματα παραπάνω όμως χρησιμοποιούμε την Τάξη() η οποία είναι σε κάθε περίπτωση του διακόπτη "txt" ίδια. Επιπλέον η Τάξη() κάνει διαχωρισμό αριθμών μέσα στα αλφαριθμητικά και έτσι το "αλφα 100" είναι μεγαλύτερο από το "αλφα 90", όπως και το "αλφα 100 βήτα 50" είναι μεγαλύτερο από το "αλφα 100 βήτα 8" (ενώ και τα δύο αν τα συγκρίνουμε απλά ως αλφαριθμητικά θα είναι το ανάποδο, επειδή στα μεν δυο πρώτα η σύγκριση στο 1 και 9 δίνει το 9 μεγαλύτερο, ενώ στο δεύτερο η σύγκριση στα 5 και 8 δίνει το 8 μεγαλύτερο).

Σε Xp, Windows 7 και Windows 8, Windows 10



Θέσε διακόπτες "+txt"
' εκτός από το ότι οι συγκρίσεις γίνονται αλφαβητικά, παίζει ρόλο και το Locale ή Τοπικό
' Μπορούμε να το ορίσουμε αν θέλουμε ώστε να αλλάξει η σειρά βάσει αλφαβήτου συγκεκριμένης γλώσσας, αν οι χαρακτήρες ανήκουν σε αυτήν, αλλιώς βάσει της γλώσσας που ανήκουν.
' Αυτό μετράει σε γλώσσες που διαχειρίζονται ίδιους χαρακτήρες.
Τύπωσε "α"="ά", "α">"ά" 'δίνει 0 και 0
Στη α$="α", β$="ά"
\\ η σύγκρινε παίρνει μόνο μεταβλητές (και αριθμητικές)
Τύπωσε Σύγκρινε(α$, β$) ' δίνει -1
\\ ο τελεστής "διαστημόπλοιο" ή "spaceship" παίρνει και αριθμητικές παραστάσεις
\\ και γυρίζει 1 ή 0 ή -1  (1 αν η πρώτη έκφραση έχει μεγαλύτερο αποτέλεσμα από τη δεύτερη)
Τύπωσε "α"<=>"ά"  ' ΄δίνει -1
\\ Η Συνάρτηση Τάξη δουλεύει μόνο για αλφαριθμητικά, πάντα σαν να έχουμε το διακόπτη στο "+txt"
Τύπωσε Τάξη(α$, β$) ' δίνει -1
Τύπωσε Τάξη("α","ά") ' δίνει -1
θέσε διακόπτες "-txt"
Τύπωσε "α"="ά", "α">"ά" ' δίνει 0 και -1
Στη α$="α", β$="ά"  
Τύπωσε Σύγκρινε(α$, β$) '1 δηλαδή α$>β$
Τύπωσε "α"<=>"ά"  ' 1
Τύπωσε Τάξη(α$, β$) ' δίνει -1
Τύπωσε Τάξη("α","ά") ' δίνει -1
\\ Ο κωδικός χαρακτήρων είναι πάντα ίδιος για οποιαδήποτε διακόπτη σύγκρισης, ή οποιοδήποτε τοπικό και αν έχουμε επιλέξει.
Τύπωσε ΧαρΚωδ("α"), ΧαρΚωδ("ά") ' 945 και 940
\\ Η Μ2000 μπορεί να κάνει μετατροπές.
\\ δουλεύει και σε Wine και σε Windows
\\ Κωδικός κατά Ansi
Τύπωσε Κωδ("α"), Κωδ("ά") ' 225   και 220
Τοπικό 1033
Τύπωσε Χαρ$(225) ' Δίνει á
Τοπικό 1032
Τύπωσε Χαρ$(225) ' Δίνει α
Τύπωσε Χαρ$(225, 1033) ' Δίνει á
Τύπωσε Χαρ$(225, 1032) ' Δίνει α
Τύπωσε Χαρ$(ΧαρΚωδ("á"), 1033) ' δίνει á
Τύπωσε Χαρ$(ΧαρΚωδ("á"), 1032) ' δίνει α



Σε  Wine σε Ubuntu Studio υπάρχει διαφορά. Το "α"="ά" δίνει αληθές. Επειδή όμως η Τάξη() δουλεύει σωστά, το πρόγραμμα ταξινόμησης δουλεύει σωστά. Οι μετατροπές με την Χαρ$() δουλεύει σωστά, όπως και στα Windows.


Θέσε διακόπτες "+txt"
' εκτός από το ότι οι συγκρίσεις γίνονται αλφαβητικά, παίζει ρόλο και το Locale ή Τοπικό
' Μπορούμε να το ορίσουμε αν θέλουμε ώστε να αλλάξει η σειρά βάσει αλφαβήτου συγκεκριμένης γλώσσας, αν οι χαρακτήρες ανήκουν σε αυτήν, αλλιώς βάσει της γλώσσας που ανήκουν.
' Αυτό μετράει σε γλώσσες που διαχειρίζονται ίδιους χαρακτήρες.
Τύπωσε "α"="ά", "α">"ά" 'δίνει -1  και 0
Στη α$="α", β$="ά"
\\ η σύγκρινε παίρνει μόνο μεταβλητές (και αριθμητικές)
Τύπωσε Σύγκρινε(α$, β$) ' δίνει 0
\\ ο τελεστής "διαστημόπλοιο" ή "spaceship" παίρνει και αριθμητικές παραστάσεις
\\ και γυρίζει 1 ή 0 ή -1  (1 αν η πρώτη έκφραση έχει μεγαλύτερο αποτέλεσμα από τη δεύτερη)
Τύπωσε "α"<=>"ά"  ' ΄δίνει 0
\\ Η Συνάρτηση Τάξη δουλεύει μόνο για αλφαριθμητικά, πάντα σαν να έχουμε το διακόπτη στο "+txt"
Τύπωσε Τάξη(α$, β$) ' δίνει 0
Τύπωσε Τάξη("α","ά") ' δίνει 0
θέσε διακόπτες "-txt"
Τύπωσε "α"="ά", "α">"ά"  ' δίνει 0 και -1
Στη α$="α", β$="ά"
Τύπωσε Σύγκρινε(α$, β$) '1 δηλαδή α$>β$
Τύπωσε "α"<=>"ά"  ' 1
Τύπωσε Τάξη(α$, β$) ' δίνει 0
Τύπωσε Τάξη("α","ά") ' δίνει 0
\\ Ο κωδικός χαρακτήρων είναι πάντα ίδιος για οποιαδήποτε διακόπτη σύγκρισης, ή οποιοδήποτε τοπικό και αν έχουμε επιλέξει.
Τύπωσε ΧαρΚωδ("α"), ΧαρΚωδ("ά") ' 945 και 940
\\ Η Μ2000 μπορεί να κάνει μετατροπές.
\\ δουλεύει και σε Wine και σε Windows
\\ Κωδικός κατά Ansi
Τύπωσε Κωδ("α"), Κωδ("ά") ' 225   και 220
Τοπικό 1033
Τύπωσε Χαρ$(225) ' Δίνει á
Τοπικό 1032
Τύπωσε Χαρ$(225) ' Δίνει α
Τύπωσε Χαρ$(225, 1033) ' Δίνει á
Τύπωσε Χαρ$(225, 1032) ' Δίνει α
Τύπωσε Χαρ$(ΧαρΚωδ("á"), 1033) ' δίνει á
Τύπωσε Χαρ$(ΧαρΚωδ("á"), 1032) ' δίνει α








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

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

You can feel free to write any suggestion, or idea on the subject.