Esercizio C difficilino (per me)

di il
8 risposte

Esercizio C difficilino (per me)

L'esercizio è il seguente: Dato un vettore con all'interno degli '1','0' e '*', con '*' che può valere sia 0 che 1, stampa indietro tutte le possibili combinazioni. L'ordine delle combinazioni non è importante.
Esempi: 00* -> 000 e 001; 0**0--> 0000, 0010, 0100, 0110 etc
Cerco un input per iniziarlo, non ho veramente idea di come fare

8 Risposte

  • Re: Esercizio C difficilino (per me)

    Innanzitutto inquadriamo e semplifichiamo (momentaneamente) il problema. Del vettore iniziale ci interessa solo il numero di *, a questo punto quello che dobbiamo fare è generare tutte le possibili disposizioni con ripetizione (e non combinazioni) di n elementi di classe k. Nel caso specifico è n=2 in quanto gli elementi possibili sono solo 0 e 1, mentre k è dato dal numero di *.
    Per la cronaca il numero (chiamiamolo m) di disposizioni con ripetizione è dato da n^k.
    Vediamo alcuni casi:

    n=2 e k=1 ==> m=2^1=2 :
    1) 0
    2) 1

    n=2 e k=2 ==> m=2^2=4 :
    1) 0 0
    2) 0 1
    3) 1 0
    4) 1 1

    n=2 e k=3 ==> m=2^3=8 :
    1) 0 0 0
    2) 0 0 1
    3) 0 1 0
    4) 0 1 1
    5) 1 0 0
    6) 1 0 1
    7) 1 1 0
    8.) 1 1 1

    Per quanto riguarda il modo di ottenere le varie disposizioni con ripetizione, non noti nulla di particolare negli esempi che ho fatto?
    Ipotizza di avere una sequenza di k bit inizializzati a 0 e di sommare 1 a tale numero binario fin quando non ottieni una sequenza di k bit pari a 1.

    A questo punto possiamo rimuovere la semplificazione iniziale andando ad inserire le varie sottosequenze ottenute nel vettore di partenza.


    P.S.
    Non so se te ne sei accorto, ma poi ho risposto al tuo topic sulla ricorsione!
  • Re: Esercizio C difficilino (per me)

    Credo di aver capito quello che mi vuoi dire ma temo che nell'implementazione non sia in grado di farlo.
    Cioè, i valori che ottengo sono i numeri in binario da 0 a 2^k con k numero di asterischi. Il problema è: come faccio a implementare una cosa del genere?
    Perchè mi viene naturale pensare a dei cicli concatenati (esattamente k, una cosa del tipo for(i=0; i<=1; i++) k volte ), ma non sapendo a priori quanto vale k non credo sia una soluzione sensata. L'altra cosa che mi viene in mente è chiedermi se esista una qualche funzione (magari nella libreria math?) che mi restituisce il valore in binario di un numero. In quel caso sarebbe facile anche se mi sembrerebbe assurdo che ad un esame il prof pretenda che conosca a memoria funzioni di questo tipo.
    Forse posso costruire il valore in binario con delle divisioni e dei resti?
  • Re: Esercizio C difficilino (per me)

    Se costruisci un ciclo da 0 a 2^k-1 e l'indice del ciclo lo trasformi in binario avrai le cifre che ti servono al posto degli asterischi.
  • Re: Esercizio C difficilino (per me)

    Oppure in modo molto più banale, per ottenere la sequenza successiva a partire da quella corrente, basta scorrere la sequenza attuale partendo da destra fin quando non incontri uno 0, a quel punto lo 0 diventerà 1 e tutti i valori successivi (intendo quelli a destra) diventeranno 0.
  • Re: Esercizio C difficilino (per me)

    Alla fine ho applicato la soluzione suggeritami da Nippolo, non penso ci sarei mai arrivato. La posto per completezza:
    #define DIM 4
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    void stampa(char *);
    int main(){
    	int x;
    	char vet[DIM] = {'0','1','*','*'};  // 0100 0101 0110 0111 2^2 valori
    	stampa(vet);
    }
    
    void stampa(char v[]){
    	int cont=0,i,k,j;
    	int * v2=NULL;
    	for(i=0; i<DIM; i++ )
    		if(v[i]=='*')
    			cont++;
    	v2 = (int *)malloc(sizeof(int)*cont);
    	for(i=0; i<cont; i++)
    		v2[i]=0;					//inizializzo vettore v2 a 0
    	for(i=0,j=0; i<DIM; i++){		//stampo prima sequenza
    			if(v[i]!='*')
    				printf("%c",v[i]);
    			else{
    				printf("%d",v2[j]);
    				j++;
    			}
    		}
    	
    	
    	printf(" ");
    		
    	for(k=1; k<pow(2,cont); k++){
    		for(i=cont-1; i>=0; i--){			//mi sto perdendo lo 00
    			if(v2[i]==0){
    				v2[i]=1;
    				break;	
    			}	
    		}
    		if(v2[i]==1 && i<cont-1)			//torno a 0 i valori ad esso successivi (se non è l'ultimo)
    			for(i=i+1; i<=cont-1; i++)
    				v2[i]=0;
    		
    		for(i=0,j=0; i<DIM; i++){
    			if(v[i]!='*')
    				printf("%c",v[i]);
    			else{
    				printf("%d",v2[j]);
    				j++;
    			}
    		}
    			
    			
    		printf(" ");	
    	}
    }
    	
  • Re: Esercizio C difficilino (per me)

    Mi fa piacere esserti stato d'aiuto!

    Cmq ho provato a svolgerlo anche io, ecco il codice:
    #include <stdio.h>
    #include <stdlib.h>
    
    int sequenza_successiva(int *v, int dim)
    {
        for(int i = dim - 1; i >= 0; --i)
        {
            if(!v[i])
            {
                v[i] = 1;
                for(int j = i + 1; j < dim; ++j)
                {
                    v[j] = 0;
                }
                return 1;
            }
        }
        return 0;
    }
    
    int main()
    {
        char s[] = "*1**0*1";
        int n = 0;
        int k = 0;
        int i;
        int j;
        for(i = 0; s[i]; ++i)
        {
            if(s[i] == '*')
            {
                ++n;
            }
        }
        int *v = (int*)malloc(sizeof(int) * n);
        for(i = 0; i < n; ++i)
        {         
             v[i] = 0;
        }
        do
        {
            j = 0;
            printf("\n%d:\t", ++k);
            for(i = 0; s[i]; ++i)
            {
                if(s[i] == '*')
                {
                    printf("%d", v[j++]);
                }
                else
                {
                    printf("%c", s[i]);
                }
            }
        }
        while(sequenza_successiva(v, n));
    }
  • Re: Esercizio C difficilino (per me)

    Per curiosità che vuol dire la condizione s nel ciclo for?
  • Re: Esercizio C difficilino (per me)

    La condizione restituisce un valore booleano, quindi in questo caso si ha la semplice conversione di
    s[i]
    in bool. La regola per i char è che \0 (carattere terminatore di stringa) viene convertito in FALSE e tutti gli altri caratteri in TRUE.
    In pratica la condizione
    s[i]
    coincide con
    s[i] != '\0'
Devi accedere o registrarti per scrivere nel forum
8 risposte