[C] Funzione che dovrebbe restituire un vettore

Suwako27
Ciao a tutti, ho dei dubbi riguardo le funzioni che dovrebbero ritornare ""array"":
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void trovaMax(int* a, int n)
 {
	 int cont = 0;

    if(*a > *(a + 1)) {printf("%d|", *a); cont++;}
	 int* b = a + 10;
	 a++;
	 while(a < b)
	 {
		 if((*a > *(a - 1))&&(*a > *(a + 1)))
		 {
			printf("%d|", *a); cont++;
		 }
		 a++;
	 }
    if(*b > *(b - 1)) {printf("%d|", *b); cont++;}
	 printf("\n\n%d", cont);
}
int main()
{
	srand(time(0));
	int n = 11;
	int* a = malloc(sizeof(int)*n);
	for(size_t i = 0; i < n; i++)
	{
		a[i] = rand()% 300;
		printf("%d|", a[i]);
	}
	puts("\n");
	trovaMax(a, n);
}

Il testo di questo esercizio chiede di trovare in un array i "max parziali", cioè quei termini che sono più grandi di quelli adiacenti. Tuttavia è richiesto che il prototipo della funzione sia del tipo: int * TrovaMaxParziale(int * a,int N); cioè si dovrebbero inserire tutti i max parziali all'interno di questo array. E' possibile quindi fare questa modifica senza complicare inutilmente il codice?

Risposte
Suwako27
"DeltaEpsilon":
[quote="Suwako27"]
non ho capito cosa hai detto :lol:


Sei stato risposto sulle questioni precedenti, e poni la stessa domanda.
Ti ho risposto sul perchè non è buona norma usare la stampa nelle funzioni, e poni la stessa domanda.

Direi (anzi, ripeto) che le risposte ti son state già date... e pure in italiano per quanto ne so... lavora sulla comprensione a questo punto, che ti devo dire...

"Suwako27":

se la funzione dovrebbe soltanto trovare dei valori non sarebbe meglio semplicemente stamparli a video senza andare a "disturbare" la memoria ? :?


Negli esercizi scolastici si può anche fare questo strappo, ma non è assolutamente buona norma di programmazione. E siccome state imparando a programmare, non vedo perchè insegnarvi e abituarvi male.

Se tu chiami la funzione sqrt per ottenere la radice quadrata di un numero, per poi utilizzarla in un altro calcolo, hai bisogno che quella funzione ritorni il valore atteso... e così succede.

Non ti darebbe fastidio se la funzione si permettesse di stampare il valore anzichè ritornartelo? Oltre ad essere tremendamente inutile...




Se ti preoccupi così tanto della memoria, libera quella allocata dinamicamente :lol:[/quote] La stai facendo tragica; Io tutte queste risposte esaustive da te non le trovo :wink:

DeltaEpsilon
"Suwako27":
La stai facendo tragica; Io tutte queste risposte esaustive da te non le trovo :wink:


Mi chiedo cosa significhi per te esaustivo, se qualsiasi cosa ti venga detta la ignori e riproponi la stessa domanda.

Nonostante tu non abbia capito, ti ho risposto nuovamente nel post precedente, spiegandoti l'importanza delle funzioni che ritornano e l'inutilità delle funzioni che al loro interno stampano e/o chiedono input dall'utente.

E mi devo sentir dire che sono tragico e poco esaustivo :-D

Ma va va

Suwako27
Comunque rigrazio tutti per le risposte; alla fine ho risolto i miei dubbi.

Suwako27
Questo è il testo dell'esercizio. Ho capito cosa deve fare la funzione; ma mi rimane solo di capire il come avere l'output esatto degli elementi . Come fa il main a sapere la dimensione dell'array che la funzione alloca dinamicamente ogni volta? Solo questo nient'altro. :cry:

Scrivere la funzione int * TrovaMaxParziale(int * a,int N);che ricevuto in ingresso un vettore di N interi, restituisca un vettore di interi con i massimi relativi del vettore. I massimi relativi hanno la caratteristica di avere l’elemento precedente e successivo minori di esso. Per il primo elemento verificare che il successivo sia minore, mentre per l’ultimo elemento verificare solo che il precedente sia minore. Es.:
input: [11,22,33,44,5,66,7,88,99,10,202]
output: [44,66,99,202]

Super Squirrel
"Suwako27":
Come fa il main a sapere la dimensione dell'array che la funzione alloca dinamicamente ogni volta?

"Super Squirrel":
Prima di parlare dell'algoritmo ti faccio una domanda: in che modo una funzione del tipo
int* TrovaMaxParziale(int *a, int N);

potrebbe darti informazioni sulla dimensione "utile" dell'array ritornato?

"apatriarca":
Un'ulteriore problematica quando si ha a che fare con array è quella di sapere il numero di elementi inserito. In questo caso abbiamo le seguenti soluzioni:

1. Non fare nulla (nel caso in cui sia già conosciuta la dimensione per altre ragioni).
2. Usare un valore come terminatore dell'array (usanto spesso nelle stringhe).
3. Se l'array è numerico, puoi usare il primo elemento come dimensione dell'array.
4. Puoi usare un argomento della funzione per questo scopo. Avrai quindi un argomento, qualcosa come [tt]int *outN[/tt], che dovrai riempire con il valore richiesto.
5. Nel caso tu stia usando la soluzione 2 sopra, puoi usare il valore di ritorno della funzione per restituirne la dimensione.
6. Puoi restituire una struttura invece che un puntatore nella soluzione 1 sopra.

"Super Squirrel":

Noto che hai ignorato la mia precedente domanda, in ogni caso, rifacendomi al post di @apatriarca, credo che con quel prototipo l'unica strada percorribile sia la numero 3).

"Super Squirrel":
E a tal proposito, visto che il prototipo della funzione deve essere quello, l'unica strada percorribile diventa il punto 3) prospettato da @apatriarca.

Il problema ti è stato fatto notare fin dall'inizio e ti è stata anche suggerita una soluzione. L'hai capita? Sei in grado di implementarla?

Suwako27
Non ho capito cosa intendesse di preciso con quel punto infatti.

Suwako27
"Super Squirrel":
[quote="Suwako27"]Come fa il main a sapere la dimensione dell'array che la funzione alloca dinamicamente ogni volta?

"Super Squirrel":
Prima di parlare dell'algoritmo ti faccio una domanda: in che modo una funzione del tipo
int* TrovaMaxParziale(int *a, int N);

potrebbe darti informazioni sulla dimensione "utile" dell'array ritornato?

"apatriarca":
Un'ulteriore problematica quando si ha a che fare con array è quella di sapere il numero di elementi inserito. In questo caso abbiamo le seguenti soluzioni:

1. Non fare nulla (nel caso in cui sia già conosciuta la dimensione per altre ragioni).
2. Usare un valore come terminatore dell'array (usanto spesso nelle stringhe).
3. Se l'array è numerico, puoi usare il primo elemento come dimensione dell'array.
4. Puoi usare un argomento della funzione per questo scopo. Avrai quindi un argomento, qualcosa come [tt]int *outN[/tt], che dovrai riempire con il valore richiesto.
5. Nel caso tu stia usando la soluzione 2 sopra, puoi usare il valore di ritorno della funzione per restituirne la dimensione.
6. Puoi restituire una struttura invece che un puntatore nella soluzione 1 sopra.

"Super Squirrel":

Noto che hai ignorato la mia precedente domanda, in ogni caso, rifacendomi al post di @apatriarca, credo che con quel prototipo l'unica strada percorribile sia la numero 3).

"Super Squirrel":
E a tal proposito, visto che il prototipo della funzione deve essere quello, l'unica strada percorribile diventa il punto 3) prospettato da @apatriarca.

Il problema ti è stato fatto notare fin dall'inizio e ti è stata anche suggerita una soluzione. L'hai capita? Sei in grado di implementarla?[/quote] anche la numero 2 potrebbe risolvere la cosa

Super Squirrel
"Suwako27":
Non ho capito cosa intendesse di preciso con quel punto infatti.

Il primo elemento dell'array è pari al numero di elementi successivi. Per esempio:

1 2

5 80 1 57 4 32

0

"Suwako27":
anche la numero 2 potrebbe risolvere la cosa

E quale valore vorresti utilizzare che non può essere confuso con uno dei massimi trovati?

Suwako27
"Super Squirrel":
[quote="Suwako27"]Non ho capito cosa intendesse di preciso con quel punto infatti.

Il primo elemento dell'array è pari al numero di elementi successivi. Per esempio:

1 2

5 80 1 57 4 32

0

"Suwako27":
anche la numero 2 potrebbe risolvere la cosa

E quale valore vorresti utilizzare che non può essere confuso con uno dei massimi trovati?[/quote]
-1 :D

Super Squirrel
vettore in ingresso: 9 2 7 5 -3 -1

vettore in uscita: 9 7 -1

:D

Suwako27
funzionerebbe solo per gli interi positivi però è possibile stampare gli elementi anche senza includerlo. Invece per il punto 3, se ho capito, non bisognerebbe modificare gli elementi dell'array successivamente averne calcolato il numero interessato?

Super Squirrel
"Suwako27":
funzionerebbe solo per gli interi positivi

Ovviamente nel caso di un array di unsigned int tale metodo funzionerebbe.

"Suwako27":
però è possibile stampare gli elementi anche senza includerlo.

:?:

"Suwako27":
Invece per il punto 3, se ho capito, non bisognerebbe modificare gli elementi dell'array successivamente averne calcolato il numero interessato?

Basta prevedere un array di $[(N+1)/2]+1$ elementi, dove il primo elemento ci dice quanti dei successivi $[(N+1)/2]$ spazi sono stati effettivamente utilizzati.

Suwako27
"Super Squirrel":
[quote="Suwako27"]funzionerebbe solo per gli interi positivi

Ovviamente nel caso di un array di unsigned int tale metodo funzionerebbe.

"Suwako27":
però è possibile stampare gli elementi anche senza includerlo.

:?:

"Suwako27":
Invece per il punto 3, se ho capito, non bisognerebbe modificare gli elementi dell'array successivamente averne calcolato il numero interessato?

Basta prevedere un array di $ [(N+1)/2]+1 $ elementi, dove il primo elemento ci dice quanti dei successivi $ [(N+1)/2] $ spazi sono stati effettivamente utilizzati.[/quote]
#include <stdio.h>
#include <stdlib.h>
#include <time.h>



 int* trovaMax(int* A, int n)
 {
	 int counter = 0;
	 int size = (n+1)/2;
	 int* V = malloc(sizeof(int)*(size + 1));
	 int* temp = V;
	 V++;
	 
	 for(unsigned int i = 0; i < n; ++i)
    {
        if((!i || A[i] > A[i - 1]) && (i == n - 1 || A[i] > A[i + 1]))
        {
            *V = A[i];
			counter++;
			V++; 
        }
    }	
	V = temp;
	*V = counter;
	
	printf("\n%d\n", *V);
    return V;
 }
int main()
{
	srand(time(0));
	int n = 11;
	int A[n];
	for(size_t i = 0; i < n; ++i)
	{
		A[i] = rand()% 300;
		printf("%d|", A[i]);
	}
	puts("\n");
	int * V = trovaMax(A, n);
	for(unsigned int j = 1; j <= V[0]; ++j)
	{
		printf("%d|", V[j]);
	}
	 free(V);
}

159|85|166|238|198|7|43|120|299|108|282|


4
159|238|299|282|

vict85
"Suwako27":
Questo è il testo dell'esercizio. Ho capito cosa deve fare la funzione; ma mi rimane solo di capire il come avere l'output esatto degli elementi . Come fa il main a sapere la dimensione dell'array che la funzione alloca dinamicamente ogni volta? Solo questo nient'altro. :cry:

Scrivere la funzione int * TrovaMaxParziale(int * a,int N);che ricevuto in ingresso un vettore di N interi, restituisca un vettore di interi con i massimi relativi del vettore. I massimi relativi hanno la caratteristica di avere l’elemento precedente e successivo minori di esso. Per il primo elemento verificare che il successivo sia minore, mentre per l’ultimo elemento verificare solo che il precedente sia minore. Es.:
input: [11,22,33,44,5,66,7,88,99,10,202]
output: [44,66,99,202]


Questo tipo di dubbi andrebbero chiariti con la persona che ha scritto il testo dell'esercizio. Anche perché quella persona avrà della preferenze e addirittura potrebbe voler cambiare il testo dell'esercizio. Infatti il punto 3 proposto da apatriarca non è altro che una versione "implicita" di
typedef struct { int size; int * data } Array;
Array TrovaMaxParziale(int * a, int N);

oppure usando i flexible array member (introdotti nel c99 e che non hanno a dire il vero avuto molta fortuna[nota]La differenza è che la variabile size è allocata insieme all'array, esattamente come nel punto 3. Mentre con la struttura la dimensione è allocata vicino al puntatore. Il C++ non li supporta.[/nota])
typedef struct { int size; int data[]; } Array;
Array* TrovaMaxParziale(int * a, int N);

Suwako27
"vict85":
[quote="Suwako27"]Questo è il testo dell'esercizio. Ho capito cosa deve fare la funzione; ma mi rimane solo di capire il come avere l'output esatto degli elementi . Come fa il main a sapere la dimensione dell'array che la funzione alloca dinamicamente ogni volta? Solo questo nient'altro. :cry:

Scrivere la funzione int * TrovaMaxParziale(int * a,int N);che ricevuto in ingresso un vettore di N interi, restituisca un vettore di interi con i massimi relativi del vettore. I massimi relativi hanno la caratteristica di avere l’elemento precedente e successivo minori di esso. Per il primo elemento verificare che il successivo sia minore, mentre per l’ultimo elemento verificare solo che il precedente sia minore. Es.:
input: [11,22,33,44,5,66,7,88,99,10,202]
output: [44,66,99,202]


Questo tipo di dubbi andrebbero chiariti con la persona che ha scritto il testo dell'esercizio. Anche perché quella persona avrà della preferenze e addirittura potrebbe voler cambiare il testo dell'esercizio. Infatti il punto 3 proposto da apatriarca non è altro che una versione "implicita" di
typedef struct { int size; int * data } Array;
Array TrovaMaxParziale(int * a, int N);

oppure usando i flexible array member (introdotti nel c99 e che non hanno a dire il vero avuto molta fortuna[nota]La differenza è che la variabile size è allocata insieme all'array, esattamente come nel punto 3. Mentre con la struttura la dimensione è allocata vicino al puntatore. Il C++ non li supporta.[/nota])
typedef struct { int size; int data[]; } Array;
Array* TrovaMaxParziale(int * a, int N);
[/quote] L'esercizio fa parte solo del primo modulo del programma del corso e ancora non erano state introdotte le strutture dati.

vict85
"Suwako27":
L'esercizio fa parte solo del primo modulo del programma del corso e ancora non erano state introdotte le strutture dati.


Certo, ma potrebbe voler cambiare la funzione in
int * TrovaMaxParziale(int * a, int N, int* out_size);
o comunque dire esplicitamente come vuole che sia comunicata la dimensione dell'array.

apatriarca
Suppongo che come terminatore per l'array si debba usare [tt]INT_MIN[/tt] (costante definita in [tt]limits.h[/tt]) per gli interi con segno. Essendo infatti il numero intero rappresentabile più piccolo, non può essere un massimo parziale per l'array.

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.