Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
LDE (liste di estrazione) - liste_di_estrazione.c

liste_di_estrazione.c

Caricato da: AldoBaldo
Scarica il programma completo

  1. // Libreria LDE (Liste Di Estrazione)
  2. // di Aldo Carpanelli, v1.0.0 - 08/02/2020
  3.  
  4. #include "liste_di_estrazione.h"
  5.  
  6. static int LDE_gSRandInvocata = 0;
  7. static int LDE_gUltimoErrore  = LDEErr_NoErr;
  8. static const short LDE_InitOk = 0x6B6F; // 'ok'
  9.  
  10. static void LDE_InizializzaCaso( void ) {
  11.     char cifre[] = "0123456789ABCDEF";
  12.     int i;
  13.  
  14.     // mischia un po' le carte, per cominciare...
  15.     for( srand(time(NULL)), i=0; i<10; rand(), ++i );
  16.  
  17.     // crea un numero con 8 cifre casuali
  18.     char semeStr[12];
  19.     for( semeStr[8]='\0', i=0; i<8; ++i )
  20.         semeStr[i] = cifre[rand()%16];
  21.     srand( strtoul(semeStr,NULL,16) );
  22.  
  23.     LDE_gSRandInvocata = 1;
  24. }
  25.  
  26. static short LDE_Caso( short v ) {
  27.     return ((double)(v))*((double)rand())/((double)RAND_MAX);
  28. }
  29.  
  30. LDE LDE_Crea( short qVal ) {
  31.     LDE lde = NULL;
  32.  
  33.     // valida il parametro qVal
  34.     qVal = qVal>=0 ? qVal : -qVal; // qVal e' interpretato come valore assoluto
  35.     if( qVal<2 ) { LDE_gUltimoErrore=LDEErr_NoEl; return lde; }
  36.  
  37.     // alloca la struttura LDE
  38.     lde = calloc( 1, sizeof(*lde) );
  39.     if( NULL == lde ) { LDE_gUltimoErrore=LDEErr_NoMem; return lde; }
  40.  
  41.     // alloca il nuovo array in memoria dinamica
  42.     if( NULL == (lde->v=(short*)calloc(qVal,sizeof(*(lde->v)))) )
  43.         { LDE_gUltimoErrore=LDEErr_NoMem; return LDE_Distruggi( lde ); }
  44.  
  45.     lde->qv = qVal; // memorizza la quantita' dei valori
  46.     lde->ue = -1;   // non esiste un ultimo estratto valido
  47.     lde->ok = LDE_InitOk;
  48.     LDE_Reset(lde); // inizializza l'array e imposta lde->de
  49.  
  50.     if( !LDE_gSRandInvocata ) LDE_InizializzaCaso();
  51.  
  52.     return lde;
  53. }
  54.  
  55. int LDE_Dimensiona( LDE lde, short qVal ) {
  56.     short *vTmp = NULL;
  57.  
  58.     // valida il parametro qVal
  59.     qVal = qVal>=0 ? qVal : -qVal; // qVal e' interpretato come valore assoluto
  60.  
  61.     if( qVal<2 )
  62.         return LDE_gUltimoErrore=LDEErr_NoEl;
  63.  
  64.     if( !LDE_Valida(lde) ) return LDE_gUltimoErrore;
  65.  
  66.     if( qVal != lde->qv ) {
  67.         // alloca il nuovo array in memoria dinamica
  68.         if( NULL == (vTmp=(short*)calloc(qVal,sizeof(*vTmp))) )
  69.             return LDE_gUltimoErrore = LDEErr_NoMem;
  70.  
  71.         free( lde->v );
  72.         lde->v = vTmp;
  73.         lde->qv = qVal; // memorizza la quantita' dei valori
  74.     }
  75.  
  76.     return LDE_Reset(lde); // inizializza l'array e imposta lde->de
  77. }
  78.  
  79. LDE LDE_Duplica( const LDE originale ) {
  80.     LDE duplicato = NULL;
  81.  
  82.     if( !LDE_Valida(originale) ) return duplicato;
  83.  
  84.     duplicato = LDE_Crea( originale->qv );
  85.  
  86.     if( NULL != duplicato ) {
  87.         memcpy( duplicato->v, originale->v,
  88.                 originale->qv*sizeof(*originale->v) );
  89.  
  90.         duplicato->qv = originale->qv;
  91.         duplicato->ue = originale->ue;
  92.         duplicato->de = originale->de;
  93.     }
  94.  
  95.     return duplicato;
  96. }
  97.  
  98. int LDE_Copia( LDE destinazione, const LDE origine ) {
  99.     if( !LDE_Valida(destinazione) )
  100.         return LDE_gUltimoErrore;
  101.  
  102.     if( !LDE_Valida(origine) )
  103.         return LDE_gUltimoErrore;
  104.  
  105.     if( destinazione->qv != origine->qv ) {
  106.         LDE ldeTmp = LDE_Crea( origine->qv );
  107.  
  108.         if( ldeTmp ) {
  109.             free( destinazione->v );
  110.             destinazione->v = ldeTmp->v;
  111.             free( ldeTmp );
  112.         }
  113.     }
  114.  
  115.     memcpy( destinazione->v, origine->v, sizeof(*origine->v)*origine->qv );
  116.  
  117.     destinazione->qv = origine->qv;
  118.     destinazione->ue = origine->ue;
  119.     destinazione->de = origine->de;
  120.  
  121.     return LDE_gUltimoErrore;
  122. }
  123.  
  124. LDE LDE_Distruggi( LDE lde ) {
  125.     if( NULL != lde ) {
  126.         if( NULL != lde->v ) {
  127.             free( lde->v );
  128.             lde->v = NULL;
  129.         }
  130.  
  131.         free( lde );
  132.         lde = NULL;
  133.     }
  134.  
  135.     return lde;
  136. }
  137.  
  138. int LDE_Valida( const LDE lde ) {
  139.     if( NULL==lde )
  140.         { LDE_gUltimoErrore = LDEErr_PtrNULL; return 0; }
  141.  
  142.     if( NULL==lde->v )
  143.         { LDE_gUltimoErrore = LDEErr_NoArray; return 0; }
  144.  
  145.     if( LDE_InitOk!=lde->ok )
  146.         { LDE_gUltimoErrore = LDEErr_NoInit; return 0; }
  147.  
  148.     if( lde->qv < 2 )
  149.         { LDE_gUltimoErrore = LDEErr_NoEl; return 0; }
  150.  
  151.     if( lde->qv < lde->de )
  152.         { LDE_gUltimoErrore = LDEErr_NoEl; return 0; }
  153.  
  154.     LDE_gUltimoErrore = LDEErr_NoErr;
  155.     return 1;
  156. }
  157.  
  158. int LDE_Reset( LDE lde ) {
  159.     short *auxPtr, i;
  160.  
  161.     if( !LDE_Valida(lde) ) return LDE_gUltimoErrore;
  162.  
  163.     for( auxPtr=lde->v, lde->de=lde->qv, i=0; i<lde->qv; ++i ) *auxPtr++ = i;
  164.     // tutti i valori sono ora disponibili per un nuovo ciclo di estrazioni
  165.  
  166.     return LDE_gUltimoErrore;
  167. }
  168.  
  169. short LDE_Estrai( LDE lde ) {
  170.     short posizione, estratto = -1;
  171.     short *vAlias, *stop;
  172.  
  173.     if( !LDE_Valida(lde) ) return estratto;
  174.  
  175.     if( !lde->de ) LDE_Reset( lde ); // non ci sono piu' numeri da estrarre!
  176.  
  177.     do {
  178.         posizione = LDE_Caso(lde->de);  // una posizione a caso
  179.         estratto = *(lde->v+posizione); // cosa c'e' in quella posizione?
  180.     } while( estratto == lde->ue );     // evita d'estrarre 2 volte
  181.                                         // lo stesso valore
  182.  
  183.     stop = lde->v + lde->de-1;   // "stop" punta all'ultimo elemento
  184.     vAlias = lde->v + posizione; // "vAlias" punta all'elemento estratto
  185.  
  186.     // "compatta" l'array eliminandone il valore estratto
  187.     while( vAlias != stop ) { *vAlias = *(vAlias+1); ++vAlias; }
  188.  
  189.     lde->ue = estratto; // memorizza l'ultimo valore estratto
  190.     --lde->de;          // c'e' un elemento in meno tra quelli da estrarre
  191.  
  192.     return estratto; // restituisce il valore estratto
  193. }
  194.  
  195. int LDE_UltimoErrore( void ) {
  196.     return LDE_gUltimoErrore;
  197. }
  198.  
  199. const char *DescrizioneUltimoErrore( void ) {
  200.     return LDE_DescrizioneErrore( LDE_gUltimoErrore );
  201. }
  202.  
  203. const char *LDE_DescrizioneErrore( int codice ) {
  204.     static const char *kStrErr[] = {
  205.         "nessun errore",
  206.         "puntatore NULL",
  207.         "array mancante",
  208.         "struttura non inizializzata",
  209.         "quantita' di valori insufficiente",
  210.         "quantita' dei valori da estrarre maggiore della quantita' dei valori disponibili",
  211.         "allocazione di memoria non riuscita"
  212.     };
  213.  
  214.     if( codice>=LDEErr_NoErr && codice<LDE_MaxErr )
  215.         return kStrErr[codice];
  216.     else return "errore non previsto";
  217. }