Lomar Δημοσ. 6 Ιουνίου 2006 Δημοσ. 6 Ιουνίου 2006 Χαίρεται! Καταρχάς να σας προειδοποιήσω ότι είμαι νέος στο χώρο (εδώ και έναν χρόνο ασχολούμαι λόγω της σχολής), οπότε ίσως να σας φανεί πολύ γελοίο αυτό που θα ρωτήσω Στο μάθημα του προγραμματισμού δώθηκε το εξής πρόβλημα: Να γραφεί πρόγραμμα το οποίο θα υπολογίζει όλους τους πρώτους αριθμούς στο διάστημα [1,1000] και θα μετράει το πλήθος τους. (Πρώτος λέγεται ένας αριθμός που δεν διαιρείται με κανένα άλλο εκτός του εαυτού του και της μονάδας) Και μετά απο πολλές κουλές προσπάθειες, τελικά αποφάσισα να δώ τη λύση που πρότεινε ο καθηγητής και ήταν η εξής: >#include <stdio.h> main() { int a, i, flag, plithos=0; for (a=1; a<=1000; a++) { flag = 0; for (i=2; i<=a/2; i++) if (a%i == 0) flag = 1; if (flag == 0) { printf("%5d",a); plithos ++; } } printf("\n\nVrethikn synolika %d protoi arithmoi\n\n",plithos); } Όλα καλά, αλλά αυτό που δε μπορώ να καταλάβω - και ούτε ο καθηγητής κατάφερε να μου εξηγήσει ικανοποιητικά - είναι η λογική των εξής γραμμών: > for (i=2; i<=a/2; i++) if (a%i == 0) flag = 1; Νομίζω πως αυτό χρειάζεται στο να συγκριθούν ενας-ενας οι αριθμοί απο το 1μέχρι το 1000 με τους μισούς τουλάχιστον αριθμούς προκειμένου να σιγουρευτεί τ'οτι ο μετρητής a δε διαιρείται με κανέναν άλλο αριθμό εκτός τον εαυτό του και τη μονάδα (προκειμένου να λέγεται πρώτος). Αλλά γιατί στην επανάληψη for παίρνει τους μισούς αριθμούς και όχι και τους χίλιους; Και κάτι τελευταίο, αυτή η πατέντα με το flag και τους δύο ελέγχους (if) γιατί γίνεται, αφού - κατα τη γνώμη μου θα μπορόυσε να γίνει μόνο με έναν και χωρις το flag; >if (a%i == 1) { printf("%5d",a); plithos ++;} Ελπίζω να μην κούρασα και ευχαριστώ για την όποια βοήθεια
e-tic Δημοσ. 6 Ιουνίου 2006 Δημοσ. 6 Ιουνίου 2006 for (i=2; i<=a/2; i++) if (a%i == 0) flag = 1; Ένας αριθμός Α δεν μπορεί να διαιρεθεί ακριβώς με έναν αριθμό Β που είναι μεγαλύτερος απο το (Α/2). Έτσι, δεδομένου οτι ο Α διαιρείται ακριβώς με το 1 και τον εαυτό του, η λούπα αυτή προσπαθεί να δεί αν ο αριθμός Α είναι πρώτος, ελέγχοντας αν υπάρχει κάποιος αριθμός στο διάστημα [2,(Α/2)] που να τον διαιρεί ακριβώς.
e-tic Δημοσ. 6 Ιουνίου 2006 Δημοσ. 6 Ιουνίου 2006 Νομίζω οτι λείπει ένα ζευγάρι brackets απο τον κώδικα που δίνεις. Δεν έχω compiler εδώ που βρίσκομαι για να το ελέγξω, αλλά νομίζω οτι έτσι όως το δίνεις, θα βγάλει όλους τους αριθμού πρώτους... Αν δείς οτι όντως υπάρχει λάθος, δοκίμασε αυτό: >#include <stdio.h> main() { int a, i, flag, plithos=0; for (a=1; a<=1000; a++) { flag = 0; for (i=2; i<=a/2; i++) [b]{[/b] if (a%i == 0) flag = 1; [b]}[/b] if (flag == 0) { printf("%5d",a); plithos ++; } } printf("\n\nVrethikn synolika %d protoi arithmoi\n\n",plithos); }
Lomar Δημοσ. 6 Ιουνίου 2006 Μέλος Δημοσ. 6 Ιουνίου 2006 thnks! e-tic 2 ερωτήσεις ακόμη σε παρακαλώ... Γιατί ένας αριθμός Α δεν μπορεί να διαιρεθεί ακριβώς με έναν αριθμό Β που είναι μεγαλύτερος απο το (Α/2); 1) Δηλαδή έστω Α=5 τότε το Β θα πρέπει να είναι Β<2.5? 2) Το υπόλοιπο του α και του i αν είναι 0 σημαίνει πως το α διαιρείται τέλεια και με κάποιον τρίτο αριθμό, άρα δεν είναι τέλειος;
e-tic Δημοσ. 6 Ιουνίου 2006 Δημοσ. 6 Ιουνίου 2006 1) Το Α/2 θα στρογγυλοποιηθεί, άρα αν Α=5 τότε Β=5/2=3. Αν Α=100, τότε Β=50. Αν το Β ήταν μεγαλύτερο απο Α/2 τότε η απόλυτη διαίρεση θα σου βγάλει δεκαδικό αριθμό μικρότερο του 2 και μεγαλύτερο του 1 δηλαδή σε Α%Β θα σου βγάλει σίγουρα υπόλοιπο (δεν θα τον διαιρεί ακριβώς). 2) Ακριβώς
Lomar Δημοσ. 6 Ιουνίου 2006 Μέλος Δημοσ. 6 Ιουνίου 2006 Φίλε μου e-tic σε ευχαριστώ πάρα πολύ, τώρα κατανόησα την βαθύτερη έννοια του programming... Να μοιράζεσαι την γνώση
dop Δημοσ. 8 Ιουνίου 2006 Δημοσ. 8 Ιουνίου 2006 Αυτός είναι πολύ απλός αλγόριθμος και θα άρχιζα να αμφισβητώ την επάρκεια του καθηγητή που δεν μπορούσε να τον εξηγήσει. Ο κώδικας καλύτερα να γραφτεί σαν: > #include <stdio.h> int main(void) { int a, i, plithos=0; for (a=1; a<=1000; a++) { for (i=2; i<=a/2; i++) { if (a%i == 0) /* δεν υπάρχει λόγος δημιουργίας του flag */ { break; } } if (i>a/2) { printf("%5d",a); plithos ++; } } printf("\n\nVrethikn synolika %d protoi arithmoi\n\n", plithos); return 0; }
Προτεινόμενες αναρτήσεις
Αρχειοθετημένο
Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.