Κυριακή, 10 Φεβρουαρίου 2008

Mind Compilation

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

Σ' ένα ερώτημα την Παρασκευή, την πάτησα σαν εντελώς αρχάριος. Έκατσα να κάνω τις εξετάσεις πριν λίγο, με την ησυχία μου, κι είδα ότι έκανα κάποια τραγικά λάθη που φυσικά δεν έπρεπε να κάνω.

Μας λέει να κάνουμε αναδρομική μέθοδο που αυξάνει τα πεδία ενός πίνακα με μια συγκεκριμένη τιμή, ξεκινώντας από συγκεκριμένη θέση.

Αυτό που έκανα ήταν το εξής και ήταν λάθος φυσικά:

public static void plus(int[] array, int start, int amount){

   array[start] += amount;

   plus(array,start+1,amount);

}

Έτσι, η μέθοδος δεν τερματίζει πουθενά με αποτέλεσμα να βγάζει εξαίρεση ArrayIndexOutOfBounds επειδή συνεχίζει και μετά το τέλος του πίνακα...

Οπότε τι γίνεται; Βάζεις απλά κι ένα ακόμα όρισμα πχ. counter (το οποίο μηδενίζεις στη main) που θα ελέγχει για το μήκος του πίνακα. Άρα:

public static void plus(int[] array, int start, int amount, int counter){

   counter += 1;

   if(counter < array.length){

      array[start] += amount;

      plus(array,start,amount,counter);

   }

}

Την πάτησα σαν εντελώς πρωτάρης. Ήταν εντελώς ηλίθιο αυτό που έκανα. Βέβαια θα 'πρεπε να το ξέρουμε αλλά όταν μαθαίνεις μηχανικά να προγραμματίζεις, λογικό είναι να μη μπορείς να κάνεις κάποια εύκολα πράγματα... Κι ένα δεύτερο.

Σε άλλο υποερώτημα είχε το εξής (μεταξύ άλλων τάξεων):

abstract class Being{

   void prog2(){};

}

Κι έπρεπε να δούμε αν το πρόγραμμα περνάει το compile, να διορθώσουμε τυχόν λάθη και να βγάλουμε την έξοδο. Εντάξει, την έξοδο την έβγαλα σωστά, δε πρόσεξα όμως το λάθος στην παραπάνω τάξη!

ΓΙΑ ΤΟ ΘΕΟ! Σε abstract τάξη, οι μέθοδοι ή πρέπει να οριστούν abstract (και να μην έχουν σώμα δηλ.{}) και να έχουν ερωτηματικό, ή να έχουν σώμα, να μην οριστούν φυσικά abstract και να μην έχουν ερωτηματικό. Και τα δύο δε γίνεται...

5 σχόλια:

rockordie είπε...

Δεν την κατέχω την java αλλά έχω την εντύπωση ότι το πρώτο πάλι λάθος το έχεις..

rockordie είπε...

Κάπως έτσι μου φαίνεται καλύτερα, υποθέτω ότι η length επιστρέφει το μέγιστο+1 για αυτό (<) αλλιώς θέλει (<=)


public static void plus(int[] array, int start, int amount){

if(start < array.length){

array[start] += amount;

plus(array, start+1, amount);

}

Γιατί με τον δικό σου τρόπο αυξάνει συνέχεια το ίδιο πεδίο.

Wise_One είπε...

Το δοκίμασα και δεν έχω λάθος απλά έπρεπε να έχω <= γιατί τώρα δεν αλλάζει το τελευταίο στοιχείο του πίνακα. Δε το πρόσεξα χθες.

Πάντως το ίδιο είναι είτε ελέγχοντας με τη start είτε χρησιμοποιώντας έναν counter. Απλά ξες, απ' την αρχή μας έδειξαν ότι οι counters βολεύουν οπότε... μάθαμε.

rockordie είπε...

Επιμένω ότι έχεις λάθος γιατί στο recursion στέλνεις συνέχεια την ίδια εντολή:
plus(array, start, amount);

ενώ πρέπει να στείλεις:

plus(array, start + 1, amount);

Επίσης με την counter μηδέν την πρώτη φορά (όπως λες) τότε το πρόγραμμα δουλεύει ΜΟΝΟ για όλο τον πίνακα και ΟΧΙι αν η start αρχίζει από την θέση 7 πχ.

Είναι ξεκάθαρο από τον κώδικα.

Wise_One είπε...

Στο δεύτερο μπλοκ κώδικα έχεις δίκιο. Δεν έγραψα το +1, ενώ στο πρώτο μπλοκ το έγραψα. Damn keyboard!! :PP

Αφού το έτρεξα και δούλεψε ρε!

Καλά θα το δώ μετά γιατί όντως μπορεί να 'χω κάνει καμιά μαλακία...