PDA

View Full Version : Scambi virtuali in c....


progC__
17-09-2005, 08:54
...qualcuno può aiutarmi a chiarire questa funzione....? allora devo scambiare posto all'elemento di un array mediante uno scambio virtuale...la funzione che ho scritto vale come scambio virtuale o comunque effettua uno scambio fisico? :confused: :confused: :confused: :muro:


void scambia_ele_array (int *v,int i,int j)
{
int temp;
temp = *(v+i);
*(v+i)= *(v+j);
*(v+j)= temp;
}

VegetaSSJ5
17-09-2005, 19:38
cosa intendi per scambio virtuale e fisico?
la tua funzione comunque scambia proprio "fisicamente" i valori all'interno dell'array, cioè dopo l'uscita dalla funzione nell'array ci saranno i valori invertiti rispetto a prima dell'esecuzione della funzione.

cionci
17-09-2005, 22:29
...qualcuno può aiutarmi a chiarire questa funzione....? allora devo scambiare posto all'elemento di un array mediante uno scambio virtuale...la funzione che ho scritto vale come scambio virtuale o comunque effettua uno scambio fisico? :confused: :confused: :confused: :muro:
Non so cosa intendi di preciso, ma se ho capito parli di quello che succede con le liste... In una lista puoi scambiare due elementi modificando la posizione all'interno delal lista dell'intera struttura (scambio fisico) o del solo valore contenuto nelal struttura (a questo punto direi scambio virtuale)... Sinceramente queste definizioni sono un po' assurde...
Comunque non si può applicare ad un array...

progC__
18-09-2005, 07:47
...non si tratta di liste...ma di array...per scambio virtuale intendo uno scambio di posizione tra elementi in un array effettuato tramite puntatori...praticamente al posto di spostare gli elementi fisicamente devo spostare i puntatori che puntano agli elementi per non effettuare lo scambio fisico...come dovrei fare?... :confused:

cionci
18-09-2005, 07:56
...non si tratta di liste...ma di array...per scambio virtuale intendo uno scambio di posizione tra elementi in un array effettuato tramite puntatori...praticamente al posto di spostare gli elementi fisicamente devo spostare i puntatori che puntano agli elementi per non effettuare lo scambio fisico...come dovrei fare?... :confused:
Guarda...in un vettore anche se usi i puntatori fai sempre lo scambio fisico... L'unico scambio, se si può chiamare così, virtuale è quello che si fa sulle liste...

progC__
18-09-2005, 08:05
Guarda...in un vettore anche se usi i puntatori fai sempre lo scambio fisico... L'unico scambio, se si può chiamare così, virtuale è quello che si fa sulle liste...

...e allora la prof che intende per scambio virtuale su un array di struct?... come devo risolvere...e se creo un puntatore esterno all'array, anzi due puntatori per scambiare i due elementi...che dici? si potrebbe fare?

cionci
18-09-2005, 08:10
Al massimo intederà non scambiare l'intera struct, ma solo l'informazione che ti interessa... Mi fai vedere com'è la struct ?

cionci
18-09-2005, 08:11
e se creo un puntatore esterno all'array, anzi due puntatori per scambiare i due elementi...che dici? si potrebbe fare?
Lo puoi fare, ma stai sempre scambiando fisicamente le due strutture...
Fammi vedere anche cosa intende per scambio fisico sempre con le stesse strutture... Queste definizioni sono molto aleatorie...

progC__
18-09-2005, 08:12
Al massimo intederà non scambiare l'intera struct, ma solo l'informazione che ti interessa... Mi fai vedere com'è la struct ?

//ARRAY STRUTTURA
struct array_struct{
int *a;
int indice;
};

cionci
18-09-2005, 08:12
In *a che ci metti ? Perchè è presente anche indice all'intenro della struct ? E' quella che imposta l'ordine reale ?

progC__
18-09-2005, 08:14
In *a che ci metti ? Perchè è presente anche indice all'intenro della struct ? E' quella che imposta l'ordine reale ?
ti faccio vedere tutto il programma così ti è più chiaro...

/*selection sort iterativo*/

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

//ARRAY STRUTTURA
struct array_struct{
int *a;
int indice; //chiave dell'array
};

typedef struct array_struct ARRAY;
void iniarray (ARRAY *ar, int len);
void ord_selezione (ARRAY *a,int n);
void main ()
{
ARRAY v;
int size;
srand((unsigned) time(NULL));
printf ("Inserisci il numero di elementi dell'array: \n");
scanf ("%d",&size);
iniarray (&v,size);
v.a = malloc(size);
if (v.a == NULL){
puts ("ERRORE ALLOCAZIONE MEMORIA");
exit(1);
}
printf ("L'array generato in modo rand e': \n");
for (v.indice = 0; v.indice < size; v.indice++){
v.a[v.indice] = rand() % 50;
printf (" %d\n",v.a[v.indice]);
}
//chiamata funzione per ordinare l'array creato
ord_selezione (&v,size);
printf ("L'array ordinato e': \n");
for (v.indice = 0; v.indice<size; v.indice++)
printf (" %d\n",v.a[v.indice]);
}


//funzione selection sort (minimo)
void scambia_ele_array (int v[],int i,int j);
void ord_selezione (ARRAY *a,int n)
{
int indice_min,k; /*indice_min è il minimo valore di tutto l'array*/
for (a->indice = 0; a->indice<n-1;a->indice++)
{
indice_min = a->indice; /*inizializzazione del'indice minimo*/
for (k=a->indice+1;k<n;k++) /*analizza gli elementi dopo il primo indice per trovare il minimo*/
{
if (a->a[indice_min] > a->a[k]) /*se l'indice minimo è maggiore di tutti gli altri elementi dell'array*/
indice_min = k; /*il valore minimo è k rispetto tutta la porzione dell'array*/
}
scambia_ele_array (a->a,a->indice,indice_min); /*una volta stabilito il minimo bisogna scambiare i posti dei*/
} /*due indici per mettere all'inizio il valore più piccolo e via via ad ogni passo riordinare*/
} /*l'array*/


//funzione scambia posto virtualemnte elementi array
void scambia_ele_array (int *v,int i,int j)
{
int temp;
temp = *(v+i);
*(v+i)= *(v+j);
*(v+j)= temp;
}

//inizializza array struct
void iniarray (ARRAY *ar, int len)
{
ar->a = malloc(len);
if (ar == NULL){ puts ("ERRORE ALLOCAZIONE MEMORIA");
exit(1);
}
ar->indice = -1;
}

cionci
18-09-2005, 08:26
Intanto questo è un errore grave: v.a = malloc(size);

v.a = malloc(size * sizeof(int));

Stesso errore anche qui: ar->a = malloc(len);

Comunque l'allocazione dell'array viene già fatta da iniarray, non importa farla anche nel main...anzi è un errore grave farla due volte, perchè hai un memory leak...

Allora...questo non è un array di struct, ma una struttura singola (nota che c'è una sola istanza della struttura ARRAY in tutto il programma)... La variabile ordine non serve praticamente a niente, visto che può essere tranquillamente sostituita da una variabile locale a ord_selezione...

Per lo scambio...ritorno alla considerazione di prima...non esiste scambio virtuale...ache se usi i puntatori (come è stato fatto) è sempre uno scambio fisico...

Ma questo è un programma che ti ha dato la prof o l'hai fatto tu ?

progC__
18-09-2005, 08:33
Intanto questo è un errore grave: v.a = malloc(size);

v.a = malloc(size * sizeof(int));

Stesso errore anche qui: ar->a = malloc(len);

Comunque l'allocazione dell'array viene già fatta da iniarray, non importa farla anche nel main...anzi è un errore grave farla due volte, perchè hai un memory leak...

Allora...questo non è un array di struct, ma una struttura singola (nota che c'è una sola istanza della struttura ARRAY in tutto il programma)... La variabile ordine non serve praticamente a niente, visto che può essere tranquillamente sostituita da una variabile locale a ord_selezione...

Per lo scambio...ritorno alla considerazione di prima...non esiste scambio virtuale...ache se usi i puntatori (come è stato fatto) è sempre uno scambio fisico...

Ma questo è un programma che ti ha dato la prof o l'hai fatto tu ?

...il programma l'ho fatto io...la traccia è della prof. L'allocazione nel main lo so che è sbagliata e non l'ho cancellata per dimenticanza....ma perchè si fa size * sizeof(int).... per il tipo di elementi che contiene l'array?

cionci
18-09-2005, 08:41
Mi dai la traccia della prof ?

Perchè il parametro di malloc è il numero di byte da allocare... Quindi se vuoi allocare 5 elementi di un certo tipo devi fare sizeof(tipo) * 5, visto che sizeof ritorna il numero di byte occupati da quel dato tipo...

Tra l'altro si fa un cast esplicito (visto che malloc ritorna un void *):

int *a = (int *) malloc(sizeof(int)*n);

progC__
18-09-2005, 08:48
Mi dai la traccia della prof ?

Perchè il parametro di malloc è il numero di byte da allocare... Quindi se vuoi allocare 5 elementi di un certo tipo devi fare sizeof(tipo) * 5, visto che sizeof ritorna il numero di byte occupati da quel dato tipo...

Tra l'altro si fa un cast esplicito (visto che malloc ritorna un void *):

int *a = (int *) malloc(sizeof(int)*n);

IMPLEMENTARE IN C:
L'ALGORITMO SELECTION SORT SU UN ARRAY DI STRUTTURA:
IN VERSIONE ITERATIVA E RICORSIVA;
MEDIANTE SCAMBI REALI E SCAMBI VIRTUALI.

progC__
18-09-2005, 08:57
...non c'è proprio nessun modo per fare sto scambio virtuale...(insisto perchè tengo l'esame...aiuto)...cmq grazie per le correzioni e spiegazioni cionci :)

cionci
18-09-2005, 08:59
Quello tuo non è un array di strutture... Comunque ha poco senso anche il testo della prof... A che serve fare un array di strutture se l'informazione da ordinare è una sola ?

Avrebbe senso se fosse una lista...

Qu@ker
18-09-2005, 13:56
Se non chiarisci cosa intende con scambio virtuale e scambio fisico, e' difficile risponderti. D'altra parte, di sicuro noi a lezione non c'eravamo...
Una possibile interpretazione:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

typedef struct struttura {
char stringa[31];
int len;
} elemento;

void inizializza_array(elemento **e, int len)
{
int i;

for (i = 0; i < len; ++i) {
int l = 1 + rand()%30;
e[i] = malloc(sizeof(elemento));
e[i]->len = l;
memset(e[i]->stringa, 'A', l);
e[i]->stringa[l] = '\0';
}
}

void scambio_virtuale (elemento **e, int i, int j)
{
elemento *tmp = e[i];
e[i] = e[j];
e[j] = tmp;
}

void scambio_fisico (elemento **e, int i, int j)
{
elemento tmp = *(e[i]);
*(e[i]) = *(e[j]);
*(e[j]) = tmp;
}

void ordina(elemento **e, int len)
{
int i, j;

for (i = 0; i < len-1; ++i) {
int min = i;
for (j = i+1; j < len; ++j)
if (e[j]->len < e[min]->len)
min = j;
scambio_virtuale(e, min, i);
/* scambio_fisico(e, min, i); */
}
}

void elimina_array(elemento **e, int len)
{
int i;

for (i = 0; i < len; ++i)
free(e[i]);
}

#define DIM 10

int main(void)
{
int i;
elemento *array[DIM];

srand(time(NULL));
inizializza_array(array, DIM);
puts("Prima della cura:");
for (i = 0; i < DIM; ++i)
puts(array[i]->stringa);
ordina(array, DIM);
puts("\nDopo la cura:");
for (i = 0; i < DIM; ++i)
puts(array[i]->stringa);
elimina_array(array, DIM);
return 0;
}

progC__
18-09-2005, 14:53
Se non chiarisci cosa intende con scambio virtuale e scambio fisico, e' difficile risponderti. D'altra parte, di sicuro noi a lezione non c'eravamo...
Una possibile interpretazione:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

typedef struct struttura {
char stringa[31];
int len;
} elemento;

void inizializza_array(elemento **e, int len)
{
int i;

for (i = 0; i < len; ++i) {
int l = 1 + rand()%30;
e[i] = malloc(sizeof(elemento));
e[i]->len = l;
memset(e[i]->stringa, 'A', l);
e[i]->stringa[l] = '\0';
}
}

void scambio_virtuale (elemento **e, int i, int j)
{
elemento *tmp = e[i];
e[i] = e[j];
e[j] = tmp;
}

void scambio_fisico (elemento **e, int i, int j)
{
elemento tmp = *(e[i]);
*(e[i]) = *(e[j]);
*(e[j]) = tmp;
}

void ordina(elemento **e, int len)
{
int i, j;

for (i = 0; i < len-1; ++i) {
int min = i;
for (j = i+1; j < len; ++j)
if (e[j]->len < e[min]->len)
min = j;
scambio_virtuale(e, min, i);
/* scambio_fisico(e, min, i); */
}
}

void elimina_array(elemento **e, int len)
{
int i;

for (i = 0; i < len; ++i)
free(e[i]);
}

#define DIM 10

int main(void)
{
int i;
elemento *array[DIM];

srand(time(NULL));
inizializza_array(array, DIM);
puts("Prima della cura:");
for (i = 0; i < DIM; ++i)
puts(array[i]->stringa);
ordina(array, DIM);
puts("\nDopo la cura:");
for (i = 0; i < DIM; ++i)
puts(array[i]->stringa);
elimina_array(array, DIM);
return 0;
}


Allora: per scambio fisico intendo che gli elementi dell'array vengono spostati realmente cioè viene preso l'elemento e spostato in un altra posizione nell'array, per lo scambio virtuale ciò non dovrebbe avvenire, praticamente gli elementi non cambiano posto, rimangono dove sono, ma ciò che cambia sono i puntatori che permettono tale scambio...

cionci
18-09-2005, 15:28
per lo scambio virtuale ciò non dovrebbe avvenire, praticamente gli elementi non cambiano posto, rimangono dove sono, ma ciò che cambia sono i puntatori che permettono tale scambio...
In un vettore allora non lo puoi fare, sempre che tu intenda ordinare gli elementi secondo le posizioni all'interno dell'array... Questo perchè in un array la posizione di ordine i-esima corrisponde alla i-esima unità di allocazione...quindi per spostare un elemento dalla posizione di ordine j alla posizione di ordine i devi spostarne il contenuto fisicamente dall'unità di allocazione j-esima all'unità di allocazione i-esima...

beppegrillo
18-09-2005, 16:07
Forse non è che intenda di tenere un vettore ordinato dapprima così
(1,2,3,4,5,...) ed ogni volta che fai uno scambio tra elementi sposti i valori in quel vettore, poi per accedere all'array modificato usi gli a[b[i]] i=0...n
dove b è il vettore degli "spostamenti".

cionci
18-09-2005, 16:12
Forse non è che intenda di tenere un vettore ordinato dapprima così
Mah...chi lo sa... Più che altro è il testo dell'esercizio che non mi torna... Un vettore di struct ?!?!?!?

progC__
18-09-2005, 17:16
In un vettore allora non lo puoi fare, sempre che tu intenda ordinare gli elementi secondo le posizioni all'interno dell'array... Questo perchè in un array la posizione di ordine i-esima corrisponde alla i-esima unità di allocazione...quindi per spostare un elemento dalla posizione di ordine j alla posizione di ordine i devi spostarne il contenuto fisicamente dall'unità di allocazione j-esima all'unità di allocazione i-esima...
... e se creo un secondo array che contiene i puntatori che punteranno gli elementi del primo array... dovrebbe andare bene?...spero.... :doh:

progC__
18-09-2005, 17:18
In un vettore allora non lo puoi fare, sempre che tu intenda ordinare gli elementi secondo le posizioni all'interno dell'array... Questo perchè in un array la posizione di ordine i-esima corrisponde alla i-esima unità di allocazione...quindi per spostare un elemento dalla posizione di ordine j alla posizione di ordine i devi spostarne il contenuto fisicamente dall'unità di allocazione j-esima all'unità di allocazione i-esima...

e se creo un secondo array contenente i puntatori agli elementi del primo array...andrebbe bene?...spero :doh:

cionci
18-09-2005, 17:21
... e se creo un secondo array che contiene i puntatori che punteranno gli elementi del primo array... dovrebbe andare bene?...spero.... :doh:
Ma il vettore di struct del testo dov'è ? :)
Puoi sicuramente ordinare il vettore anche semplciemente ordinandone i puntatori... In questo modo lo scambio è per modo di dire virtuale perchè la posizione del dato originale è la stessa...

progC__
18-09-2005, 17:26
Ma il vettore di struct del testo dov'è ? :)
Puoi sicuramente ordinare il vettore anche semplciemente ordinandone i puntatori... In questo modo lo scambio è per modo di dire virtuale perchè la posizione del dato originale è la stessa...

...quindi come ho detto primo con due array va bene? :confused: due array? ;)

cionci
18-09-2005, 19:19
...quindi come ho detto primo con due array va bene? :confused: due array? ;)
A qul punto lo scambio 'virtuale' ce l'avresti, ma il vettore di strutture quale sarebbe ?!?!? :D

progC__
18-09-2005, 22:29
A qul punto lo scambio 'virtuale' ce l'avresti, ma il vettore di strutture quale sarebbe ?!?!? :D

... :D :D :D ...e mi sa che lo rimango così il programma...boh :doh: ...

3nigma666
18-09-2005, 22:39
scusa ma non basta utilizzarre un semplice xor???? fai lo zor e in una riga hai risolto tutto:

void swap (long& a, long& b) {
a ^= b ^= a ^= b;
};


ed è anche un metodo inplace per scambiare i valori,non hai bisogno di alcun tipo di array opzionale e lo puoi utilizzare con float int double! a posto di a e b usi le tue variabilì!

progC__
18-09-2005, 22:47
scusa ma non basta utilizzarre un semplice xor???? fai lo zor e in una riga hai risolto tutto:

void swap (long& a, long& b) {
a ^= b ^= a ^= b;
};


ed è anche un metodo inplace per scambiare i valori,non hai bisogno di alcun tipo di array opzionale e lo puoi utilizzare con float int double! a posto di a e b usi le tue variabilì!

...ma usando anche lo xor gli scambi non avvengono lo stesso fisicamente...o no?...a me sembra proprio di si.... :confused:

cionci
18-09-2005, 22:47
Sì, ma anche quello è uno scambio 'fisico'...cioè vai a mettere a nella posizione di b e viceversa...

3nigma666
18-09-2005, 22:58
beh bvasta fare una piccolissima modifica e passare il parametro alla funzione per riferimento e non per valore e il gioco è fatto!!LA tua struttura rimane intatta ,non hai bisogno di alcuna tipoligia di array supplementare o particolari strategie

void swap (long *a,long *b)
{
a ^= b ^= a ^= b;
}


cambi gli indirizzi ma non la struttura.

cionci
19-09-2005, 06:52
Quella funzione non fa assolutamente niente :)
Scambia due indirizzi, ma la modifica non si riflette sui dati e soprattutto sul programma chiamante, anche perchè hai passato gli indirizzi per valore...

3nigma666
19-09-2005, 12:55
e non è quello ke vuole lui??allora no nho capito cosa vuole

cionci
19-09-2005, 13:50
e non è quello ke vuole lui??allora no nho capito cosa vuole
Ripeto...il codice che hai postato sopra non ha alcun effetto...con qualsiasi dato gli passi ;)