Πίνακες στη ΓΛΩΣΣΑ
Κεφ. 9 §9.1–9.3 · Μονοδιάστατοι, πότε χρησιμοποιούνται, πολυδιάστατοι
Διαβάζεις τους βαθμούς 25 μαθητών και θέλεις να βρεις πόσοι είναι πάνω από τον μέσο όρο. Πρόβλημα: τον μέσο όρο τον ξέρεις μόνο αφού διαβάσεις όλους τους βαθμούς — αλλά τότε οι βαθμοί έχουν «χαθεί», αφού μια μεταβλητή κρατά μόνο μία τιμή.
Η λύση είναι ο πίνακας: μία μεταβλητή με πολλές θέσεις. Στο Θέμα Δ θα τον χρειαστείς σχεδόν πάντα.
Μονοδιάστατοι πίνακες
Ο πίνακας είναι ένα σύνολο μεταβλητών του ίδιου τύπου, με κοινό όνομα, που ξεχωρίζουν μεταξύ τους με έναν δείκτη (τη θέση τους). Δηλώνεται στο τμήμα ΜΕΤΑΒΛΗΤΕΣ με το μέγεθός του σε αγκύλες:
ΜΕΤΑΒΛΗΤΕΣ ΠΡΑΓΜΑΤΙΚΕΣ: ΒΑΘ[25] ΧΑΡΑΚΤΗΡΕΣ: ΟΝ[25]
Το ΒΑΘ[1] είναι το πρώτο στοιχείο και το ΒΑΘ[25] το τελευταίο. Ο δείκτης μπορεί να είναι σταθερά, μεταβλητή ή έκφραση ακέραιου τύπου (π.χ. ΒΑΘ[i], ΒΑΘ[i + 1]) και πρέπει να βρίσκεται μέσα στα όρια της δήλωσης.
Η επεξεργασία όλων των στοιχείων γίνεται σχεδόν πάντα με ΓΙΑ:
ΓΙΑ i ΑΠΟ 1 ΜΕΧΡΙ 25 ΔΙΑΒΑΣΕ ΒΑΘ[i] ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
Ένας πίνακας δηλώνεται ΑΚΕΡΑΙΕΣ: Α[40]. Ποια αναφορά είναι λανθασμένη;
Πότε πρέπει να χρησιμοποιούνται πίνακες
Οι πίνακες δεσμεύουν μνήμη για όλα τα στοιχεία τους από την αρχή (είναι στατική δομή) και το μέγεθός τους πρέπει να είναι γνωστό από πριν. Γι' αυτό χρησιμοποιούνται μόνο όταν χρειάζονται:
- Χρειάζεται πίνακας όταν οι τιμές πρέπει να ξαναχρησιμοποιηθούν μετά την ανάγνωσή τους: σύγκριση κάθε τιμής με τον μέσο όρο, ταξινόμηση, αναζήτηση, εκτύπωση με αντίστροφη σειρά.
- Δεν χρειάζεται πίνακας όταν κάθε τιμή επεξεργάζεται μία φορά τη στιγμή που διαβάζεται: άθροισμα, μέσος όρος, μέγιστο, πλήθος τιμών που ικανοποιούν μια συνθήκη.
Η άσκοπη χρήση πινάκων σπαταλά μνήμη και θεωρείται κακή πρακτική.
Παράδειγμα 1: Διαβάζονται οι βαθμοί 25 μαθητών. Να εμφανιστεί πόσοι έχουν βαθμό μεγαλύτερο από τον μέσο όρο.
Σ ← 0 ΓΙΑ i ΑΠΟ 1 ΜΕΧΡΙ 25 ΔΙΑΒΑΣΕ ΒΑΘ[i] Σ ← Σ + ΒΑΘ[i] ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ ΜΟ ← Σ / 25 πλ ← 0 ΓΙΑ i ΑΠΟ 1 ΜΕΧΡΙ 25 ΑΝ ΒΑΘ[i] > ΜΟ ΤΟΤΕ πλ ← πλ + 1 ΤΕΛΟΣ_ΑΝ ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ ΓΡΑΨΕ πλ
Χρειάζονται δύο περάσματα: στο πρώτο υπολογίζεται ο μέσος όρος, στο δεύτερο κάθε βαθμός συγκρίνεται μαζί του. Χωρίς πίνακα οι βαθμοί θα έπρεπε να πληκτρολογηθούν δεύτερη φορά.
Για ποιο πρόβλημα δεν χρειάζεται πίνακας;
Πολυδιάστατοι πίνακες
Ο δισδιάστατος πίνακας έχει γραμμές και στήλες και κάθε στοιχείο του προσδιορίζεται με δύο δείκτες: Π[i, j] είναι το στοιχείο της γραμμής i και της στήλης j.
ΜΕΤΑΒΛΗΤΕΣ ΑΚΕΡΑΙΕΣ: Π[30, 5]
Ο Π[30, 5] έχει 30 γραμμές, 5 στήλες και στοιχεία. Η επεξεργασία γίνεται με εμφωλευμένα ΓΙΑ· ανάγνωση κατά γραμμές:
ΓΙΑ i ΑΠΟ 1 ΜΕΧΡΙ 30 ΓΙΑ j ΑΠΟ 1 ΜΕΧΡΙ 5 ΔΙΑΒΑΣΕ Π[i, j] ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
Για ανάγνωση κατά στήλες αντιστρέφεις τη σειρά των δύο ΓΙΑ (εξωτερικό το j). Υπάρχουν και πίνακες τριών ή περισσότερων διαστάσεων, π.χ. Θ[12, 31, 24] για θερμοκρασίες ανά μήνα, ημέρα και ώρα.
Μέθοδος: σχεδίαση πίνακα σε άσκηση
- Αποφάσισε αν χρειάζεται πίνακας (θα ξαναχρησιμοποιηθούν οι τιμές;).
- Όρισε τι σημαίνει κάθε διάσταση (π.χ. γραμμή = μαθητής, στήλη = μάθημα) και γράψ' το.
- Δήλωσε τον πίνακα με τον σωστό τύπο και μέγεθος· για ονόματα, παράλληλος πίνακας χαρακτήρων με το ίδιο μέγεθος.
- Γέμισε τον πίνακα με ΓΙΑ (και έλεγχο εγκυρότητας αν ζητείται).
- Επεξεργάσου τον με ΓΙΑ, προσέχοντας τα όρια των δεικτών.
Θέμα τύπου Πανελλαδικών: Τετραγωνικός πίνακας Α[5, 5] περιέχει ακέραιους. Να γραφεί τμήμα που υπολογίζει το άθροισμα των στοιχείων της κύριας διαγωνίου και το πλήθος των αρνητικών στοιχείων πάνω από την κύρια διαγώνιο.
Λύση: Κύρια διαγώνιος: i = j. Πάνω από αυτήν: j > i.
Σ ← 0 πλ ← 0 ΓΙΑ i ΑΠΟ 1 ΜΕΧΡΙ 5 Σ ← Σ + Α[i, i] ΓΙΑ j ΑΠΟ i + 1 ΜΕΧΡΙ 5 ΑΝ Α[i, j] < 0 ΤΟΤΕ πλ ← πλ + 1 ΤΕΛΟΣ_ΑΝ ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ ΓΡΑΨΕ Σ, πλ
Για τη διαγώνιο αρκεί ένα ΓΙΑ (5 στοιχεία, όχι 25 έλεγχοι i = j). Τα στοιχεία πάνω από τη διαγώνιο είναι .
Ποια στοιχεία ενός πίνακα Β[4, 4] ανήκουν στη δευτερεύουσα διαγώνιο;
Παράδειγμα 2: Διαβάζονται οι θερμοκρασίες 7 ημερών. Να εμφανιστούν οι ημέρες στις οποίες η θερμοκρασία ήταν μεγαλύτερη από της προηγούμενης ημέρας.
ΓΙΑ i ΑΠΟ 1 ΜΕΧΡΙ 7 ΔΙΑΒΑΣΕ Θ[i] ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ ΓΙΑ i ΑΠΟ 2 ΜΕΧΡΙ 7 ΑΝ Θ[i] > Θ[i - 1] ΤΟΤΕ ΓΡΑΨΕ 'Ημέρα ', i ΤΕΛΟΣ_ΑΝ ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
Για Θ = [21, 23, 22, 25, 25, 27, 24] εμφανίζονται οι ημέρες 2, 4, 6. Το δεύτερο ΓΙΑ ξεκινά από το 2, γιατί η 1η ημέρα δεν έχει προηγούμενη — με i = 1 θα ζητούσαμε το Θ[0], εκτός ορίων. Στην ημέρα 5 η θερμοκρασία είναι ίση (25), όχι μεγαλύτερη.
Στη ΓΛΩΣΣΑ οι δείκτες των πινάκων ξεκινούν από το 1, όπως στα μαθηματικά. Στις περισσότερες σύγχρονες γλώσσες (C, Java, Python) ξεκινούν από το 0 — μια επιλογή που ο Edsger Dijkstra υπερασπίστηκε το 1982 σε σημείωμά του με τίτλο «Why numbering should start at zero».
Να γραφεί τμήμα που αντιστρέφει τα στοιχεία ενός πίνακα Α[Ν] μέσα στον ίδιο πίνακα (χωρίς δεύτερο πίνακα). Πόσες αντιμεταθέσεις γίνονται για Ν = 7;
Δοκίμασε πρώτα μόνος σου — μετά δες τη λύση
Ανταλλάσσουμε το 1ο με το Ν-οστό, το 2ο με το (Ν − 1)-οστό κ.ο.κ., μέχρι τη μέση:
ΓΙΑ i ΑΠΟ 1 ΜΕΧΡΙ Ν DIV 2 temp ← Α[i] Α[i] ← Α[Ν - i + 1] Α[Ν - i + 1] ← temp ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
Για Ν = 7 γίνονται 7 DIV 2 = 3 αντιμεταθέσεις (1↔7, 2↔6, 3↔5) και το μεσαίο στοιχείο Α[4] μένει στη θέση του. Αν το ΓΙΑ έφτανε μέχρι το Ν, κάθε ζεύγος θα ανταλλασσόταν δύο φορές και ο πίνακας θα ξαναγύριζε στην αρχική του μορφή!
- Χρήση πίνακα όταν δεν χρειάζεται (π.χ. μόνο για μέσο όρο): κακή πρακτική, σπατάλη μνήμης.
- Δείκτης εκτός ορίων, συνήθως με i + 1 στην τελευταία επανάληψη (Α[Ν + 1]).
- Σύγχυση γραμμών και στηλών: στο Π[i, j] πρώτα η γραμμή, μετά η στήλη.
- Δήλωση πίνακα με μεταβλητή ως μέγεθος (Α[Ν] χωρίς το Ν να είναι σταθερά): το μέγεθος πρέπει να είναι γνωστό κατά τη δήλωση.
- Πίνακας: μεταβλητές ίδιου τύπου με κοινό όνομα και δείκτη· δήλωση στο ΜΕΤΑΒΛΗΤΕΣ, π.χ. ΑΚΕΡΑΙΕΣ: Α[40].
- Δείκτες από 1 έως το μέγεθος· επεξεργασία με ΓΙΑ.
- Πίνακας μόνο όταν οι τιμές ξαναχρησιμοποιούνται (σύγκριση με ΜΟ, ταξινόμηση, αναζήτηση).
- Δισδιάστατος Π[i, j]: γραμμή i, στήλη j· εμφωλευμένα ΓΙΑ.
- Τετραγωνικός: κύρια διαγώνιος i = j, δευτερεύουσα i + j = N + 1.