sancroth Δημοσ. 4 Μαΐου 2014 Δημοσ. 4 Μαΐου 2014 (επεξεργασμένο) Εκφωνηση :Να γραφει προγραμμα το οποιο θα εισαγει εναν ακεραιο αριθμο απο 1-50 σε πινακα 20 θεσεων.Για λογους ευκολιας αυτο θα γινεται στην αρχη του προγραμματος με τυχαιους αριθμους.Κατοπιν το προγραμμα θα δημιουργει εναν δευτερο πινακα Β ο οποιος θα περιεχει τα στοιχεια του Α αλλαθα εχοντασ μετατοπισει τοθσ αριθμους 1-25 στις αρχικες θεσεις του πινακα ενω τα >25 στις τελευταιες.πχ.Α[40 6 30 45 10 15 22 11 9 49] Β[6 10 15 22 11 9 40 30 45 49] Ο κωικας μου : #include <stdio.h> #include <stdlib.h> #include <time.h> int main(int argc, char *argv[]) { srand(time(NULL)); int anap=0,ortha=0,x,i,pin[20],pinB[20]; for(i=0;i<20;i++) { x=rand()%50+1; pin[i]=x; if(x<=25) { pinB[ortha]=x; ortha++; } else { pinB[20-anap]=x; anap++; } printf("A[%d]=%d\n",i+1,pin[i]); } for(i=0;i<20;i++) printf("B[%d]=%d\n",i+1,pinB[i]); return 0; } Πετυχαινω λοιπον το πρωτο κομματι αλλα τα >25 μπαινουν με αναποδη σειρα.Υπαρχει καποιος τροπος να το πετυχουμε to splitpush μεσα στην πρωτη επαναληψη που δημιουργουμε και τον Α? Επεξ/σία 5 Μαΐου 2014 από sancroth
Moderators Kercyn Δημοσ. 4 Μαΐου 2014 Moderators Δημοσ. 4 Μαΐου 2014 Bump σε 5 ώρες και 11 λεπτά και χωρίς code tag; Nigga pls
sancroth Δημοσ. 5 Μαΐου 2014 Μέλος Δημοσ. 5 Μαΐου 2014 Μαλιστα.Ελπιζω να καταλαβες οτι ζητησα για βοηθεια σε μια εργασια και οχι ειρωνια χωρις λογο.Ευχαριστω.
Moderators Kercyn Δημοσ. 5 Μαΐου 2014 Moderators Δημοσ. 5 Μαΐου 2014 Γιατί λοιπόν δε βάζεις τον κώδικα σε code tags για να μη βγαίνουν τα μάτια σε εμάς που θέλουμε να βοηθήσουμε;
Moderators Kercyn Δημοσ. 5 Μαΐου 2014 Moderators Δημοσ. 5 Μαΐου 2014 http://ideone.com/gNwK37 Δες τη γραμμή 27. Του λες να βάλει το πρώτο νούμερο που θα βρει στο τέλος του πίνακα, το δεύτερο μια θέση πριν απ' το τέλος κ.ο.κ. Αν θες να σου μπαίνουν "με τη σειρά" πρέπει πρώτα να βάλεις όλα τα στοιχεία που είναι <= 25, να κρατήσεις τη θέση του τελευταίου στοιχείου και να ξαναπεράσεις τον πίνακα για να βάλεις όλα τα στοιχεία που είναι >25, ξεκινώντας από τη θέση που κράτησες + 1. Εναλλακτικός τρόπος: έχεις ένα counter κάτω από τη γραμμή 17 που μετράει όλα τα x <= 25, για να ξέρεις πόσες θέσεις θα πιάσουν στο Β.
sancroth Δημοσ. 5 Μαΐου 2014 Μέλος Δημοσ. 5 Μαΐου 2014 Με counter το ελυσα και εγω για να το τελειοποιησω απλα ελεγα μπασ και υπαρχει καποιος τροποσ να γινει μονομιας.Ευχαριστω
georgemarios Δημοσ. 5 Μαΐου 2014 Δημοσ. 5 Μαΐου 2014 (επεξεργασμένο) else { pinB[10+anap]=x; anap++; } Εδιτ, γραψε λαθος Επεξ/σία 5 Μαΐου 2014 από georgemarios
Moderators Kercyn Δημοσ. 5 Μαΐου 2014 Moderators Δημοσ. 5 Μαΐου 2014 else { pinB[10+anap]=x; anap++; } Δε λέει πουθενά ότι οι αριθμοί είναι 10 <=25 και άλλοι 10 >25.
migf1 Δημοσ. 5 Μαΐου 2014 Δημοσ. 5 Μαΐου 2014 ... Πετυχαινω λοιπον το πρωτο κομματι αλλα τα >25 μπαινουν με αναποδη σειρα.Υπαρχει καποιος τροπος να το πετυχουμε to splitpush μεσα στην πρωτη επαναληψη που δημιουργουμε και τον Α? Αν πάρουμε κατά γράμμα την εκφώνηση, τότε στο loop που γεμίζεις τον pinA ΔΕΝ πρέπει να κάνεις τίποτε άλλο. Δηλαδή το μόνο που θα κάνει το loop αυτό θα είναι να γεμίζει τον pinA με τυχαίους αριθμούς. Επίσης, πάντα αν πάρουμε κατά γράμμα την εκφώνηση, τότε ο pinB είτε πρέπει να δημιουργηθεί δυναμικά αμέσως μετά το παραπάνω loop αν μιλάμε για C89/90, είτε να οριστεί στατικά ή σαν VLA αν μιλάμε για C99 και μετά. Επειδή όμως δεν ξέρουμε τι έχετε μάθει και τι όχι, ας υποθέσουμε πως τους ορίζουμε και τους 2 στατικά, στην αρχή της main. Τώρα, αυτό που ρωτάς, αν το κατάλαβα σωστά, σημαίνει αν υπάρχει τρόπος να μειώσεις τον χρόνο εκτέλεσης του κώδικα, σωστά; Οι προτάσεις του Kercyn σκανάρουν μόνιμα 2 φορές τον pinA. Αν θέλεις να σκανάρεις τον pinA μόνο μια φορά και να μειώσεις τον μέσο όρο συνολικής εκτέλεσης σε χρόνο που αντιστοιχεί σε περίπου 1.5 σκαναρίσματα του pinA, μπορείς να χρησιμοποιήσεις έναν τρίτο προσωρινό πίνακα, για όσα στοιχεία του pinA βρίσκεις να είναι > 25. Όταν τελειώσεις το σκανάρισμα του pinA, και ταυτόχρονα έχεις βάλει στην αρχή του pinB όσα στοιχεία είναι <= 25 και στον προσωρινό πίνακα όσα στοιχεία είναι > 25, μπορείς να κάνεις concatenate τα ωφέλιμα περιεχόμενα των δυο αυτών πινάκων. Προφανώς αυτή η προσέγγιση θυσιάζει μνήμη προς όφελος της μέσης ταχύτητας εκτέλεσης. Στον κώδικα που παραθέτω παρακάτω σε spoiler, αυτό το "concatenation" το κάνω με την memcpy(), αλλά αν δεν την έχετε μάθει, μπορείς να την αντικαταστήσεις με κανονικό loop από [j έως Ν) ... #include <stdio.h> #include <string.h> #include <stdlib.h> #include <time.h> #define N 20 /* ------------------------------------- */ void arr_print( int *arr, const char *label ) { if ( !arr ) { return; } if ( label ) { printf( "%s", label ); fflush( stdout ); } for (int i=0; i < N; i++ ) { printf( "%2d ", arr[i] ); } putchar( '\n' ); } /* ------------------------------------- */ int main( void ) { int src[N] = {0}; // source array int dst[N] = {0}; // destination array int tmp[N] = {0}; // temp array int i, j, k; // array indexers // fill source array with random ints from 1 to 50 srand( time(NULL) ); for (int i=0; i < N; i++) { src[i] = 1 + rand() % 50; } arr_print( src, "src: " ); // copy ints <= 25 from source to destination array, rest of them to the temp array for (i=0, j=0, k=0; i < N; i++) { if ( src[i] <= 25 ) { dst[j++] = src[i]; } else { tmp[k++] = src[i]; } } // if needed, concatenate destination array with temp array if ( k ) { memcpy( &dst[j], &tmp[0], k * sizeof(int) ); } arr_print( dst, "dst: " ); return EXIT_SUCCESS; } /* Ενδεικτική έξοδος: src: 5 44 7 22 2 39 18 9 14 45 19 22 31 31 50 17 27 45 8 37 dst: 5 7 22 2 18 9 14 19 22 17 8 44 39 45 31 31 50 27 45 37 */ ΥΓ1. Ενδεχομένως να υπάρχει πιο time efficient υλοποίηση, αλλά στα 5 λεπτά που αφιέρωσα για να σκεφτώ δεν μου ήρθε κάποια άλλη στο μυαλό. ΥΓ2. Ο κώδικας ενδέχεται να περιέχει bugs ή άλλες αβλεψίες. Δεν έχει δοκιμαστεί με ικανό πλήθος test-cases.
gon1332 Δημοσ. 5 Μαΐου 2014 Δημοσ. 5 Μαΐου 2014 Αν πάρουμε κατά γράμμα την εκφώνηση, τότε στο loop που γεμίζεις τον pinA ΔΕΝ πρέπει να κάνεις τίποτε άλλο. Δηλαδή το μόνο που θα κάνει το loop αυτό θα είναι να γεμίζει τον pinA με τυχαίους αριθμούς. Επίσης, πάντα αν πάρουμε κατά γράμμα την εκφώνηση, τότε ο pinB είτε πρέπει να δημιουργηθεί δυναμικά αμέσως μετά το παραπάνω loop αν μιλάμε για C89/90, είτε να οριστεί στατικά ή σαν VLA αν μιλάμε για C99 και μετά. Επειδή όμως δεν ξέρουμε τι έχετε μάθει και τι όχι, ας υποθέσουμε πως τους ορίζουμε και τους 2 στατικά, στην αρχή της main. Τώρα, αυτό που ρωτάς, αν το κατάλαβα σωστά, σημαίνει αν υπάρχει τρόπος να μειώσεις τον χρόνο εκτέλεσης του κώδικα, σωστά; Οι προτάσεις του Kercyn σκανάρουν μόνιμα 2 φορές τον pinA. Αν θέλεις να σκανάρεις τον pinA μόνο μια φορά και να μειώσεις τον μέσο όρο συνολικής εκτέλεσης σε χρόνο που αντιστοιχεί σε περίπου 1.5 σκαναρίσματα του pinA, μπορείς να χρησιμοποιήσεις έναν τρίτο προσωρινό πίνακα, για όσα στοιχεία του pinA βρίσκεις να είναι > 25. Όταν τελειώσεις το σκανάρισμα του pinA, και ταυτόχρονα έχεις βάλει στην αρχή του pinB όσα στοιχεία είναι <= 25 και στον προσωρινό πίνακα όσα στοιχεία είναι > 25, μπορείς να κάνεις concatenate τα ωφέλιμα περιεχόμενα των δυο αυτών πινάκων. Προφανώς αυτή η προσέγγιση θυσιάζει μνήμη προς όφελος της μέσης ταχύτητας εκτέλεσης. Στον κώδικα που παραθέτω παρακάτω σε spoiler, αυτό το "concatenation" το κάνω με την memcpy(), αλλά αν δεν την έχετε μάθει, μπορείς να την αντικαταστήσεις με κανονικό loop από [j έως Ν) ... #include <stdio.h> #include <string.h> #include <stdlib.h> #include <time.h> #define N 20 /* ------------------------------------- */ void arr_print( int *arr, const char *label ) { if ( !arr ) { return; } if ( label ) { printf( "%s", label ); fflush( stdout ); } for (int i=0; i < N; i++ ) { printf( "%2d ", arr[i] ); } putchar( '\n' ); } /* ------------------------------------- */ int main( void ) { int src[N] = {0}; // source array int dst[N] = {0}; // destination array int tmp[N] = {0}; // temp array int i, j, k; // array indexers // fill source array with random ints from 1 to 50 srand( time(NULL) ); for (int i=0; i < N; i++) { src[i] = 1 + rand() % 50; } arr_print( src, "src: " ); // copy ints <= 25 from source to destination array, rest of them to the temp array for (i=0, j=0, k=0; i < N; i++) { if ( src[i] <= 25 ) { dst[j++] = src[i]; } else { tmp[k++] = src[i]; } } // if needed, concatenate destination array with temp array if ( k ) { memcpy( &dst[j], &tmp[0], k * sizeof(int) ); } arr_print( dst, "dst: " ); return EXIT_SUCCESS; } /* Ενδεικτική έξοδος: src: 5 44 7 22 2 39 18 9 14 45 19 22 31 31 50 17 27 45 8 37 dst: 5 7 22 2 18 9 14 19 22 17 8 44 39 45 31 31 50 27 45 37 */ ΥΓ1. Ενδεχομένως να υπάρχει πιο time efficient υλοποίηση, αλλά στα 5 λεπτά που αφιέρωσα για να σκεφτώ δεν μου ήρθε κάποια άλλη στο μυαλό. ΥΓ2. Ο κώδικας ενδέχεται να περιέχει bugs ή άλλες αβλεψίες. Δεν έχει δοκιμαστεί με ικανό πλήθος test-cases. Αν cheat-άρεις μπορείς να καταφέρεις κάτι καλύτερο. Αν μαζέψεις κάποια λογιστικά κατά την είσοδο ας πούμε ... #include <stdio.h> #include <stdlib.h> #include <time.h> #define ARRAY_SIZE 20 #define MAX_VALUE 50 #define SEPARATOR 25 int main (void) { int array_a[ARRAY_SIZE] = {0}; int array_b[ARRAY_SIZE] = {0}; int big_num_count = 0; // number of values greater than 25 // Initialize array a with random values in [1, 50] srand(time(NULL)); for (int i = 0; i < ARRAY_SIZE; ++i) { int reg = (array_a[i] = rand() % MAX_VALUE + 1); if (reg > SEPARATOR) big_num_count++; } // Print array a { printf("array_a : "); for (int i = 0; i < ARRAY_SIZE; ++i) printf("%2d ", array_a[i]); puts(""); } // Create array b as described int offset = ARRAY_SIZE - big_num_count; int j = 0; for (int i = 0; i < ARRAY_SIZE; ++i) if (array_a[i] <= SEPARATOR) array_b[j++] = array_a[i]; else array_b[offset++] = array_a[i]; // Print array b { printf("array_b : "); for (int i = 0; i < ARRAY_SIZE; ++i) printf("%2d ", array_b[i]); puts(""); } return(0); }
migf1 Δημοσ. 5 Μαΐου 2014 Δημοσ. 5 Μαΐου 2014 Αν cheat-άρεις μπορείς να καταφέρεις κάτι καλύτερο. Αν μαζέψεις κάποια λογιστικά κατά την είσοδο ας πούμε ... ... Χεχε... αν είναι να cheat-αρουμε, τότε αφήνουμε το original cheat όπως το έχουν τα παιδιά παραπάνω, και κατόπιν αντιστρέφουμε μονάχα τα big-numbers στο destination array, κάνοντας τις μισές από τις δικές σου επισκέψεις στο 2ο loop ... #define N 20 .... int main( void ) { int src[N] = {0}; // source array int dst[N] = {0}; // destination array int i, j, k; // array indexers // fill src array with random ints from 1 to 50 // and copy into dst array small numbers to the left, reversed big numbers to the right srand( time(NULL) ); for (i=0, j=0, k=N; i < N; i++) { src[i] = 1 + rand() % 50; if ( src[i] <= 25 ) { dst[j++] = src[i]; } else { dst[--k] = src[i]; } } // in dst, reverse only the big numbers, visiting only half their count for (i=k, j=N-1; j >= i; i++, j--) { int temp = dst[i]; dst[i] = dst[j]; dst[j] = temp; } arr_print( src, "src: " ); arr_print( dst, "dst: " ); return EXIT_SUCCESS; }
gon1332 Δημοσ. 5 Μαΐου 2014 Δημοσ. 5 Μαΐου 2014 Χεχε... αν είναι να cheat-αρουμε, τότε αφήνουμε το original cheat όπως το έχουν τα παιδιά παραπάνω, και κατόπιν αντιστρέφουμε μονάχα τα big-numbers στο destination array, κάνοντας τις μισές από τις δικές σου επισκέψεις στο 2ο loop ... #define N 20 .... int main( void ) { int src[N] = {0}; // source array int dst[N] = {0}; // destination array int i, j, k; // array indexers // fill src array with random ints from 1 to 50 // and copy into dst array small numbers to the left, reversed big numbers to the right srand( time(NULL) ); for (i=0, j=0, k=N; i < N; i++) { src[i] = 1 + rand() % 50; if ( src[i] <= 25 ) { dst[j++] = src[i]; } else { dst[--k] = src[i]; } } // in dst, reverse only the big numbers, visiting only half their count for (i=k, j=N-1; j >= i; i++, j--) { int temp = dst[i]; dst[i] = dst[j]; dst[j] = temp; } arr_print( src, "src: " ); arr_print( dst, "dst: " ); return EXIT_SUCCESS; } Ξέρεις κάτι; Fuck src! Μας είναι άχρηστη, άσε που μας επιβαρύνει με 3*Ν προσπελάσεις στη μνήμη. Βάλε μία απλή μεταβλητή για τις συγκρίσεις και κάνε μία εκτύπωση της εισόδου στο πρώτο loop. Κότσαρε και ένα "printing src : " από μπροστά και είμαστε GG (για να είναι και ευχαριστημένος ο μεταπτυχιακός που θα το διορθώσει). Βάλε και κανα-δυό openmp directives (για NOS). Ξέρεις πως θα πηγαίνει;
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα