Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ. (επεξεργασμένο)

Εκφωνηση :

Να γραφει προγραμμα το οποιο θα εισαγει εναν ακεραιο αριθμο απο 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 μεσα στην πρωτη επαναληψη που δημιουργουμε και τον Α?
Επεξ/σία από sancroth
Δημοσ.

Μαλιστα.Ελπιζω να καταλαβες οτι ζητησα για βοηθεια σε μια εργασια και οχι ειρωνια χωρις λογο.Ευχαριστω.

  • Moderators
Δημοσ.

Γιατί λοιπόν δε βάζεις τον κώδικα σε code tags για να μη βγαίνουν τα μάτια σε εμάς που θέλουμε να βοηθήσουμε;

  • Moderators
Δημοσ.

http://ideone.com/gNwK37

 

Δες τη γραμμή 27. Του λες να βάλει το πρώτο νούμερο που θα βρει στο τέλος του πίνακα, το δεύτερο μια θέση πριν απ' το τέλος κ.ο.κ. Αν θες να σου μπαίνουν "με τη σειρά" πρέπει πρώτα να βάλεις όλα τα στοιχεία που είναι <= 25, να κρατήσεις τη θέση του τελευταίου στοιχείου και να ξαναπεράσεις τον πίνακα για να βάλεις όλα τα στοιχεία που είναι >25, ξεκινώντας από τη θέση που κράτησες + 1. Εναλλακτικός τρόπος: έχεις ένα counter κάτω από τη γραμμή 17 που μετράει όλα τα x <= 25, για να ξέρεις πόσες θέσεις θα πιάσουν στο Β.

Δημοσ.

Με counter το ελυσα και εγω για να το τελειοποιησω απλα ελεγα μπασ και υπαρχει καποιος τροποσ να γινει μονομιας.Ευχαριστω :)

  • Moderators
Δημοσ.
else
{
   pinB[10+anap]=x;
   anap++;
}

 

Δε λέει πουθενά ότι οι αριθμοί είναι 10 <=25 και άλλοι 10 >25.

Δημοσ.

...

Πετυχαινω λοιπον το πρωτο κομματι αλλα τα >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.

Δημοσ.

 

Αν πάρουμε κατά γράμμα την εκφώνηση, τότε στο 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-άρεις μπορείς να καταφέρεις κάτι καλύτερο. Αν μαζέψεις κάποια λογιστικά κατά την είσοδο ας πούμε ... :P

 

 

#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);
}

 

 

Δημοσ.

Αν cheat-άρεις μπορείς να καταφέρεις κάτι καλύτερο. Αν μαζέψεις κάποια λογιστικά κατά την είσοδο ας πούμε ... :P

...

Χεχε... αν είναι να 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;
}

Δημοσ.

Χεχε... αν είναι να 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). Ξέρεις πως θα πηγαίνει;

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...