/** DEBUT BIGINT racine_carree(BIGINT); DEBUT **/ BIGINT racine_carree(BIGINT nb) { BIGINT resultat, tmp2, tmp, initial_guess; int i; initListe(&resultat); initListe(&initial_guess); initListe(&tmp); initListe(&tmp2); initial_guess = clone(nb); for(i = 0; i < (nb.nbEl / 2); i += 1) defilerListe(&initial_guess); i = 0; while(i < SQRT_HERON_THRESHOLD) { resultat = clone(initial_guess); tmp = divisionScolaire(nb, initial_guess); tmp2 = addition(tmp, initial_guess); viderListe(&tmp); viderListe(&initial_guess); initial_guess = divisionPar2(tmp2); if(comparer_nb(initial_guess, resultat) == EGAL) { i += 1; } viderListe(&resultat); viderListe(&tmp2); } return initial_guess; }
/** DEBUT BIGINT puissanceDC(BIGINT, INT UNSIGNED); DEBUT **/ BIGINT puissanceDC(BIGINT nb, int unsigned exp) { BIGINT resultat; BIGINT tmp, tmp2; initListe(&resultat); initListe(&tmp); initListe(&tmp2); if(exp == 0) { empilerListe(&resultat, 1); return resultat; } else if(exp == 1) { return nb; } resultat = puissanceDC(nb, exp / 2); if(exp % 2 == 0) { tmp = multiplication(resultat, resultat); return tmp; } else { tmp = multiplication(resultat, resultat); tmp2 = multiplication(tmp, nb); viderListe(&tmp); return tmp2; } }
/** DEBUT BIGINT factorielle(BIGINT, INT); DEBUT **/ BIGINT factorielle(unsigned int nb) { BIGINT tmp, tmp2, tmp3; BIGINT p = chaine2liste("1"); BIGINT r = chaine2liste("1"); int h = 0, shift = 0, high = 1; unsigned int y = nb; initListe(&tmp); initListe(&tmp2); initListe(&tmp3); if (nb < 2) return chaine2liste("1"); N = 1; int log2n = -1; /// Equivaut à log2(n) /// while (y) { y >>= 1; log2n++; } while (h != nb) { shift += h; h = nb >> log2n--; int len = high; high = (h - 1) | 1; len = (high - len) / 2; if (len > 0) { tmp = produit(len); tmp2 = multiplication(p, tmp); viderListe(&p); p = tmp2; viderListe(&tmp); tmp3 = multiplication(r, p); viderListe(&r); r = tmp3; } } viderListe(&p); tmp = left_shift(r, shift); viderListe(&r); return tmp; }
/** DEBUT BIGINT divisionScolaire(BIGINT, BIGINT); DEBUT **/ BIGINT divisionScolaire(BIGINT nb1, BIGINT nb2) { BIGINT resultat, ligne; BIGINT tmp; initListe(&resultat); initListe(&ligne); /// Variable pour vidage mémoire des calculs intermédiaires /// initListe(&tmp); /// Gestion du signe du résultat /// resultat.signe = nb1.signe * nb2.signe; nb1.signe = PLUS; nb2.signe = PLUS; if(comparer_nb(nb1, nb2) == INF) { empilerListe(&resultat, 0); return resultat; } else if(comparer_nb(nb1, nb2) == EGAL) { empilerListe(&resultat, 1); return resultat; } else if(nb2.debut->valeur == 0 && nb2.nbEl == 1) { /// Impossible de diviser par zero /// return; } while(!listeVide(nb1)) { insererFin(&ligne, 0); ligne.fin->valeur = nb1.debut->valeur; insererFin(&resultat, 0); nettoyerNb(&ligne); while(comparer_nb(ligne, nb2) >= EGAL) { resultat.fin->valeur += 1; tmp = soustraction(ligne, nb2); viderListe(&ligne); ligne = tmp; } nb1.debut = nb1.debut->suivant; } nettoyerNb(&resultat); return resultat; }
/** DEBUT BIGINT divisionPar2(BIGINT); DEBUT **/ BIGINT divisionPar2(BIGINT nb) { BIGINT resultat; BIGINT cinq; initListe(&resultat); initListe(&cinq); empilerListe(&cinq, 5); resultat = multiplication(nb, cinq); defilerListe(&resultat); return resultat; }
//---------EXERCICE 3---------- // Suppression des éléments pairs d'une liste et les insèrer dans une nouvelle // RESULAT: Pointeur sur la liste paire typeElt *enlevePair(typeElt **premier){ typeElt *precedent1, *courant1, *courant2, *premier2, *nouveau; int val; // Initialiser la liste 2 (nb paires) initListe(&premier2); courant1 = *premier; courant2 = NULL; precedent1 = NULL; while (courant1 != NULL) { val = valElt(courant1); if (val % 2 == 0) { courant1 = suivantElt(courant1); nouveau = creerElt(val); insereElt(&premier2, courant2, nouveau); detruireElt(premier, precedent1); courant2 = nouveau; }else{ // Faire avancer les 2 pointeurs precedent1 = courant1; courant1 = suivantElt(courant1); } } return premier2; }
void viderListe(BIGINT *ptrListe) { while(!listeVide(*ptrListe)) { depilerListe(ptrListe); } initListe(ptrListe); }
int main (void) { ProdListe ** listptr = (ProdListe**)malloc(sizeof(ProdListe*)); ProdInfo * curProd; int n, i; time_t timetmp; initListe(listptr); #ifndef TEST_FILE_GET // Zufallsgenerator initialisieren time(&timetmp); srand((unsigned int)timetmp); printf("\n\nWie viele Produkte sollen generiert werden?"); scanf("%i", &n); for (i = 1; i <= n; i++) { ProdInfo * product = einlesenProdukt(); char buf[12]; sprintf(buf, "Produkt %i", i); strcpy(product->name, buf); product->preis = ((double)(rand() % 99999 + 1) / 100.0); einfuegenListe(listptr, product); } #ifdef TEST_FILE_PUT listToFile(listptr); #endif #endif #ifdef TEST_FILE_GET fileToList(listptr); #endif while ((*listptr)->info) { ProdListe * previtem = *listptr; curProd = naechstesProdukt(listptr); ausgebenProdukt(curProd); } free(listptr); free(curProd); return 0; }
/** DEBUT BIGINT addition(BIGINT, BIGINT); DEBUT **/ BIGINT addition(BIGINT nb1, BIGINT nb2) { BIGINT resultat; int tmp; unsigned int retenue = 0; initListe(&resultat); /// Gestion du signe du résultat /// if(nb1.signe == MOINS && nb2.signe == PLUS) { nb1.signe = PLUS; resultat = soustraction(nb1, nb2); resultat.signe = MOINS; return resultat; } else if (nb1.signe == PLUS && nb2.signe == MOINS) { nb2.signe = PLUS; return resultat = soustraction(nb1, nb2); } else if(nb1.signe == MOINS && nb2.signe == MOINS) { resultat.signe = MOINS; nb1.signe = PLUS; nb2.signe = PLUS; } while(!listeVide(nb1) && !listeVide(nb2)) { tmp = nb1.fin->valeur + nb2.fin->valeur + retenue; retenue = tmp / 10; empilerListe(&resultat, tmp % 10); nb1.fin = nb1.fin->precedent; nb2.fin = nb2.fin->precedent; } /// Necessaire si nb1.nbEl > nb2.nbEl, il faut finir l'addition avec le reste des chiffres de nb1.nbEl /// /** J'ai séparé volontairement cette condition de la boucle principale, pour éviter une condition qui n'est pas nécessaire ** dans le cas ou nb1.nbEl = nb2.nbEl. Cela ajoute une répétition dans l'ecriture mais un léger gain en performance **/ while(!listeVide(nb1)) { tmp = nb1.fin->valeur + retenue; retenue = tmp / 10; empilerListe(&resultat, tmp % 10); nb1.fin = nb1.fin->precedent; } /// Necessaire si nb2.nbEl > nb1.nbEl, il faut finir l'addition avec le reste des chiffres de nb2.nbEl /// /** J'ai séparé volontairement cette condition de la boucle principale, pour éviter une condition qui n'est pas nécessaire ** dans le cas ou nb2.nbEl = nb1.nbEl. Cela ajoute une répétition dans l'ecriture mais un léger gain en performance **/ while(!listeVide(nb2)) { tmp = nb2.fin->valeur + retenue; retenue = tmp / 10; empilerListe(&resultat, tmp % 10); nb2.fin = nb2.fin->precedent; } /// Ajout de la retenue de fin, si elle existe. Exemple 99 + 10 = 1 retenue et 09 => 109 // if(retenue) empilerListe(&resultat, 1); nettoyerNb(&resultat); return resultat; }
/** DEBUT void left_shift(BIGINT, int); DEBUT **/ BIGINT right_shift(BIGINT nb, unsigned int shift) { BIGINT tmp, tmp2; int j; initListe(&tmp); initListe(&tmp2); if (shift <= 0) return nb; empilerListe(&tmp, 1); for (j=0;j<shift;++j) { tmp2 = multiplication(tmp, chaine2liste("2")); viderListe(&tmp); tmp = tmp2; } return divisionScolaire(nb, tmp); }
BIGINT clone(BIGINT nb) { BIGINT clone; initListe(&clone); while(!listeVide(nb)) { insererFin(&clone, nb.debut->valeur); nb.debut = nb.debut->suivant; } return clone; }
BIGINT produit(int n) { BIGINT tmp, tmp2, tmp3; initListe(&tmp); initListe(&tmp2); initListe(&tmp3); int m = n / 2; if (m == 0) { N += 2; return long2bigint(N); } if (n == 2) { return long2bigint(((N += 2) * (N += 2))); } tmp = produit(n - m); tmp2 = produit(m); tmp3 = multiplication(tmp, tmp2); viderListe(&tmp); viderListe(&tmp2); return tmp3; }
int main (void) { t_Listenkopf liste; GenTestdaten(); initListe(&liste); printf("Testtreiber beginnt mit leerer Liste:\n"); printListe(&liste); testTeil1(&liste); testTeil2(&liste); printf("Testtreiber erfolgreich beendet.\n"); return (0); }
/** DEBUT BIGINT multiplicationBasique(BIGINT, BIGINT); DEBUT **/ BIGINT multiplicationBasique(BIGINT nb1, BIGINT nb2) { BIGINT resultat, ligne, tmp; int j, signe_nb1, signe_nb2; signe_nb1 = nb1.signe; signe_nb2 = nb2.signe; nb1.signe = PLUS; nb2.signe = PLUS; initListe(&resultat); /// Variable pour vidage mémoire des calculs intermédiaires /// initListe(&tmp); /// Cas ou nb1 ou nb2 seraient égal à 0, on renvoie 0 directement /// if(egal_zero(nb1) || egal_zero(nb2)) { empilerListe(&resultat, 0); return resultat; } ligne = nb1; while(!listeVide(nb2)) { for(j = 1; j <= nb2.fin->valeur; j += 1) { tmp = addition(resultat, ligne); viderListe(&resultat); resultat = tmp; } nb2.fin = nb2.fin->precedent; insererFin(&ligne, 0); } /// Gestion du signe du résultat /// resultat.signe = signe_nb1 * signe_nb2; return resultat; }
BIGINT int2bigint(int nb) { BIGINT resultat; int n; initListe(&resultat); while(nb != 0) { n = nb % 10; if(n < 0) n = n * -1; empilerListe(&resultat,n ); nb /= 10; } return resultat; }
BIGINT long2bigint(long nb) { BIGINT resultat; int n; initListe(&resultat); if(nb < 0) resultat.signe = MOINS; else resultat.signe = PLUS; while(nb != 0) { n = nb % 10; if(n < 0) n = n * -1; empilerListe(&resultat, n); nb /= 10; } return resultat; }
/** DEBUT BIGINT puissanceDC(BIGINT, INT UNSIGNED); DEBUT **/ BIGINT puissanceBasique(BIGINT nb, int exp) { BIGINT resultat; int i; initListe(&resultat); resultat = clone(nb); if(exp == 0) { empilerListe(&resultat, 1); return resultat; } for(i = 1; i < exp; i++) { resultat = multiplication(resultat, nb); } return resultat; }
// Fusion de 2 listes en gardant l'ordre croissant // RESULTAT: pointeur sur la nouvelle liste typeElt *fusionListes (typeElt *liste1, typeElt *liste2){ typeElt *listeFusionee, *courant1, *courant2, *courant3, *nouveau; int val1, val2; //Initialier la nouvelle liste initListe(&listeFusionee); courant1 = liste1; courant2 = liste2; courant3 = NULL; while (courant1 != NULL && courant2 != NULL) { val1 = valElt(courant1); val2 = valElt(courant2); nouveau = creerElt(mini(val1, val2)); insereElt(&listeFusionee, courant3, nouveau); courant3 = nouveau; if (val1 < val2) { courant1 = suivantElt(courant1); }else{ courant2 = suivantElt(courant2); } } //Raccorder la fin de la dernière liste if (courant2 != NULL) { courant1 = courant2; } while (courant1 != NULL) { val1 = valElt(courant1); nouveau = creerElt(val1); insereElt(&listeFusionee, courant3, nouveau); courant3 = nouveau; courant1 = suivantElt(courant1); } return listeFusionee; }
BIGINT chaine2liste(char *nb) { int taille = strlen(nb); int indice; int fin; BIGINT l; initListe(&l); if(nb[0] == 45) { l.signe = MOINS; fin = 1; } else { l.signe = PLUS; fin = 0; } for(indice = taille - 1; indice >= fin; indice -= 1) { empilerListe(&l, (int)nb[indice] - 48); } return l; }
int main(int argc, char* args[]) { // Kommando-Variablen initialisieren bool ausgabeKonsole=false; int wortSchwelle=0; int anzInputDat=0; char inputDateien [30][MAX_FILENAME2]; char outputDatei [MAX_FILENAME2]; // Aufrufkommandos lesen und prüfen if (!kommandoValide (argc,args,&ausgabeKonsole,&wortSchwelle,inputDateien,&anzInputDat,outputDatei)) fMeld ("Aufrufparameter nicht valide. Aufruf: \n lt <options> <outputfile> <inputfile>\n",true); // Datei-Variablen intitialisieren FILE* fOut = fopen(outputDatei, "w") ; FILE* fIn = NULL; // Text-Elemente initialisieren Liste* indexList = initListe(copyWortIndex, printWortIndex,removeWortIndex) ; // Indexliste char zeile [MAX_ZEILE2]; // Pufferzeile char brocken [MAX_ZEILE2]; // Puffer für Brocken WortIndex* wiBuffer=malloc(sizeof(WortIndex)); // Puffer für WortIndex Struct wiBuffer->_wort=malloc(256*sizeof(char)); wiBuffer->_letzteDatei=malloc(sizeof(int)); wiBuffer->_letzteZeile=malloc(sizeof(int)); wiBuffer->_inxZeile=malloc(256*sizeof(char)); WortIndex* wiGefunden=NULL; // Puffer (Zeiger!) für Suche int cntDat=0; int cntZeile=0; int zPos=0; // Daten einlesen uns in Liste übertragen for (cntDat=0; (cntDat)<(anzInputDat);cntDat++) // Schleife für alle Input-Datein { fIn=fopen(inputDateien[cntDat], "r") ; cntZeile=0; while (zeileLesen (fIn,zeile)) // Schleife für jede Zeile in der Datei { zPos=0; cntZeile++; while (getBrocken (zeile, &zPos, brocken)) // Schleife für jeden Brocken in einer Zeile { if (strlen(brocken)>=wortSchwelle) { if (isWort (brocken)) { char* lineBuffer = NULL; strcpy(wiBuffer->_wort,brocken); wiGefunden=find(indexList, wiBuffer, eqWort); // Wort im Index suchen if (wiGefunden==NULL) // neues Wort im Index anlegen { // Puffer-Datensatz vom Typ Wortindex ("wiBuffer") befüllen.. *(wiBuffer->_letzteDatei)=cntDat; *(wiBuffer->_letzteZeile)=cntZeile; if (anzInputDat>1) { char* lineBuffer2 = appendDatei (brocken,inputDateien[cntDat],true); lineBuffer = appendZeile(lineBuffer2,cntZeile); free (lineBuffer2); } else lineBuffer = appendZeile(brocken,cntZeile); strcpy (wiBuffer->_inxZeile,lineBuffer); free (lineBuffer); //.. und in Index-Liste einfügen insertLex (indexList, wiBuffer,biggerWort); } else // bestehenden Eintrag im Index ergänzen { if (*(wiGefunden->_letzteDatei)==cntDat) { if (*(wiGefunden->_letzteZeile)!=cntZeile) { lineBuffer=appendZeile(wiGefunden->_inxZeile,cntZeile); free (wiGefunden->_inxZeile); wiGefunden->_inxZeile=lineBuffer; }; } else { char* lineBuffer2 = appendDatei (wiGefunden->_inxZeile,inputDateien[cntDat],false); lineBuffer=appendZeile(lineBuffer2,cntZeile); free (lineBuffer2); free (wiGefunden->_inxZeile); wiGefunden->_inxZeile=lineBuffer; } *(wiGefunden->_letzteDatei)=cntDat; *(wiGefunden->_letzteZeile)=cntZeile; }; }; }; initString (brocken); }; }; if (fclose(fIn)==EOF) fMeld ("Fehler beim Schließen einer Quelldatei",true); }; // Ausgabe der Liste als Datei und ggf. auf die Konsole Listenelement* readZeiger = NULL; char* bufferZeile=NULL; if (ausgabeKonsole) printf("\n*** Indexliste *** \n"); do { readZeiger=getNextNode (indexList,readZeiger); if (readZeiger !=NULL) { bufferZeile=readNode(readZeiger,readIndexLine); if (ausgabeKonsole) printf("\n%s",bufferZeile) ; if (!zeileSchreiben (fOut,bufferZeile)) fMeld ("Fehler beim Schreiben in Zieldatei.",true); }; } while (readZeiger!=NULL); if (ausgabeKonsole) printf("\n **************** \n") ; // Speicher freigeben removeList(indexList); free (wiBuffer->_wort); free (wiBuffer->_letzteDatei); free (wiBuffer->_letzteZeile); free (wiBuffer->_inxZeile); free (wiBuffer); if (fclose(fOut)==EOF) fMeld ("Fehler beim Schließen der Zieldatei.",true); return EXIT_SUCCESS ; // Dateien schließen und Speicher freigeben }
/** DEBUT BIGINT soustraction(BIGINT, BIGINT); DEBUT **/ BIGINT soustraction(BIGINT nb1, BIGINT nb2) { BIGINT resultat; int tmp; unsigned int retenue = 0; initListe(&resultat); //nettoyerNb(&nb1); //nettoyerNb(&nb2); if(egal_zero(nb2)) return clone(nb1); else if(egal_zero(nb1)) { nb2.signe = nb2.signe * -1; return clone(nb2); } /// Gestion du signe du résultat /// if(nb1.signe == MOINS && nb2.signe == PLUS) { nb1.signe = PLUS; resultat = addition(nb1, nb2); resultat.signe = MOINS; return resultat; } else if(nb1.signe == PLUS && nb2.signe == MOINS) { nb2.signe = PLUS; resultat.signe = PLUS; return resultat = addition(nb1, nb2); } else if(nb1.signe == MOINS && nb2.signe == MOINS) { BIGINT tmp = nb1; nb1 = nb2; nb2 = tmp; nb2.signe = PLUS; nb1.signe = PLUS; } if(comparer_nb(nb1, nb2) == INF) { BIGINT tmp = nb1; nb1 = nb2; nb2 = tmp; resultat.signe = MOINS; } /// Necessaire si nb2.nbEl > nb1.nbEl, il faut finir la soustraction avec le reste des chiffres de nb2.nbEl /// /** J'ai séparé volontairement cette condition de la boucle principale, pour éviter une condition qui n'est pas nécessaire ** dans le cas ou nb2.nbEl = nb1.nbEl. Cela ajoute une répétition dans l'ecriture mais un léger gain en performance **/ while(!listeVide(nb2)) { tmp = (nb1.fin->valeur - retenue - nb2.fin->valeur); if(nb1.fin->valeur > 0) retenue = 0; if(tmp < 0) { tmp = tmp + 10; retenue = 1; } empilerListe(&resultat, tmp % 10); nb1.fin = nb1.fin->precedent; nb2.fin = nb2.fin->precedent; } /// Necessaire si nb1.nbEl > nb2.nbEl, il faut finir la soustraction avec le reste des chiffres de nb1.nbEl /// /** J'ai séparé volontairement cette condition de la boucle principale, pour éviter une condition qui n'est pas nécessaire ** dans le cas ou nb1.nbEl = nb2.nbEl. Cela ajoute une répétition dans l'ecriture mais un léger gain en performance **/ while(!listeVide(nb1)) { tmp = nb1.fin->valeur - retenue; if(nb1.fin->valeur > 0) retenue = 0; if(tmp < 0) { tmp = tmp + 10; retenue = 1; } empilerListe(&resultat, tmp % 10); nb1.fin = nb1.fin->precedent; } nettoyerNb(&resultat); return resultat; }
/** DEBUT BIGINT multiplicationKaratsuba(BIGINT, BIGINT); DEBUT **/ BIGINT multiplicationKaratsuba(BIGINT nb1, BIGINT nb2) { BIGINT x0, x1, y0, y1, p0, p1, p2, resultat; BIGINT tmp, tmp2; int m, i, signe_nb1, signe_nb2; signe_nb1 = nb1.signe; signe_nb2 = nb2.signe; nb1.signe = PLUS; nb2.signe = PLUS; nb1.signe = PLUS; nb2.signe = PLUS; initListe(&resultat); /// Variables pour calculs intermédiaires /// initListe(&x0); initListe(&x1); initListe(&y0); initListe(&y1); initListe(&p0); initListe(&p1); initListe(&p2); /// Variables pour vidage mémoire des calculs intermédiaires /// initListe(&tmp); initListe(&tmp2); /// On enlève les 0 devant nb1 et nb2, car la taille du nombre est importante dans l'execution de l'algorithme de karatsuba /// nettoyerNb(&nb1); nettoyerNb(&nb2); /// m = milieu du plus grand nombre. Exemple : 9828839 => m = 4, 192893 => m = 3 /// m = (max_element(nb1, nb2) + 1) / 2; /// Creation de x0 et x1, dont nb1 = x1 * B^m + x0 /// if(nb1.nbEl <= m) { x0 = clone(nb1); empilerListe(&x1, 0); } else { for(i = 0; i < m; i += 1) { empilerListe(&x0, nb1.fin->valeur); nb1.fin = nb1.fin->precedent; } while(!listeVide(nb1)) { empilerListe(&x1, nb1.fin->valeur); nb1.fin = nb1.fin->precedent; } } /// Creation de y0 et y1, dont nb2 = y1 * B^m + y0 /// if(nb2.nbEl <= m) { y0 = clone(nb2); empilerListe(&y1, 0); } else { for(i = 0; i < m; i += 1) { empilerListe(&y0, nb2.fin->valeur); nb2.fin = nb2.fin->precedent; } while(!listeVide(nb2)) { empilerListe(&y1, nb2.fin->valeur); nb2.fin = nb2.fin->precedent; } } /// On enlève les 0 devant x0, x1, y0 et y1, car la taille du nombre est importante dans l'execution de l'algorithme de karatsuba /// nettoyerNb(&x0); nettoyerNb(&x1); nettoyerNb(&y0); nettoyerNb(&y1); /// Calculs d'après l'algorithme de karatsuba (voir description) /// p0 = multiplication(x0, y0); p2 = multiplication(x1, y1); tmp = addition(x0, x1); tmp2 = addition(y0, y1); p1 = multiplication(tmp, tmp2); viderListe(&tmp); viderListe(&tmp2); viderListe(&x0); viderListe(&x1); viderListe(&y0); viderListe(&y1); tmp = soustraction(p1, p2); p1 = soustraction(tmp, p0); viderListe(&tmp); puissancede10(&p1, m); puissancede10(&p2, (m * 2)); tmp = addition(p0, p2); resultat = addition(p1, tmp); viderListe(&tmp); /// Gestion du signe du résultat /// resultat.signe = signe_nb1 * signe_nb2; return resultat; }