Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 20

Discussione: [C] Fattori

  1. #1
    Utente bannato
    Registrato dal
    Jan 2003
    Messaggi
    1,414

    [C] Fattori

    Torno alla carica con la programmazione in C
    Un problema assai ricorrente all'interno dei miei programmini di prova è quello della fattorizzazione di un numero.

    La procedura mentale che uno esegue è

    Prendi numero
    Prova a dividerlo per 2
    |__ Se si può dividere, fallo e riprova a dividerlo per 2.
    Seno' prova a dividerlo per 3
    Se si puo' dividerlo fallo, senò prova a dividerlo per 5

    All'infinito...ma già così in pochi passaggi non riesco a tenere il conto, e verrebbe un source chilometrico

    All'atto pratico non mi viene in mente come realizzare il passaggio "se si puo' dividere" e soprattutto come scrivere un algoritmo efficace.


    Dimenticavo, il tutto senza utilizzare Strutture e puntatori, visto che non ci sono ancora arrivato

    Grassie

  2. #2
    Per controllare se un numero è divisibile per un'altro basta fare cosi'
    codice:
    int n=10;
    int div=2;
    
    if(n%div == 0) printf("%d è divisibile per %d",n,div);
     else printf("%d NON è divisibile per %d",n,div);
    Vediamo..sogni che diventano professione...passioni che diventano vita... Free as in Freedom...

  3. #3
    Utente bannato
    Registrato dal
    Sep 2003
    Messaggi
    1,012
    Hai fatto i cicli?

  4. #4
    Utente di HTML.it L'avatar di /dev/null
    Registrato dal
    May 2004
    Messaggi
    1,936
    Uhm... Potresti farlo con un ciclo...
    codice:
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    int main ( )
    {
    	srand ( (unsigned) time ( NULL ) );
    	int numero = rand ( ) % 10000;
    	int n_attuale = numero;
    	int i;
    	
    	for ( i = 2; n_attuale > 1; ) {
    		if ( ! ( n_attuale % i ) ) {
    			printf ( "%d (%d) e' divisibile per %d (resta %d).\n",
    				 numero, n_attuale, i, n_attuale/i );
    			n_attuale /= i;
    			continue;
    		}
    		i ++;
    	}
    	
    	return 0;
    }
    Ultima modifica ad opera dell'utente /dev/null il 01-01-0001 alle 00:00

  5. #5
    Utente di HTML.it L'avatar di netarrow
    Registrato dal
    Apr 2004
    Messaggi
    1,425
    Io ho fatto un programma in C++ che fattorizza 3 numeri interi e ne ricava mcm e MCD, ti posto il codice per farti vedere come ho risolto:

    codice:
    #include <iostream.h>
    #include <iomanip.h>
    
    int MCD(int, int, int);
    int mcm(int, int, int);
    
    int main() {
    	int a,b,c;
    	bool is;
    	int co = 0;
    
    cout << "Questo programma fattorizza tre numeri e ne ricava mcm e MCD\nInserisci tre numeri interi:\n";
    cin >> a;
    cin >> b;
    cin >> c;
    
    int numfirst[5000];
    for(int i = 2; i < 5000; i++) {
    	is = true;
    for(int j = 2; j < i/2; j++)
    if((i%j) == 0) is = false;
    
    		if(is) 
    			numfirst[co] = i;
    			co++;
    }
    
    int now, nowb, nowc;
    
    now = a;
    for(int n = 0; n <= co; ) {
    	if(now % numfirst[n] == 0) {
    		cout << endl << now << ":";
    		cout << numfirst[n] << "\r";
    		now /= numfirst[n];
    		n = 0;
    	}
    	else n++;
    }
    
    nowb = b;
    cout << endl;
    for(int o = 0; o <= co; ) {
    	if(nowb % numfirst[o] == 0) {
    		cout << endl << nowb << ":";
    		cout << numfirst[o] << "\r";
    		nowb /= numfirst[o];
    		o = 0;
    	}
    	else o++;
    }
    
    nowc = c;
    cout << endl;
    for(int p = 0; p <= co; ) {
    	if(nowc % numfirst[p] == 0) {
    		cout << endl << nowc << ":";
    		cout << numfirst[p] << "\r";
    		nowc /= numfirst[p];
    		p = 0;
    	}
    	else p++;
    }
    cout << endl;
    cout << "\nmcm(" << a << ", " << b << ", " << c << ")" << " = " << mcm(a, b, c) << endl;
    cout << "MCD(" << a << ", " << b << ", " << c << ")" << " = " << MCD(a, b, c) << endl << endl;
    
    cout << "Premi un tasto per uscire: ";
    char exit;
    cin >> exit;
    
    return 0;
    
    }
    
    int mcm(int a, int b, int c) {
    	for(int mcm = 2; ; mcm++) {
    		if(mcm % a == 0 && mcm % b == 0 && mcm % c == 0) break;
    	}
    	return mcm;
    }
    
    int MCD(int a, int b, int c) {
    	int max;
    	if(a > b && a > c) max = a;
    	else if(b > a && b > c) max = b;
    	else if(c > a && c > b) max = c;
    for(int MCD = max; ; MCD--) {
    		if(a % MCD == 0 && b % MCD == 0 && c % MCD == 0) break;
    	}
    	return MCD;
    }
    Imparare è un'esperienza, tutto il resto è solo informazione. (Albert Einstein)

  6. #6
    Utente bannato
    Registrato dal
    Jan 2003
    Messaggi
    1,414
    Grazie a tutti

    Prendo il source di Null come base perchè è in C semplice...da buon fagiano partono le domandone di chiarimento

    1) Ho sostituito l'assegnamento random di "numero"
    codice:
    srand ( (unsigned) time ( NULL ) );
    int numero = rand ( ) % 10000;
    Con un semplice valore per scanf
    codice:
    int numero;
    scanf ("%d", &numero);
    Ma i risultati (cambiando solo quello) lasciano perplessi...perchè!?
    codice:
    [maiosyet]@[alcibiade]-[~/Sorci/Fattori] ./Prova.bin
    Inserire numero da fattorizzare
    999
    999 (1206604416) e' divisibile per 2 (resta 603302208).
    999 (603302208) e' divisibile per 2 (resta 301651104).
    999 (301651104) e' divisibile per 2 (resta 150825552).
    999 (150825552) e' divisibile per 2 (resta 75412776).
    999 (75412776) e' divisibile per 2 (resta 37706388).
    999 (37706388) e' divisibile per 2 (resta 18853194).
    999 (18853194) e' divisibile per 2 (resta 9426597).
    999 (9426597) e' divisibile per 3 (resta 3142199).
    999 (3142199) e' divisibile per 41 (resta 76639).
    999 (76639) e' divisibile per 173 (resta 443).
    999 (443) e' divisibile per 443 (resta 1).
    [maiosyet]@[alcibiade]-[~/Sorci/Fattori]
    Fa tutto sto casino, ma conclude sempre con 443, qualsiasi numero io gli dia...

    Poi ci sono alcune parti di codice che non ho capito

    codice:
    if ( ! ( n_attuale % i ) ) {
    Questo pezzo dice: Se il resto di n_attuale / i è diverso da...? Da cosa?

    E poi
    codice:
    n_attuale /= i;
    continue;
    Questa istruzione è come dire
    codice:
    n_attuale = n_attuale / i
    ?

    Ultima cosa: al posto che un valore sentinella per uscire dal ciclo, hai messo continue...ma come funziona? :master:

    Grazie

  7. #7
    Utente di HTML.it L'avatar di /dev/null
    Registrato dal
    May 2004
    Messaggi
    1,936
    Originariamente inviato da maiosyet
    Grazie a tutti

    Prendo il source di Null come base perchè è in C semplice...da buon fagiano partono le domandone di chiarimento

    1) Ho sostituito l'assegnamento random di "numero"
    codice:
    srand ( (unsigned) time ( NULL ) );
    int numero = rand ( ) % 10000;
    Con un semplice valore per scanf
    codice:
    int numero;
    scanf ("%d", &numero);
    Ma i risultati (cambiando solo quello) lasciano perplessi...perchè!?
    codice:
    [maiosyet]@[alcibiade]-[~/Sorci/Fattori] ./Prova.bin
    Inserire numero da fattorizzare
    999
    999 (1206604416) e' divisibile per 2 (resta 603302208).
    999 (603302208) e' divisibile per 2 (resta 301651104).
    999 (301651104) e' divisibile per 2 (resta 150825552).
    999 (150825552) e' divisibile per 2 (resta 75412776).
    999 (75412776) e' divisibile per 2 (resta 37706388).
    999 (37706388) e' divisibile per 2 (resta 18853194).
    999 (18853194) e' divisibile per 2 (resta 9426597).
    999 (9426597) e' divisibile per 3 (resta 3142199).
    999 (3142199) e' divisibile per 41 (resta 76639).
    999 (76639) e' divisibile per 173 (resta 443).
    999 (443) e' divisibile per 443 (resta 1).
    [maiosyet]@[alcibiade]-[~/Sorci/Fattori]
    Fa tutto sto casino, ma conclude sempre con 443, qualsiasi numero io gli dia...
    Semplicemente perche'
    codice:
    n_attuale = numero;
    Viene dato prima che numero abbia il suo valore finale...

    Sostituisci cosi' il pezzo della dichiarazione delle vars:
    codice:
    	int numero;
    	int n_attuale;
    	int i;
    	
    	scanf ( "%d", &numero );
    	n_attuale = numero;
    E' solo questione d'esperienza: presto ti ci abituerai a queste stranezze del C











    Poi ci sono alcune parti di codice che non ho capito

    codice:
    if ( ! ( n_attuale % i ) ) {
    Questo pezzo dice: Se il resto di n_attuale / i è diverso da...? Da cosa?
    Quel pezzo dice: se i e' divisore di n_attuale...
    Per l'esattezza l'operatore modulo ( % ) da il resto della divisione tra i due operandi... Se il resto e' 0 ovviamente significa che il primo e' multiplo del secondo...

    Il punto esclamativo davanti e' il segno di negazione... Inverte la condizione: se e' vera la rende falsa, e se e' falsa la rende vera...
    Nel C (come in quasi tutti gli altri linguaggi, fa eccezione -che io sappia- solo la bash ) lo 0 significa falso, mentre un valore diverso da 0 significa vero...
    Se il resto della divisione tra n_attuale & i ( n_attuale % i ) e' 0 la condizione risulta quindi falsa... Ponendoci un ! davanti viene trasformata in vera, mentre in tutti gli altri casi viene trasformata in falsa e non viene eseguita...

    In pratica quella riga e' identica a questa:
    codice:
    if ( ( n_attuale % i ) == 0 ) {










    E poi
    codice:
    n_attuale /= i;
    continue;
    Questa istruzione è come dire
    codice:
    n_attuale = n_attuale / i
    ?
    Esatto
    Assegna a n_attuale il risultato della sua divisione con i...
    codice:
    ( a += b ) == ( a = a + b)
    ( a -= b ) == ( a = a - b)
    ( a *= b ) == ( a = a * b)
    ( a /= b ) == ( a = a / b)
    ( a %= b ) == ( a = a % b)
    Queste abbreviazioni (come anche usare il "!" invece che mettere "== 0") sono comode perche' abbreviano il tempo di scrittura del codice, e quando sai cosa scrivere sono splendidamente comode










    Ultima cosa: al posto che un valore sentinella per uscire dal ciclo, hai messo continue...ma come funziona? :master:

    Grazie
    Il continue fa tornare immediatamente a capo del ciclo, non lo fa terminare...
    Ho usato il continue perche' quando trovo un valore per i che lo rende divisore di n_attuale devo riciclare senza incrementare i, dato che lo stesso numero puo' essere piu' volte divisore...
    Se avessi tolto il continue ed avessi lasciato continuare l'esecuzione del ciclo i sarebbe stata incrementata e con alcuni numeri cio' puo' provocare problemi...
    Prova a levare quel continue e ad inserire come numero "4"...
    Invece che usare quel continue avrei potuto altrimenti metterci un "i--;"... Prova a sostituirlo e vedrai che non cambia nulla...


    Ultima modifica ad opera dell'utente /dev/null il 01-01-0001 alle 00:00

  8. #8
    Utente bannato
    Registrato dal
    Jan 2003
    Messaggi
    1,414
    Splendidamente chiaro

    Per il fatto della sostituzione, non è poi una stranezza pensandoci bene...trattandosi di una stupida macchina, se non gli metto le cose bene una in fila all'altra lui mica se le può cercare

    Il continue è una cosa che mi piace un sacco

    L'unica questione che mi lascia un po' perplesso sono le abbreviazioni, che sul momento non credo mi verrà mai in mente di usare...però chissà

    Grazie di tutto

  9. #9
    Utente di HTML.it L'avatar di /dev/null
    Registrato dal
    May 2004
    Messaggi
    1,936
    Originariamente inviato da maiosyet
    Splendidamente chiaro

    Per il fatto della sostituzione, non è poi una stranezza pensandoci bene...trattandosi di una stupida macchina, se non gli metto le cose bene una in fila all'altra lui mica se le può cercare
    Gia'... Anche se esegui tu il codice di quel programma esegui le istruzioni in fila e se prima copi il valore da $numero a $n_attuale e dopo modifichi $numero ovviamente non vai a toccare n_attuale
    Il continue è una cosa che mi piace un sacco
    Uhm... Io lo uso spesso ed e' molto comodo... Come anche il break;...
    Pero' a dire la verita' sarebbe meglio farne a meno poiche' toglie al codice una sequenza logica regolare...
    Tutte le funzioni di salto (goto [soprattutto], ma anche break e continue) infatti potrebbero rendere poco chiaro il flusso del programma...
    L'unica questione che mi lascia un po' perplesso sono le abbreviazioni, che sul momento non credo mi verrà mai in mente di usare...però chissà
    Bho, io ho iniziato ad usarle da quando scrivo in C, e le ho sempre trovate molto molto comode...
    Poi bhe'... Non cambia assolutamente niente l'usarle o meno...
    Grazie di tutto
    Figurati
    Ultima modifica ad opera dell'utente /dev/null il 01-01-0001 alle 00:00

  10. #10
    Utente bannato
    Registrato dal
    Jan 2003
    Messaggi
    1,414
    Folgorato dal momentaneo successo ho deciso di applicare subito il nuovo giochino, ad esempio impiegandolo come funzione in un altro programma per provare anche ciò che mi hai detto a proposito dei return

    Purtroppo c'è qualcosa che non va...

    codice:
    /* Calolo dei numeri perfetti da 1 a 1000 */ 
    
    #include <stdio.h>
    
    main() {
    
    int k;
    
         for ( k = 2; k < 1000; k++ )        {
    
              if ( FATTORIZZAZIONE(k) )            /* = true */
                         printf ("Yep\n");
              else 
                         printf ("Sux\n");
                                       }                
        return 0;
           }
         
    FATTORIZZAZIONE() {
            
     /* Funzione per la fattorizzazione di un numero con calcolo della somma dei fattori */
            
     int numero; 
     int i;
     int n_attuale;
     int totale = 0;        
      
     n_attuale = numero;
     
             for ( i = 2; n_attuale > 1;) {
                    if ( ! ( n_attuale % i ) ) {
                      
                        n_attuale /= i; 
                        totale += i;
                           continue;
                    }
                    i ++;
     }
           
     if ( ( totale+1 ) == numero )  {
           
                  printf ("%d e' perfetto!!!\n", numero);
                    
           return 1;  
                                                     }           
     else 
           return 0;
                      
    }
    Quando hai un attimo gli dai un'occhiata?

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.