View Full Version : [C] Invertire un array...??
fabri_napoli
09-12-2008, 18:00
Detto sinceramente pensavo che fosse un argomento già affrontato, quindi ho usato la funzione cerca con scarsi risultati.. se come immagino non sono stato capace di usarla decentemente chiedo scusa a mod e admin (so quanto irriti vedere più volte uno stesso Topic :) ).
Quello che vorrei chiedervi è questo:
è possibile invertire un array ordinato a[i] senza usare nessun array di supporto?? per invertire intendo che da a {1, 2, 3, 4} voglio a {4, 3, 2, 1}.. posso farlo senza introdurre un eventuale b[i]?
Grazie :D
P.S. l'ho scritto nel titolo del topic, ma per sicurezza ribadisco che programmo in C :D
DanieleC88
09-12-2008, 18:38
Certo, si tratta di un'inversione in place/in loco. È un'operazione ricorsivamente banale:
void exchange(int *array, int i, int j)
{
int tmp = array[j];
array[j] = array[i];
array[i] = tmp;
}
Questa è semplicemente una funzione di appoggio: riceve l'array e i due indici degli elementi da scambiare.
Ora, siccome mi pare sia vietato dal regolamento dare le soluzioni agli esercizi, ti dico che manca solo un pezzetto di codice.
Immagina di avere due indici, uno che rappresenta l'elemento iniziale ed uno che rappresenta l'elemento finale dell'array, e pensa a cosa puoi fare con una funzione che scambia due elementi alla volta: penso che la soluzione sarà immediata. :)
fabri_napoli
09-12-2008, 19:35
Prima di tutto ti ringrazio per avermi risposto! :D
Seconda cosa... importantissima... voglio precisare che questo è il mio primo anno alla facoltà di informatica (l'anno scorso ero a psicologia... BLEEEAH!! XD).. e ho cominciato a studiare programmazione da un mesetto (perchè non prima? perchè sono un idiota e mi sono lasciato gli arretrati dicendo ok sì poi studio... :()..
ora provo a riportarti il codice del programma che ho scritto...
#include <stdio.h>
#include <stdlib.h>
int inverti (int *a, int i, int n);
main ()
{
int *a, n, i, j;
printf ("Quante locazioni deve contenere il tuo array?\n");
scanf ("%d", &n);
a= (int*) malloc (n*sizeof(int));
for (i=0; i<=n; i++) {
printf ("Inserisci il valore n.%d\n", i);
scanf ("%d", &a[i]); }
printf ("Gli elementi del tuo array sono inseriti in questo ordine:\n");
for (i=0; i<=n; i++) {
printf ("%d) %d\n", i, a[i]); }
inverti (a, i, n);
printf ("Ora gli elementi del tuo array sono inseriti in questo ordine:\n");
for (i=0; i<=n; i++) {
printf ("%d) %d\n", i, a[i]); }
system ("pause");
}
int inverti (int *a, int i, int n) {
int *ptemp, j;
for (i=0; i<(n/2); i++) {
*ptemp = a[j];
a[j] = a[i];
a[i] = *ptemp;
}
return *a;
}
come ho scritto anche in un altro topic.. puoi aiutarmi a capire cosa sbaglio?? cosa non ho capitoooo??? certo la soluzione mi farebbe piacere visto che tra poco prendo il pc, il devC, il manuale di C e li butto giù... XD
però poi alla fine la classica frase fatta "e che mi so imparato?" ritorna sempre... il 16 ho una prova di intercorso e se mi aiuti a capire ti sarei moooolto grato!!! :D
grazie milleeee!
DanieleC88
09-12-2008, 20:47
Innanzitutto, devi stare attento agli indici quando fai un loop: nel tuo caso hai usato:
for (i=0; i<=n; i++)
Questo è un tipico errore "off-by-one": tu all'inizio hai allocato memoria per un array di n elementi, ma gli indici dell'array vanno da 0 ad n-1. Quando termina il tuo loop? Dopo n iterazioni o dopo... n+1 iterazioni? Ragionaci un po' e capirai cosa succede, perché succede, e come fare per risolvere. ;)
Attenzione poi alle chiamate di funzioni:
inverti (a, i, n);
Cosa ti aspetti che faccia la funzione inverti()? Quali argomenti riceve, e perché? Logicamente io direi che gli indici dovrebbero delimitare a sinistra e a destra una porzione dell'array, quindi la prima chiamata dovrà ricevere due indici ben precisi (sia i che n sono errati).
Arriviamo al punto dolente... :D
int inverti (int *a, int i, int n) {
int *ptemp, j;
for (i=0; i<(n/2); i++) {
*ptemp = a[j];
a[j] = a[i];
a[i] = *ptemp;
}
return *a;
}
Vediamo:
int *ptemp: con questa hai appena dichiarato un puntatore ad una zona di memoria, ma non è né inizializzata (e quindi conterrà un valore più o meno casuale... a che memoria punta?), né allocata (hai riservato tu la memoria che è puntata?)
*ptemp = a[j]: qui l'errore è doppio; c'è sia l'errore di prima (stai effettivamente scrivendo in una zona di memoria non meglio definita), e stai leggendo da una posizione j nell'array, ma j non è inizializzata (né modificata mai durante il codice), quindi a quale elemento dell'array stai provando ad accedere? :D
ricevi un indice i in input ma poi lo usi come indice del loop, sovrascrivendo e quindi perdendo l'informazione ricevuta.
La variabile ptemp deve essere un semplice intero, non ha bisogno di puntare a niente (ed eventualmente puoi usare la funzione che ti ho scritto prima per effettuare degli scambi senza usare variabili aggiuntive).
In più, se avete già studiato la ricorsione ti dirò che la funzione inverti() può anche essere lunga esattamente due righe e funzionare correttamente. :D
ciao ;)
P.S.: Dev-C++? Ommadonna, quello è la fonte di molti problemi! Prova Code::Blocks... e ricorda sempre (almeno mentre studi) di compilare con tutti i warning del compilatore attivati (per GCC le opzioni sono -W -Wall, se l'IDE te lo chiedesse).
DanieleC88
09-12-2008, 20:54
Aspetta, mi era sfuggito anche che la memoria che allochi per il vettore poi non la liberi alla fine del main() con una free() corrispondente.
In definitiva, ti direi di ripassare:
puntatori (soprattutto questi visto il macello di prima :D), ed eventualmente allocazione dinamica della memoria
vettori (attento agli indici, secondo me ti sfugge qualcosa)
ricorsione (ripeto, se l'avete studiata, altrimenti lascia stare)
fabri_napoli
10-12-2008, 17:35
ho risolto così:
#include <stdio.h>
#include <stdlib.h>
int inverti (int *a, int n);
main ()
{
int *a, n, i;
printf ("Quante locazioni deve contenere il tuo array?\n");
scanf ("%d", &n);
a= (int*)malloc(n*sizeof(int));
for (i=1; i<=n; i++) {
printf ("Inserisci il valore n.%d\n", i);
scanf ("%d", &a[i]); }
printf ("Gli elementi del tuo array sono inseriti in questo ordine:\n");
for (i=1; i<=n; i++) {
printf ("%d) %d\n", i, a[i]); }
inverti (a, n);
printf ("Ora gli elementi del tuo array sono inseriti in questo ordine:\n");
for (i=1; i<=n; i++) {
printf ("%d) %d\n", i, a[i]); }
system ("pause");
}
int inverti (int *a, int n) {
int temp, i;
for (i=1; i<(n/2); i++) {
temp = a[i];
a[i] = a[n-i+1];
a[n-i+1] = temp;
}
}
così mi funziona! ho un po' cambiato il codice però... via puntatori XD
Se usi malloc() devi verificare che la memoria ti sia effettivamente restituita, cosa che non avviene sempre causa possibili memory leak (ancor piu' possibili nel tuo caso :sofico:) , visto che non usi mai la free() :D
fabri_napoli
10-12-2008, 18:00
Se usi malloc() devi verificare che la memoria ti sia effettivamente restituita, cosa che non avviene sempre causa possibili memory leak (ancor piu' possibili nel tuo caso :sofico:) , visto che non usi mai la free() :D
:eek: :eek:
che casotto :D ho il cervello in panne, maledico i pomeriggi trascorsi fuori al bar invece di tenere il passo col programma :D
:asd:
Comunque attento che il programma non funziona , io ho immesso il vettore {1,2,3,4,5} ed il risultato e' {5,2,3,4,1}
PS: l'indice dei vettori in c parte da 0 :D e non da 1
fabri_napoli
10-12-2008, 18:36
:asd:
Comunque attento che il programma non funziona , io ho immesso il vettore {1,2,3,4,5} ed il risultato e' {5,2,3,4,1}
PS: l'indice dei vettori in c parte da 0 :D e non da 1
!!!! è vero :( :eek:
mi hai sconvolto l'esistenza :( :(
fabri_napoli
10-12-2008, 19:02
Ho provato a cambiare qualcosina:
#include <stdio.h>
#include <stdlib.h>
int inverti (int *a, int n);
main ()
{
int n, i;
printf ("Quante locazioni deve contenere il tuo array?\n");
scanf ("%d", &n);
int a[n];
for (i=0; i<=n; i++) {
printf ("Inserisci il valore n.%d\n", i);
scanf ("%d", &a[i]); }
printf ("Gli elementi del tuo array sono inseriti in questo ordine:\n");
for (i=0; i<=n; i++) {
printf ("%d) %d\n", i, a[i]); }
inverti (a, n);
printf ("Ora gli elementi del tuo array sono inseriti in questo ordine:\n");
for (i=0; i<=n; i++) {
printf ("%d) %d\n", i, a[i]); }
system ("pause");
}
int inverti (int *a, int n) {
int temp, i;
for (i=0; i<=n; i++) {
temp = a[i];
a[i] = a[n-i+1];
a[n-i+1] = temp;
}
}
Ora mi inverte l'array, tranne l'ultimo valore :(
se inserisco {1, 2, 3, 4, 5} mi ritorna {5, 4, 3, 2, 92837482736} :( :( :(
perchè fa così? lo odio :(
Alex_87_xelA
10-12-2008, 19:12
scusate l'intromissione ... così funziona ? a me sembra di si :D
#include <stdio.h>
#include <stdlib.h>
int inverti (int *a, int n);
int main ()
{
int *a, n, i;
printf ("Quante locazioni deve contenere il tuo array?\n");
scanf ("%d", &n);
a= (int*)malloc(n*sizeof(int));
for (i=0; i<n; i++) {
printf ("Inserisci il valore n.%d\n", i+1);
scanf ("%d", &a[i]); }
printf ("Gli elementi del tuo array sono inseriti in questo ordine:\n");
for (i=0; i<n; i++) {
printf ("%d) %d\n", i+1, a[i]); }
inverti (a, n);
printf ("Ora gli elementi del tuo array sono inseriti in questo ordine:\n");
for (i=0; i<n; i++) {
printf ("%d) %d\n", i+1, a[i]); }
system ("pause");
return 0;
}
int inverti (int *a, int n)
{
int temp, i;
for (i=0; i<(n/2); i++)
{
temp = a[i];
a[i] = a[n-1 -i];
a[n-1 -i] = temp;
}
return 0;
}
però bisogna aggiungere una cosa !!! mi sapete dire cosa ? :D
DanieleC88
10-12-2008, 19:57
Pensa alla soluzione più semplice! Usa due indici ed hai risolto.
Pseudocodice:
inverti(array, inizio, fine)
if inizio < fine:
scambia(array, inizio, fine)
inverti(array, inizio+1, fine-1)
Che ovviamente puoi ridurre ad una forma iterativa:
inverti(array, lunghezza)
i = 0
j = lunghezza-1
while i < j:
scambia(array, i, j)
i = i+1
j = j-1
Per il resto, una volta allocata la memoria atttento a non sforare dalla dimensione allocata e ricordati di liberarla una volta che non ti è più necessaria, tutto qui.
ciao ;)
DanieleC88
10-12-2008, 20:04
però bisogna aggiungere una cosa !!! mi sapete dire cosa ? :D
:wtf:
Cos'è, un quiz? Chi vuol essere milionario? :D
Alex_87_xelA
10-12-2008, 20:11
:wtf:
Cos'è, un quiz? Chi vuol essere milionario? :D
hehehe hai ragione ... la deallocazione :D
fabri_napoli
10-12-2008, 20:55
siete dei maledettissimi geni :eek:
non avete idea di quanto vi sono grato :( se riuscirò a prendere un voto decente sarà anche merito vostro :D
grazie ancora!! :D
a presto :)
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.