HElp please :)

Ξεκίνησε από Petran, 09 Μαΐου 2006, 04:04:36 ΜΜ

« προηγούμενο - επόμενο »

Petran

Μπορείτε να βοηθήσετε ??
Να γραφεί αλγόριθμος που να διαβάζει έναν ακέραιο θετικό αριθμό
Με άγνωστο αριθμό ψηφίων
και να εμφανίζει τον ανάποδό του

πχ 12345670321  και να εμφανίζει  12307654321
Ευχαριστώ

filippos

Μια γρήγορη λύση:

Κώδικας: ΓΛΩΣΣΑ
ΠΡΟΓΡΑΜΜΑ Αντιστροφή_Ακεραίου
ΜΕΤΑΒΛΗΤΕΣ
  ΑΚΕΡΑΙΕΣ: αριθμός, ανάποδο
ΑΡΧΗ
  ΔΙΑΒΑΣΕ αριθμός
  ανάποδο <- 0
  ΟΣΟ αριθμός <> 0 ΕΠΑΝΑΛΑΒΕ
    ανάποδο <- ανάποδο*10 + αριθμός MOD 10
    αριθμός <- αριθμός DIV 10
  ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
  ΓΡΑΨΕ  ανάποδο
ΤΕΛΟΣ_ΠΡΟΓΡΑΜΜΑΤΟΣ

gpapargi

Η λύση του που παρουσίασε ο Φίλιππος είναι πολύ κομψή!

Βέβαια είναι λίγο δύσκολο ο μαθητής να τη σκεφτεί από μόνος του (αυτή η αριστερή ολίσθηση που πετυχαίνει με πολ/σμό με 10). Μια λύση που σκέφτονται οι μαθητές ευκολότερα είναι να μετρήσεις τα ψηφία του αριθμού. (Πχ αυξάνεις το ι μέχρι το 10^ι να ξεπεράσει τον αριθμό).

Μετά κόβεις ένα ένα τα ψηφία από το τέλος του αριθμού (υπόλοιπο με 10), τα πολ/ζεις με την κατάλληλη δύναμη του 10 (πχ σε 6ψήφιο αριθμό το τελευταίο ψηφίο θα το πολ/σεις με την 5 η δύναμη του 10, το προτελευταίο στην 4 η κλπ)
και τα προσθέτεις μεταξύ τους.

Όχι τόσο ευφυής λύση όσο η προηγούμενη (αφού θέλει 2 εντολές επανάληψης) αλλά ίσως πιο πιθανό να τη σκεφτεί μόνος του ο μαθητής κυρίως επειδή ανάγεται σε ασκήσεις που έχει κάνει.

Και για να ξεσκουριάσουμε λίγο θέτω ένα γρίφο (για όποιον θέλει να ασχοληθεί) που σχετίζεται λίγο με το θέμα αλλά σαφώς ξεφεύγει από τα πλαίσια του μαθήματος:

Μπορείτε να φτιάξετε ένα τύπο που να δίνει το πλήθος των ψηφίων ενός ακέραιου αριθμού (χωρίς επαναληπτική διαδικασία); Δηλαδή να γραφτεί μια εντολή σε ΓΛΩΣΣΑ της μορφής

πλήθος_ψηφίων < - [τύπος]

andreas_p

Petran, Καλημέρα

Μια άλλη λύση, ίσως πιο κατανοητή από το μέσο μαθητή  :

ΠΡΟΓΡΑΜΜΑ Αντίστροφος
ΜΕΤΑΒΛΗΤΕΣ
  ΑΚΕΡΑΙΕΣ: αριθμός, νέος, κ, ψηφίο , πλ, χ, ψ
ΑΡΧΗ
  ΑΡΧΗ_ΕΠΑΝΑΛΗΨΗΣ
    ΓΡΑΨΕ 'Δώσε θετικό ακέραιο : '
    ΔΙΑΒΑΣΕ αριθμός
  ΜΕΧΡΙΣ_ΟΤΟΥ  αριθμός > 0
! για να μην τον χάσω
  χ <- αριθμός
! Πλήθος ψηφίων
  πλ <- 0
  ΟΣΟ χ > 0 ΕΠΑΝΑΛΑΒΕ
    χ <- χ DIV 10
    πλ <- πλ+1
  ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
  ΓΡΑΨΕ 'Πλήθος ψηφίων = ', πλ
! Βρίσκω τον αντίστροφο
  νέος <- 0
  ΓΙΑ ψ ΑΠΟ πλ-1 ΜΕΧΡΙ 0  ΜΕ_ΒΗΜΑ -1
    ψηφίο <- αριθμός MOD 10
    νέος <- νέος + ψηφίο*Α_Μ((10^ψ))
    αριθμός <- αριθμός DIV 10
  ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
  ΓΡΑΨΕ  νέος
ΤΕΛΟΣ_ΠΡΟΓΡΑΜΜΑΤΟΣ  Αντίστροφος

andreas_p

Προς : fipillo

Πώς μπορώ  στο παρόν forum,
να παρουσιάζω τον κώδικα  σε ΓΛΩΣΣΑ
σε μορφή (όπως είναι στο περιβάλλον του Διερμηνευτή )
"προγραμματιστική" και όχι απλά κειμένου ;


alkisg

@andreas_p: για χρωματισμό δες τις οδηγίες στο σχετικό θέμα: //index.php?topic=405

filippos

κάτι τέτοιο εννοείς Γιώργο;

Κώδικας: ΓΛΩΣΣΑ
ΠΡΟΓΡΑΜΜΑ Ψηφία
ΜΕΤΑΒΛΗΤΕΣ
  ΑΚΕΡΑΙΕΣ: αριθμός, Πλήθος_Ψηφίων
ΑΡΧΗ
  ΔΙΑΒΑΣΕ αριθμός
  Πλήθος_Ψηφίων <- Α_Μ(ΛΟΓ(αριθμός*10)/ΛΟΓ(10))
  ΓΡΑΨΕ Πλήθος_Ψηφίων
ΤΕΛΟΣ_ΠΡΟΓΡΑΜΜΑΤΟΣ

gpapargi

#7
Σε παραδέχομαι Φίλιππε   ;)

Ωστόσο έχει ενδιαφέρον να δούμε και μια μικρή απόδειξη καθώς χωρίς αυτή είναι δύσκολο να είμαστε σίγουροι για την ορθότητα του τύπου. Είναι πολύ απλή και ο λόγος που πιάνει χώρο είναι ότι τη γράφω αναλυτικά.

Ξεκινάμε από μια μικρή παρατήρηση υπό μορφή παραδείγματος.
Κάθε τριψήφιος αριθμός είναι μεταξύ του 100 και του 1000. Δηλαδή ισχύει:

10^2 <= 3_ψήφιος < 10^3

Που εύκολα γενικεύεται για ν ψηφία:

10^(ν-1) <= ν_ψήφιος < 10^ν

Παίρνουμε το λογάριθμο με βάση το 10 (έστω log με λατινικούς χαρακτήρες) στην παραπάνω σχέση (η φορά της ανισότητας δεν αλλάζει γιατί η λογαριθμική συνάρτηση με βάση το 10 είναι γνησίως αύξουσα):

Log(10^(ν-1)) <= log(ν_ψήφιος) < log(10^ν)

Εφαρμόζοντας τις ιδιότητα του λογαρίθμου που θέλει τον εκθέτη να βγαίνει έξω από το λογάριθμο και το log10 να είναι ίσο με ένα έχουμε:

ν-1 <= log(ν_ψήφιος) < ν

Αφού ο δεκαδικός λογάριθμος του αριθμού με ν ψηφία είναι ανάμεσα στο ν και στο ν-1 τότε το ακέραιο μέρος του θα είναι ν-1.

Άρα

[log(ν_ψήφιος)] = ν-1

Λύνοντας ως προς ν έχουμε:

ν = [log(ν_ψήφιος)] + 1

Επειδή η ΓΛΩΣΣΑ δεν υποστηρίζει δεκαδικό λογάριθμο αλλά μόνο φυσικό (με βάση το e) χρειαζόμαστε τον τύπο αλλαγής βάσης. Έτσι έχουμε

ν = [ln(ν_ψήφιος)/ln(10)] + 1

Για να καταλήξουμε στον τύπο του Φίλιππου βάζουμε 1 μέσα στο ακέραιο μέρος, κάνουμε ομόνυμα τα κλάσματα και γράφουμε το ln(ν_ψήφιος) + ln(10) σαν ln(ν_ψήφιος * 10).

Με αυτό το τέχνασμα της λογαρίθμισης μπορούμε να βρούμε πόσα ψηφία έχουν (δηλαδή τι τάξη μεγέθους έχουν) τεράστιοι αριθμοί γραμμένοι σε εκθετική μορφή (πχ ο 9^9^9^9). Μέχρι να φτάσουν στο σημείο οι υπολογιστές να χειρίζονται τέτοιους αριθμούς, στηριζόμαστε στη μαθηματική έμπνευση.

andreas_p

Άλκη, ευχαριστώ.

P.Tsiotakis

Αλγόριθμος Αντιστροφή
  Διάβασε αριθμός  ! θετικός
  ψηφία <-- 0
  Όσο αριθμός <> 0 επανάλαβε
    ψηφία <-- ψηφία +1
    ΠΙΝ[ψηφία] <-- αριθμός mod 10
    αριθμός <-- αριθμός div 10
  Τέλος_επανάληψης
  νέος <- 0
  Για ι από 1 μέχρι ψηφία
    νέος <-- νέος + ΠΙΝ[ι] * 10^(ψηφία – ι)
  Τέλος_επανάληψης
  Εκτύπωσε νέος
Τέλος Αντιστροφή

andreas_p

Κώδικας: ΓΛΩΣΣΑ
ΠΡΟΓΡΑΜΜΑ Αντίστροφος
ΜΕΤΑΒΛΗΤΕΣ
  ΑΚΕΡΑΙΕΣ: αριθμός, νέος, κ, ψηφίο , πλ, χ, ψ
ΑΡΧΗ
  ΑΡΧΗ_ΕΠΑΝΑΛΗΨΗΣ
    ΓΡΑΨΕ 'Δώσε θετικό ακέραιο : '
    ΔΙΑΒΑΣΕ αριθμός
  ΜΕΧΡΙΣ_ΟΤΟΥ  αριθμός > 0
! για να μην τον χάσω
  χ <- αριθμός
! Πλήθος ψηφίων
  πλ <- 0
  ΟΣΟ χ > 0 ΕΠΑΝΑΛΑΒΕ
    χ <- χ DIV 10
    πλ <- πλ+1
  ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
  ΓΡΑΨΕ 'Πλήθος ψηφίων = ', πλ
! Βρίσκω τον αντίστροφο
  νέος <- 0
  ΓΙΑ ψ ΑΠΟ πλ-1 ΜΕΧΡΙ 0  ΜΕ_ΒΗΜΑ -1
    ψηφίο <- αριθμός MOD 10
    νέος <- νέος + ψηφίο*Α_Μ((10^ψ))
    αριθμός <- αριθμός DIV 10
  ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
  ΓΡΑΨΕ  νέος
ΤΕΛΟΣ_ΠΡΟΓΡΑΜΜΑΤΟΣ  Αντίστροφος


andreas_p

Συγνώμη, για τα δοκιμαστικά.
Αν και θα μπορούσαν να είχαν γίνει με το 'Προεπισκόπηση'.

alkisg

Αντρέα τα έσβησα, πάντως μπορείς να πατάς και το κουμπί "Τροποποίηση" αν θες να αλλάξεις τα μηνύματά σου εκ των υστέρων.

andreas_p

Άλκη, ευχαριστώ.

Επίσης,

το πρόγραμμα σου 'Διερμηνευτής της Γλώσσας'  "ΒΑΛΣΑΜΟ"

κυρίως για τους μέτριους μαθητές.

Με τη βηματική εκτέλεση, αντιλαμβάνονται πλήρως  την κλήση  των

υποπρογραμμάτων καθώς επίσης και την επιστροφή στο κύριο πρόγραμμα.

Μια σκέψη μου : Σε επόμενη έκδοση , αν είναι εφικτό, να γίνεται  και η παρουσίαση της σχέσης  "Διαδικασίες -Στοίβα χρόνου εκτέλεσης".

Ανδρέας

filippos

Συμφωνώ απόλυτα με τον Ανδρέα.

Η μεθοδική χρήση του διερμηνευτή, ειδικά από τις προηγούμενες τάξης (Γ' Γυμνασία, Α' & Β' Λυκείου) είναι πράγματι ΒΑΛΣΑΜΟ για την κατανόηση βασικών αλγοριθμικών τεχνικών.

Επίσης συμφωνώ (με πρόλαβες Ανδρέα) στη σκέψη για απεικόνιση της στοίβας χρόνου εκτέλεσης.  Προσωπικά τη δούλεψα αρκετά φέτος "στο χαρτί" και βοήθησε αρκετά τους μαθητές στην κατανόηση του μηχανισμού κλήση - επιστροφή αλλά και της λειτουργίας της στοίβας ως δομής δεδομένων. 

Και μάλιστα θα πρότεινα, σε πιθανή υλοποίησή της (εάν ο Άλκης το κρίνει σκόπιμο και εφικτό) από τη στιγμή που το περιβάλλον του διερμηνευτή είναι ήδη εφοδιασμένο με αριθμούς γραμμών, να καταχωρούνται στη στοίβα χρόνου εκτέλεσης απλά οι αριθμοί γραμμών της εντολής κλήσης (στην περίπτωση συνάρτησης) ή της επόμενης (στην περίπτωση της διαδικασίας) Είναι πιστεύω παιδαγωγικά επαρκής ως υλοποίηση (της "διεύθυνσης" επιστροφής) στο πλαίσο των στόχων του μαθήματος.

Βέβαια, it's up to ʼλκης ;)

alkisg

@andreas_p, @filippos: ευχαριστώ για τα καλά σας λόγια. Αυτή τη στιγμή η στοίβα χρόνου εκτέλεσης φαίνεται μόνο από το κουτί "Κληθέντα υποπρογράμματα" του Διερμηνευτή, στο οποίο εμφανίζονται όλες οι (εμφωλευμένες) κλήσεις που έχουν γίνει... Επίσης, διαλέγοντας ένα υποπρόγραμμα από το ίδιο κουτί, εμφανίζονται στην καρτέλα "Μεταβλητές" οι τιμές των μεταβλητών του υποπρογράμματος της συγκεκριμένης κλήσης που επιλέχθηκε...

Όμως δεν μπορώ να φανταστώ κάποιο interface που να δίνει καλύτερα τη σχέση κλήσης/στοίβας από τον πίνακα τιμών.
Αν ευκαιρείτε, κοιτάξτε λίγο το topic Μορφή του πίνακα τιμών καθώς και το παράδειγμα που δίνω στο https://alkisg.mysch.gr/pivakas_timwv.htm.
Αν σ' αυτό το παράδειγμα προσθέσουμε και αυτά που λέει ο Φίλιππος (αριθμούς γραμμών της κλήσης), νομίζω ότι είμαστε εντάξει όσον αφορά στην αναπαράσταση... Τι λέτε;