TutorielsVous débutez ? C'est ici qu'on commence !
Mon compte
Recherche
Livre d'or
PublicitéVous devez être inscrit pour pouvoir poster des messages
| Page : Précédente 1 2 3 ... 9 10 11 12 13 14 15 ... 26 27 28 29 Suivante | |||||||||||||||||||||||||||||||||
| Auteur | Message | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2 visiteurs sur ce sujet (2 anonymes) | |||||||||||||||||||||||||||||||||
| Page : Précédente 1 2 3 ... 9 10 11 12 13 14 15 ... 26 27 28 29 Suivante | |||||||||||||||||||||||||||||||||
zero ptt
|
# Posté le 03/06/2008 à 13:10:45 | ||||||||||||||||||||||||||||||||
![]() Groupe : Bannis |
Reprise du dernier message de la page précédente :
Citation : zero pttadmettons que 'x' est le frag, la syntaxe special devient @x oubien xx ?
mon tout nouveau siteweb: Creations regroupe tous mes programmes de A à Z (piur me soutenir, un clic sur la pub suffit)attention, google arrive ![]() |
||||||||||||||||||||||||||||||||
freecircus
|
# Posté le 03/06/2008 à 13:31:01 | ||||||||||||||||||||||||||||||||
"Se coucher tard nuit"![]() Groupe : Membres |
@zero ptt >
Il y en a qui jouent un peu trop L'énoncé à été mis à jour : Citation : Nanoc Et on est face à un nouveau problème, comment gérer les cas ou le flag apparait quand même dans le texte à compresser. Dans ce cas particulier, on choisit la syntaxe spéciale "flag flag"
|
||||||||||||||||||||||||||||||||
Genius
|
# Posté le 03/06/2008 à 13:41:07 | ||||||||||||||||||||||||||||||||
Mais que se passe-t-on ?![]() Groupe : Membres |
Bon ben j'ai fait le programme sans flag
![]() Je peux quand même l'envoyer à Reponse_exercices ? Sachant qu'il compresse plus que le programme demandé ![]() 1 caractère => 1 caractère n caractères (n >= 2) => 2 caractères Un joueur d'échecs c'est comme de la peinture, s'il n'est pas brillant il est mat... In a world without walls and fences, who needs Windows and Gates ? (\_/) Copiez/collez lapin dans votre signature, (='.'=) et aidez le à concrétiser sa domination du monde ! (")_(") |
||||||||||||||||||||||||||||||||
Kurlze
|
# Posté le 03/06/2008 à 13:43:38 | ||||||||||||||||||||||||||||||||
L.O.S.T![]() Groupe : Membres |
Citation : Genius
Bon ben j'ai fait le programme sans flag ![]() Je peux quand même l'envoyer à Reponse_exercices ? Sachant qu'il compresse plus que le programme demandé ![]() 1 caractère => 1 caractère n caractères (n >= 2) => 2 caractères Comment tu peux arriver à compresser & décompresser correctement sans flag ?
You cannot change your fate. No man can. |
||||||||||||||||||||||||||||||||
Nanoc
|
# Posté le 03/06/2008 à 14:01:01 | ||||||||||||||||||||||||||||||||
Apprenez à utiliser la STL !!![]() Groupe : Membres |
Tu peux te l'envoyer si ça te fait plaisir, mais il ne servira pas de corrigé pour les zéros puisque il ne correspond pas à la donnée du problème.
Exercices de C++ pour tous les niveaux ! Mes tutos: Tri de Shell --- [C++] Manipulateurs de flux --- [C++] Notions avancées (suite du cours de M@teo21) |
||||||||||||||||||||||||||||||||
zero ptt
|
# Posté le 03/06/2008 à 15:14:05 | ||||||||||||||||||||||||||||||||
![]() Groupe : Bannis |
projet terminée!
on peut mettre le flag choisi dans le debut du fichier pour sa decompression plus tard? mon tout nouveau siteweb: Creations regroupe tous mes programmes de A à Z (piur me soutenir, un clic sur la pub suffit)attention, google arrive ![]() |
||||||||||||||||||||||||||||||||
poulecaca
|
# Posté le 03/06/2008 à 15:31:44 | ||||||||||||||||||||||||||||||||
![]() Groupe : Membres |
@zero ptt :Lis les messages précédents
|
||||||||||||||||||||||||||||||||
Zopieux
|
# Posté le 03/06/2008 à 18:10:28 | ||||||||||||||||||||||||||||||||
it… it can't be true!![]() ![]() |
Merci Nanoc pour l'interêt que tu portes à mon outil. Je viens de le modifier un tantinet afin de proposer davantage de caractères (94 en tout, les basiques, càd du code ASCII 33 à 127).
En passant, il est très laid niveau code, donc c'est pas un exploit ...
Édité
le 03/06/2008 à 18:24:59
par Zopieux
|
||||||||||||||||||||||||||||||||
Jaloyan1
|
# Posté le 03/06/2008 à 18:41:37 | ||||||||||||||||||||||||||||||||
Choisir = se priver du reste.![]() Groupe : Membres |
Déjà je vais vous proposer deux petit fichier a compresser pour le test.
Code : Autre
Voila normalement cela devrait suffir comme code d'exemple aussi essayer de compiler votre code source. Il doit gérer les majuscules, les \n, et les caractères spéciaux. Et faire une gestion d'erreur si vous n'avez pas prévu. évidemment je poste dans un but instructif c'est plus pour que vous me critiquiez et que vous me corrigiez pour que j'apprenne aussi que dans le but de frimer ou autre. J'expose mes idées pour que l'on sache ce qui ne va pas et donc que l'on me corrige. Si quelqu'un vous dit : "Je me tue à vous le répéter", laissez-le mourir. ![]() ![]() ![]() Chef du fan club de jaloyan1 |
||||||||||||||||||||||||||||||||
Buldozer[FR]
|
# Posté le 03/06/2008 à 20:01:46 | ||||||||||||||||||||||||||||||||
![]() Groupe : Membres |
|||||||||||||||||||||||||||||||||
Nanoc
|
# Posté le 03/06/2008 à 20:45:13 | ||||||||||||||||||||||||||||||||
Apprenez à utiliser la STL !!![]() Groupe : Membres |
J'ai déjà répondu 2 fois. On "compresse" la séquence "flag flag flag" en "flag flag flag flag flag flag".
Exercices de C++ pour tous les niveaux ! Mes tutos: Tri de Shell --- [C++] Manipulateurs de flux --- [C++] Notions avancées (suite du cours de M@teo21) |
||||||||||||||||||||||||||||||||
Buldozer[FR]
|
# Posté le 03/06/2008 à 20:54:49 | ||||||||||||||||||||||||||||||||
![]() Groupe : Membres |
|||||||||||||||||||||||||||||||||
Nanoc
|
# Posté le 03/06/2008 à 21:12:03 | ||||||||||||||||||||||||||||||||
Apprenez à utiliser la STL !!![]() Groupe : Membres |
Solution du mois de maiBonjour tout le monde ! Il est temps que je dévoile une solution pour l'exercice du mois de mai. Vous avez été 7 à m'envoyer une solution. C'est moins que le mois passé. Apparement, la question était trop difficile, ou disons que vous avez pensé que c'était trop difficile. Je vous fais donc part d'un mélange des solutions que j'ai reçu. Les prototypes de la classe et des fonctions membres sont de moi. Les corps des fonctions viennent pour la plus-part des réponses reçues. Beaucoup avait de bonne partie mais toutes avaient un problème quelque part. A noter que seul deux personnes ont utilisé les std::vector, ce qui simplifiait grandement le travail. La correction est assez longue. Je vous conseille de lire le début, d'essaxer par vous-même et de ragarder le corrigé si ça ne va pas. Analyse de la donnéeLa principale difficulté de cet exercice consistait à considérer un grand nombre comme un tableau de chiffres entre 0 et 9. Une fois ce pas franchi, il fallait ensuite essayer de minimiser nos efforts en programmant le moins de chose inutile. Pour cela, il fallait comprendre comment jouer avec les opérateurs pour en réaliser le plus possible avec le moins de code. Choix des structures de donnéesJ'ai choisi de représenter les nombres "dans l'ordre inverse". C'est-à-dire que le chiffre des unités sera dans la case 0 du tableau, le chiffre des dizaines dans la case 1 et ainsi de suite. Pour me simplifier la taĉhe, j'ai utilisé un std::vector<short int> comme tableau. C'est un choix arbitraire, on aurait très bien pu représenter les nombres dans l'ordre normal. Pour le signe, j'ai choisi un booléen, avec la convention qu'il sera vrai si le nombre est >=0. On a donc quelque chose comme: Code : C++
Je ne vais pas tout vous détailler, mais je vais présenter les points clés. ConstructeursPrenons le cas du contructeur prenant en argument un entier n de type int. La première chose à faire est de sauvegarder le signe de n. Puis le cas échéant, d'en prendre la valeur absolue pour ne travailler qu'avec les chiffres bruts. On peut alors découper le nombre en chiffres en utilisant l'opérateur modulo (%). Si vous ne savez pas ce que c'est, sachez qu'il correspond au reste d'une division entière. Code : C++
Le code traite en plus le cas spécial où n==0. A la fin, il supprime les zéros pour éviter les cas où n==000123 en les remplaçant par n=123. Le constructeur qui prend en argument une string est similaire. Constructeur de copie et operator=Comme notre classe ne possède aucun pointeur comme attribut et qu'elle n'alloue aucune mémoire, la version fournie par le compilateur de ces deux fonctions nous suffit. On a donc même pas besoin de les écrire. DestructeurComme nous n'avons alloué aucune mémoire, il n'y a rien à faire dans le destructeur. On a donc même pas besoin de l'écrire. Accès aux chiffresIl peut être intéressant d'avoir un accès aux chiffres qui composent le nombre. (En tout cas pendant la période de développement.) Le moyen le plus naturel est d'utiliser pour ceci l'opérateur []. Pour cet opérateur, on fournit toujours deux versions. Une permettant une modification du chiffre et l'autre non. Ce qui donne dans notre cas : Code : C++
Affichage en consoleLa première fonction à coder est certainement celle permettant d'afficher un BigInt en console. Cela nous permettra de faire des essais pour les autres fonctions dans la suite. Cette fonction doit toujours être déclarée en-dehors de la classe. Son prototype est toujours le même. Il s'agit de : Code : C++
Ce qui donne dans notre cas: Code : C++
A partir de là, on peut s'attaquer à la partie mathématique du problème. Opérateurs d'égalitéCommençons par les opérateurs d'égalité == et !=. Deux BigInt sont égaux si ils ont le même signe, si ils ont la même longueur et si tous leurs chiffres sont identiques. On a donc la définition suivante : Code : C++
L'opérateur != se code alors très facilement, puisqu'il suffit d'écrire : Code : C++
Opérateurs de comparaisonPour les opérateurs de comparaison, c'est la même chose. En en définissant un, on a les trois autres de manière. Prenons donc l'opérateur a<=b comme base. Un nombre A est plus petit ou égal à B si : 1) A est négatif et B positif 2) Sinon si A est moins long que B si ils ont le même signe 3) Sinon si le premier chiffre différent entre A et B est plus petit dans A que dans B. On peut donc écrire quelquechose comme : Code : C++
A partir de là, on a les 3 autres opérateurs : Code : C++
Les opérateurs << == != < > <= et >= ne sont pas des fonctions membres de la classe. Opposé d'un BigIntL'opposé d'un nombre est le même nombre auquel on a changé le signe. On utilise l'opérateur moins unaire pour cela. Ce qui donne : Code : C++
AdditionEntrons dans le vif du sujet. Pour code l'addition, commençons par coder l'opérateur +=. Code : C++
Pour cela, on peut distinguer 3 cas pour l'addition a + b 1) Les deux nombres ont le même signe. 2) Les nombres sont de signe opposé et abs(a) >= abs(b) 3) Les nombres sont de signe opposé et abs(a) < abs(b) Dans le premier cas, on doit additionner les parties chiffres des nombres comme on l'a appris au primaire. Dans le deuxième cas, on doit effectuer une sonstraction comme on l'a appri au primaire. Dans le troisième cas, on inverse a et b et on se retrouve dans le cas 2. On aura donc quelque chose comme : Code : C++
Les codes des fonctions membres addition() et soustraction() sont dans le code source final. Opérateurs qui dépendent de l'additionA partir de là, on peut définir toute une flopée d'opérateurs. Le moins binaire. Code : C++
L'incrémentation et la décrémentation Code : C++
ainsi que les opérateurs + et - externes. Code : C++
Le reste des opérateursEn vous inspirant de ce qui a été fait. Il est aisé de coder les opérateurs restants. Pour la division et le modulo, il peut être intéressant d'utiliser une fonction amie qui renvoie une structure de type: Code : C++
Afin d'éviter une duplication inutile du code. Le code completLe code étant assez long, je l'ai mis dans les balises secret. BigInt.h Secret (cliquez pour afficher) <code type="cpp"> #include <vector> #include <string> #include <ostream> struct Resultat; class BigInt { public: //CONSTRUCTEURS ---------------------------------------------------------------- BigInt(int n=0); BigInt(std::string chaine); // FONCTIONS MEMBRES SIMPLES --------------------------------------------------- unsigned int longueur() const; //La longueur du nombre bool getsigne() const; //Le signe sous forme de boolene BigInt abs() const; //Renvoit la valeur absolue //ACCES AUX CHIFFRES ----------------------------------------------------------- short int& operator[](unsigned int i); const short int& operator[](unsigned int i) const; short int& at(unsigned int i); const short int& at(unsigned int i) const; //OPPOSE ----------------------------------------------------------------------- BigInt operator-() const; //OPERATEURS ARITHMETIQUES ----------------------------------------------------- BigInt& operator+=(const BigInt&); BigInt& operator-=(const BigInt&); BigInt& operator*=(const BigInt&); BigInt& operator/=(const BigInt&); BigInt& operator^=(int n); BigInt& operator%=(const BigInt&); //OPERATEURS D'INCREMENTATION -------------------------------------------------- BigInt& operator++(); //Incrémente de 1 BigInt operator++(int); BigInt& operator--(); BigInt operator--(int); private: // FONCTIONS ASSISTANTES ------------------------------------------------------- void addition(const BigInt&); //Additione deux nombres de meme signe void soustraction(const BigInt&autre); //Effectue la soustraction *this - autre si |*this| > |autre| friend Resultat division(BigInt dividende, BigInt diviseur); //Effectue la division dividende/diviseur et renvoit //Une structure de type Resultat avec le quotient et le reste BigInt& multiplication_10n(int n); //Multiplie le BigInt par 10^n BigInt(std::vector<short int> v); //Constructeur a partir d'un vector<>. Cree un nombre positif std::vector<short int> getVecteur() const; //Renvoit le tableau m_chiffres void supprimer_zeros(); //Supprime les zeros en tete du nombre void zero(); //Met le BigInt a 0 //ATTRIBUTS -------------------------------------------------------------------- std::vector<short int> m_chiffres; //Les differents chiffres du nombre bool m_signe; //true si le BigInt >=0 }; //PETITE STRUCTURE POUR LES DIVISIONS ------------------------------------------ struct Resultat { BigInt quotient; BigInt reste; }; // OPERATEURS D'ECRITURE DANS LES FLUX ---------------------------------------- std::ostream& operator<<(std::ostream& flux, const BigInt& n); //OPERATEURS DE COMPARAISON----------------------------------------------------- bool operator==(const BigInt& a,const BigInt& b); bool operator!=(const BigInt& a,const BigInt& b); bool operator<=(const BigInt& a,const BigInt& b); bool operator>=(const BigInt& a,const BigInt& b); bool operator<(const BigInt& a,const BigInt& b); bool operator>(const BigInt& a,const BigInt& b); //OPERATEURS ARITHMETIQUES EXTERNES -------------------------------------------- BigInt operator+(const BigInt& a,const BigInt& b); BigInt operator-(const BigInt& a,const BigInt& b); BigInt operator*(const BigInt& a,const BigInt& b); BigInt operator/(const BigInt& a,const BigInt& b); BigInt operator^(const BigInt& a,int n); BigInt operator%(const BigInt& a,const BigInt& b); //FONCTIONS MATHEMATIQUES USUELLES --------------------------------------------- BigInt abs(const BigInt& n); //Valeur absolue BigInt signe(const BigInt n); //Fonction signe BigInt.cpp Secret (cliquez pour afficher) <code type="cpp"> #include "BigInt.h" #include <cstdlib> //Pour abs() #include <iostream> using namespace std; //CONSTRUCTEURS ---------------------------------------------------------------- BigInt::BigInt(int n) :m_chiffres(0),m_signe(true) { //On sauvegarde le signe m_signe = n>=0; n=std::abs(n); //Si c'est zero if (n==0) { zero(); return; } //Sinon, on stocke les chiffres dans le vector dans l'ordre inverse while (n>0) { m_chiffres.push_back(n%10); n/=10; } //Et on supprime les zeros en-tete du vector supprimer_zeros(); } BigInt::BigInt(string chaine) :m_chiffres(0),m_signe(true) { //Si il y a un moins devant, on met un signe - if (chaine[0]=='-') { m_signe=false; chaine.erase(0,1); } //On stocke ensuite les chiffres dans le vector for (int i(chaine.size()-1);i>=0;--i) m_chiffres.push_back(chaine[i]-'0'); //Et on supprime les zeros en-tete du vector supprimer_zeros(); } // FONCTIONS MEMBRES SIMPLES --------------------------------------------------- unsigned int BigInt::longueur() const { return m_chiffres.size(); } bool BigInt::getsigne() const { return m_signe; } BigInt BigInt::abs() const { //On cree une copie de l'objet avec un signe positif et on la renvoit BigInt retour(*this); retour.m_signe = true; return retour; } //ACCES AUX CHIFFRES ----------------------------------------------------------- short int& BigInt::operator[](unsigned int i) { //On renvoit la composante i du vector return m_chiffres[i]; } const short int& BigInt::operator[](unsigned int i) const { //idem return m_chiffres[i]; } short int& BigInt::at(unsigned int i) { //On renvoit la composante i du vector avec un test de validité return m_chiffres.at(i); } const short int& BigInt::at(unsigned int i) const { //idem return m_chiffres.at(i); } //OPPOSE ----------------------------------------------------------------------- BigInt BigInt::operator-() const { //On cree une copie de l'objet avec le signe oppose et on la renvoit BigInt retour(*this); retour.m_signe = !m_signe; return retour; } //OPERATEURS ARITHMETIQUES ----------------------------------------------------- BigInt& BigInt::operator+=(const BigInt& autre) { if (m_signe == autre.m_signe) addition(autre); //Addition de type primaire else if (abs() >= autre.abs()) soustraction(autre);//Soustraction de type primaire else operator=(autre+(*this)); //Inversion de a et b return *this; } BigInt& BigInt::operator-=(const BigInt& autre) { //Effectuer a-b revient a faire a+(-b) operator+=(-autre); return *this; } BigInt& BigInt::operator*=(const BigInt& autre) { BigInt backup(*this); zero(); for (unsigned int i(0);i<autre.longueur();++i) { BigInt temp(backup); int retenue(0); for (unsigned int j(0);j<temp.longueur();++j) { if (((temp[j] *= autre[i])+=retenue) >= 10) { retenue = temp[j]/10; temp[j]%=10; } else retenue =0; } if (retenue) temp.m_chiffres.push_back(retenue); temp.multiplication_10n(i); operator+=(temp); } m_signe = backup.m_signe == autre.m_signe; supprimer_zeros(); return *this; } BigInt& BigInt::operator/=(const BigInt& autre) { operator=(division(*this,autre).quotient); return *this; } BigInt& BigInt::operator%=(const BigInt& autre) { operator=(division(*this,autre).reste); return *this; } BigInt& BigInt::operator^=(int n) { if (n<0) zero(); else { BigInt a(*this); operator=(1); for (int i(0); i<n;++i) { operator*=(a); } } return *this; } //OPERATEURS D'INCREMENTATION -------------------------------------------------- BigInt& BigInt::operator++() { return operator+=(1); } BigInt BigInt::operator++(int) { BigInt ans = *this; operator+=(1); return ans; } BigInt& BigInt::operator--() { return operator-=(1); } BigInt BigInt::operator--(int) { BigInt ans = *this; operator-=(1); return ans; } // FONCTIONS ASSISTANTES ------------------------------------------------------- void BigInt::addition(const BigInt& autre) { unsigned int l(longueur() < autre.longueur() ? longueur() : autre.longueur()); int retenue(0); for (unsigned int i(0);i<l;++i) { if ((m_chiffres[i] += autre[i] + retenue) >=10) { m_chiffres[i] %=10; retenue =1; } else retenue =0; } if (longueur() > autre.longueur()) for (unsigned int i(l);i<longueur();++i) { if ((m_chiffres[i]+= retenue) >=10) { m_chiffres[i] %=10; retenue =1; } else { retenue =0; } } else if (autre.longueur() > longueur()) for (unsigned int i(l);i<autre.longueur();++i) { if ((autre[i] + retenue) >=10) { m_chiffres.push_back((retenue+autre[i])%10); retenue =1; } else { m_chiffres.push_back(autre[i]+retenue); retenue =0; } } if (retenue!=0) { m_chiffres.push_back(1); } } void BigInt::soustraction(const BigInt& autre) { int l(autre.longueur()); int retenue(0); for (int i(0);i<l;++i) { if ((m_chiffres[i]-= (autre[i]+retenue)) <0) { m_chiffres[i] = (m_chiffres[i] +10)%10; retenue = 1; } else retenue =0; } while (retenue!=0) { if ((m_chiffres[l]-=1) <0) { m_chiffres[l] = (m_chiffres[l] +10)%10; retenue =1; ++l; } else retenue =0; } supprimer_zeros(); } BigInt& BigInt::multiplication_10n(int n) { m_chiffres.insert(m_chiffres.begin(),n,0); return *this; } BigInt::BigInt(std::vector<short int> v) :m_chiffres(v), m_signe(true) { supprimer_zeros(); } std::vector<short int> BigInt::getVecteur() const { return m_chiffres; } void BigInt::supprimer_zeros() { int i(longueur()-1); while (i>=1 && m_chiffres[i] ==0) { m_chiffres.pop_back(); --i; } if (i==0 && m_chiffres[i]==0) zero(); } void BigInt::zero() { m_signe = true; m_chiffres.clear(); m_chiffres.push_back(0); } // OPERATEURS DE LECTURE ET ECRITURE DANS LES FLUX ----------------------------- ostream& operator<<(ostream& flux,const BigInt& n) { if (!n.getsigne()) flux << "-"; for (int i(n.longueur()-1);i>=0;--i) flux << n[i]; return flux; } //OPERATEURS DE COMPARAISON----------------------------------------------------- bool operator==(const BigInt& a,const BigInt& b) { if (a.getsigne() == b.getsigne()) //si a et b ont le meme signe { if (a.longueur() == b.longueur()) //qu'ils ont la meme longueur { for (unsigned int i(0);i<a.longueur();++i) //et qu'ils ont aucun chiffre different if (a[i] != b[i]) return false; //Si il y a un différent on renvoit false return true; //alors ils sont égaux } } return false; //sinon ils sont differents } bool operator!=(const BigInt& a, const BigInt& b) { return !operator==(a,b); } bool operator<=(const BigInt& a,const BigInt& b) { if (!a.getsigne() && b.getsigne()) //a negatif et b positif return true; else if (a.getsigne() && !b.getsigne()) //a positif et b negatif return false; else //a et b de meme signe { if (a.longueur() < b.longueur()) //si la longueur de a et plus petite que b return a.getsigne(); //ce sera vrai si a est positif et faux sinon else if (a.longueur() > b.longueur()) //si a est plus long que b return !a.getsigne(); //ce sera vrai si a est négatif else //si ils ont la meme longueur { for (int i(a.longueur()-1);i>=0;--i) //on cherche le premier chiffre de a plus grand que b if (a[i] > b[i]) //si il y en a un return !a.getsigne(); //le test est vrai si a est negatif et faux sinon else if (a[i] < b[i]) return a.getsigne(); } } return true; } bool operator>=(const BigInt& a,const BigInt& b) { return operator<=(b,a); } bool operator>(const BigInt& a,const BigInt& b) { return !operator<=(a,b); } bool operator<(const BigInt& a,const BigInt& b) { return !operator>=(a,b); } //OPERATEURS ARITHMETIQUES EXTERNES -------------------------------------------- BigInt operator+(const BigInt& a,const BigInt& b) { BigInt retour(a); return retour+=b; } BigInt operator-(const BigInt& a,const BigInt& b) { BigInt retour(a); return retour-=b; } BigInt operator*(const BigInt& a,const BigInt& b) { BigInt retour(a); return retour*=b; } BigInt operator/(const BigInt& a,const BigInt& b) { return division(a,b).quotient; } BigInt operator%(const BigInt& a,const BigInt& b) { return division(a,b).reste; } BigInt operator^(const BigInt& a,int n) { BigInt retour(a); return retour^=n; } Resultat division(BigInt dividende, BigInt diviseur) { Resultat r; //On traite le cas ou |diviseur| > |dividende| if (diviseur.abs() > dividende.abs()) { r.quotient.zero(); r.reste = dividende; r.reste.m_signe = dividende.m_signe; return r; } //On traite le cas de la division par zero if (diviseur.abs()==0) return r; //A partir d'ici, on est dans un cas normal //On cree une table de toutes les multiplications du diviseur vector<BigInt> tableau; for (int i(0);i<=10;++i) tableau.push_back(i*(diviseur.abs())); //On cree un tableau pour le quotient vector<short int> quotient; //On cree un tableau avec les premiers chiffres du dividende std::vector<short int> temp(diviseur.longueur()); for (unsigned int i(1);i<=temp.size();++i) temp[temp.size()-i] = dividende[dividende.longueur()-i]; //Le nombre de chiffres descendus unsigned int nbr_descendu(temp.size()); do { //Si le tableau n'est pas assez grand, on ajoute le chiffre suivant if (BigInt(temp)< diviseur.abs()) { temp.insert(temp.begin(),dividende[dividende.longueur()-nbr_descendu-1]); ++nbr_descendu; } //On cherche le multiple i du diviseur le plus grand que l'on peut mettre dans temp int i(0); while ((BigInt(temp) >= tableau[i])) { ++i; } if (i>0) --i; //On ajoute i au quotient quotient.insert(quotient.begin(),i); //Et on effectue la soustraction temp = (BigInt(temp)-= tableau[i]).getVecteur(); //On recommence tant qu'on a pas descendu tous les chiffres } while (nbr_descendu < dividende.longueur()); //On sauve le quotient et le reste r.quotient = quotient; r.reste = temp; //Et on gere les signes r.quotient.m_signe = dividende.m_signe == diviseur.m_signe; if (r.reste.abs() == 0) r.reste.zero(); else r.reste.m_signe = dividende.m_signe; return r; } //FONCTIONS MATHEMATIQUES USUELLES --------------------------------------------- BigInt abs(const BigInt& n) { return n.abs(); } BigInt signe(const BigInt n) { return n.getsigne() ? 1: -1; } N'hésitez pas à posez des questions si des points restent obscures. Remarques sur les codes reçusBravo à poulecaca et lanfeusst, qui malgrè le fait d'avoir utilisé des tableaux "à la C" ont presque entièrement réussi l'exercice.
Il ne sert à rien d'envoyer votre code si il ne fonctionne pas ou pire, si il ne compile pas. Merci à tous ceux qui ont participé. Et bonne chance avec l'exercice suivant ! EDIT : Modification de la réponse. Ajout de at() et amélioration du style.
Édité
le 11/06/2008 à 10:06:45
par Nanoc
Exercices de C++ pour tous les niveaux ! Mes tutos: Tri de Shell --- [C++] Manipulateurs de flux --- [C++] Notions avancées (suite du cours de M@teo21) |
||||||||||||||||||||||||||||||||
Cyprien_
|
# Posté le 04/06/2008 à 07:42:22 | ||||||||||||||||||||||||||||||||
Le Monde d'Akhiris![]() Groupe : Membres |
Merci beaucoup pour cette solution
.Par contre, serait-il possible d'avoir également la solution qui optimise les calculs, c'est-à-dire en base 2^(sizeof(unsigned int)*8) ? Celle-là m'intéresserait grandement, vu que je bloquais dès le départ .Bien sûr, si ça prend trop de temps de la coder ou si tu n'en as pas l'envie, pas de problème .
Un jeu online novateur ? Le Monde d'Akhiris ! |
||||||||||||||||||||||||||||||||
lmghs
|
# Posté le 04/06/2008 à 10:20:54 | ||||||||||||||||||||||||||||||||
|
Groupe : Membres |
Pour la comparaison, il y avait même moyen d'utiliser operator==(vector, vector). Et pour deux vecteurs de longueurs égales, on pouvait utiliser <, >, etc je pense.
Pour la version optimisant l'occupation mémoire, je m'y serai bien amusé, mais je n'en ai pas trop le temps malheureusement. ![]() Sinon, les algos sont identiques, c'est juste la formule pour détecter les dépassements qui change un chouilla -- j'avais donné un version bidouillée il y a quelques pages de cela. |
||||||||||||||||||||||||||||||||
MatteX
|
# Posté le 04/06/2008 à 18:22:16 | ||||||||||||||||||||||||||||||||
The cake is a lie!![]() Groupe : Membres |
Voici une ligne que vous devriez essayer de compresser et de décompressé parfaitement. Si vous y arriver c'est que votre algorithme est fonctionnel
(Remplacez le @ par votre flag) 1@29955555@@@@6665999999999999999999992@@1@3@@@0 Compressé ça me donne 1@@2995@58@@@3@659@99@99924@@@1@@36@@@0 81% de la taille originale. Et ça décompresse aisément. Je souhaite beaucoup de plaisir à ceux qui n'ont pas de flags ![]() Petit indice : @ devient @@, @@ devient 4@@@, @@@ devient 6@@@, @@@@ devient 8@@@, etc... donc on a une perte de compression de 1 @ mais à partir de 2 et plus c'est bon... Aucun doute possible. Je tient à rappeler que ce genre de compresssion ne sert absolument pas à traiter des fichiers de texte ordinaires. Il est rares que dans le langage écrit par des humains qu'il y ai plusieurs caractères de suite. Exception fait des expressif qui aime trop la pontuaction. Mais dans des fichier binaires ils se peut qu'il y ai vraiment beaucoup d'octets nul (0x00) ou DEL (0xFF) ou autre les uns à la suite des autres. C'est dans ces cas là que la compression devient utile. C'est un exercice, cela ne vous servira probablement jamais dans un cas réel. [EDIT]J'ai fait une modif et il n'y a plus de @@@@[/EDIT]
Édité
le 04/06/2008 à 18:44:38
par MatteX
liens utiles: FAQ C++ (developpez.com) | GotAPI.com | H-Deb Mon futur ex-blog | Logique : http://thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx Propriétaire d'un Dell Inspiron 1720, Core 2 Duo 2.4Ghz, 3Go DDR2, 8600M GT 256Mo. Avec Blu-Ray! |
||||||||||||||||||||||||||||||||
zero ptt
|
# Posté le 04/06/2008 à 18:27:32 | ||||||||||||||||||||||||||||||||
![]() Groupe : Bannis |
je crois que @@@ doit devenir @@ @@ @@ (sans espaces)
mon tout nouveau siteweb: Creations regroupe tous mes programmes de A à Z (piur me soutenir, un clic sur la pub suffit)attention, google arrive ![]() |
||||||||||||||||||||||||||||||||
Genius
|
# Posté le 04/06/2008 à 18:32:08 | ||||||||||||||||||||||||||||||||
Mais que se passe-t-on ?![]() Groupe : Membres |
Citation : MatteX
81% de la taille originale. Et ça décompresse aisément. Je souhaite beaucoup de plaisir à ceux qui n'ont pas de flags ![]() En effet, 58%, ça fait plaisir
Un joueur d'échecs c'est comme de la peinture, s'il n'est pas brillant il est mat... In a world without walls and fences, who needs Windows and Gates ? (\_/) Copiez/collez lapin dans votre signature, (='.'=) et aidez le à concrétiser sa domination du monde ! (")_(") |
||||||||||||||||||||||||||||||||
MatteX
|
# Posté le 04/06/2008 à 18:45:26 | ||||||||||||||||||||||||||||||||
The cake is a lie!![]() Groupe : Membres |
Et ça décompresse bien Genius?
liens utiles: FAQ C++ (developpez.com) | GotAPI.com | H-Deb Mon futur ex-blog | Logique : http://thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx Propriétaire d'un Dell Inspiron 1720, Core 2 Duo 2.4Ghz, 3Go DDR2, 8600M GT 256Mo. Avec Blu-Ray! |
||||||||||||||||||||||||||||||||
Genius
|
# Posté le 04/06/2008 à 18:49:08 | ||||||||||||||||||||||||||||||||
Mais que se passe-t-on ?![]() Groupe : Membres |
Ben oui, sinon ça compterait pas
Un joueur d'échecs c'est comme de la peinture, s'il n'est pas brillant il est mat... In a world without walls and fences, who needs Windows and Gates ? (\_/) Copiez/collez lapin dans votre signature, (='.'=) et aidez le à concrétiser sa domination du monde ! (")_(") |
||||||||||||||||||||||||||||||||
MatteX
|
# Posté le 04/06/2008 à 21:18:21 | ||||||||||||||||||||||||||||||||
The cake is a lie!![]() Groupe : Membres |
Qu'est-ce que tu fais pour savoir que 321 ça donne 311 ou 2221 ?
liens utiles: FAQ C++ (developpez.com) | GotAPI.com | H-Deb Mon futur ex-blog | Logique : http://thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx Propriétaire d'un Dell Inspiron 1720, Core 2 Duo 2.4Ghz, 3Go DDR2, 8600M GT 256Mo. Avec Blu-Ray! |
||||||||||||||||||||||||||||||||
Genius
|
# Posté le 04/06/2008 à 21:21:57 | ||||||||||||||||||||||||||||||||
Mais que se passe-t-on ?![]() Groupe : Membres |
Je t'envoie le code
Un joueur d'échecs c'est comme de la peinture, s'il n'est pas brillant il est mat... In a world without walls and fences, who needs Windows and Gates ? (\_/) Copiez/collez lapin dans votre signature, (='.'=) et aidez le à concrétiser sa domination du monde ! (")_(") |
||||||||||||||||||||||||||||||||
ocin
|
# Posté le 04/06/2008 à 21:58:59 | ||||||||||||||||||||||||||||||||
si seulement 1+1=1![]() Groupe : Membres |
moi je pense que le flag qui serai pas mal c'est le §
il est plus que rarement utilisé. |
||||||||||||||||||||||||||||||||
TiPouss
|
# Posté le 04/06/2008 à 22:15:00 | ||||||||||||||||||||||||||||||||
|
Apprendre Toujours Plus... Groupe : Membres |
Citation
3@ -> 3@0 -> 000 En effet. C'est pour cela, qu'on utilise un flag qui n'apparait jamais dans le texte. Il n'y a pas de solution à ce problème si on utilise un flag. Il y aura toujours une séquence de caractère qui coince. Une solution est souvent de remplace la séquence "flag" par "flagflag", ce qui ne résoud pas entièrement le problème. Ne pas utiliser de flags pose lui un autre problème, celui que j'ai soulevé dans la première partie. Comment savoir si "33" est 3 suivi de 3 ou 3 fois 3 ? Si on utilise un flag de plus de 1 caractère, le problème reste le même et en plus, ça diminue gravement le taux de compression. Bonjour à tous J'ai réfléchi au problème du flag pour ma partie Analyse. Je ne me suis pas encore posé sur la programmation en elle-même (il me faut lire le tutoriel en même temps pour m'apprendre). Comme on a dit qu'il fallait choisir pour flag un caractère "rare",si on prend comme le proposait nanoc le caractère "@" et que comme le donne l'énoncé,on ne compresse pas une suite de moins de 3 éléments successifs,pourquoi ne pas coder "exceptionnellement" le flag qui se trouverai dans la séquence à compresser en : xxx@@ pour une répétition de x "@" dans la séquence Ainsi,la séquence @@@ se transformerai en 333@@ et non en @@@@@@ De plus,en voyant dans la compression un @@,on aura qu'à regarder ce qui précède et en voyant 333,on saura qu'il s'agit de @@@. Si la compression donne 999@@,on comprendra @@@@@@@@@. Biensur,cela rallonge la séquence contenant le flag dans le cas où la succession du flag est inférieure à 5,mais comme on choisit pour flag un caractère rare,ce soucis sera limité... Par ailleurs,si la série de flag est dupliquée à plus de 10 exemplaire,on pourra toujours la divisé en 2 morceaux comme donné dans l'énoncé. Ex: @@@@@@@@@@@@@@@ = 999@@666@@ Test sur l'exemple de MatteX : 1@29955555@@@@6665999999999999999999992@@1@3@@@0 (48 caractères) deviendrai : 1111@@2995@5444@@3@659@99@92@9222@@1111@@3333@@0 (48 caractères) => Bon,là le flag est très présent dans la séquence à compresser,mais en prenant un autre flag,où même en prenant 9 comme flag,on serait déjà sur une compression favorable ![]() flag "9" : 119@22229959549@39659999999999222992@@1@339@0 (45 caractères) Je vais réfléchir à ce que je viens de dire et essayer de voir si je trouve une faille dans cette hypothèse ![]() Si vous en voyez une,n'hésitez pas !
Édité
le 04/06/2008 à 22:31:25
par TiPouss
Seul est perdu le combat que l'on abandonne... Persévérance et Volonté,deux mots source de Réussite... |
||||||||||||||||||||||||||||||||
Isra17
|
# Posté le 05/06/2008 à 04:06:46 | ||||||||||||||||||||||||||||||||
ouin![]() Groupe : Membres |
Matex, ta méthode de (dé)compression n'est pas valide
Hero War c'est pour bientôt? Ouais!! |
||||||||||||||||||||||||||||||||
Nanoc
|
# Posté le 05/06/2008 à 08:50:20 | ||||||||||||||||||||||||||||||||
Apprenez à utiliser la STL !!![]() Groupe : Membres |
A nouveau, je le répète, ce moyen de compression n'est qu'un exemple simple. Le but n'est pas la performance, mais plutôt la manière de coder, de présenter le code, d'utiliser les outils du C++.
Je pensais que donner un contexte au sujet du mois serait une bonne idée pour stimuler. Apparement, c'est plutôt le contraire, ça stimule la contestation et le débat. Ce n'est en soit pas un défaut, mais ça finit par embrouiller les gens qui cherchent juste à répondre à la donnée. Envoyer un programme qui ne correspond pas à la donnée ne sert à rien, puisqu'il ne pourra servir de correction.
Édité
le 05/06/2008 à 09:57:49
par Nanoc
Exercices de C++ pour tous les niveaux ! Mes tutos: Tri de Shell --- [C++] Manipulateurs de flux --- [C++] Notions avancées (suite du cours de M@teo21) |
||||||||||||||||||||||||||||||||
youyou
|
# Posté le 05/06/2008 à 18:24:47 | ||||||||||||||||||||||||||||||||
1337 un jour 1337 toujours![]() Groupe : Membres |
Pour la correction, pourqoi ne fait tu aucun controle d'acces?
il vaut mieux utiliser at() au lieu de [] |
||||||||||||||||||||||||||||||||
Nanoc
|
# Posté le 05/06/2008 à 18:35:05 | ||||||||||||||||||||||||||||||||
Apprenez à utiliser la STL !!![]() Groupe : Membres |
Pour ce qui est du code dans les fonctions membres, je le fais pas parce que je sais que mon algorithme est correcte et que je ne dépasserai pas. C'est donc un test superflu et donc une perte de temps. Bien que l'optimisation ne soit pas le but ici.
Si on sait qu'on ne va pas dépasser, alors autant utiliser [] qui est plus rapide. Pour ce qui est du code de l'opérateur [], j'ai décidé de ne pas faire de test pour fournir une fonction qui joue le même rôle que [] sur un vector. J'aurais également pu fournir une fonction at() qui, elle, aurait fait le contrôle d'accès. Exercices de C++ pour tous les niveaux ! Mes tutos: Tri de Shell --- [C++] Manipulateurs de flux --- [C++] Notions avancées (suite du cours de M@teo21) |
||||||||||||||||||||||||||||||||
NioS
|
# Posté le 08/06/2008 à 15:14:34 | ||||||||||||||||||||||||||||||||
![]() Groupe : Membres |
Bonjour et merci Nanoc pour ces exercices.
Je suis tombé il y a quelques jours sur ce topic, et j'ai déjà fait les exercices des mois précédents (avec succès ).J'ai une question pour l'exercice du mois de juin, par rapport aux exceptions. Quand tu dis : Citation : Nanoc utiliser les exceptions pour gérer le cas des fichiers qui sont mal formatés (qui contiennent des erreurs) Veux-tu dire qu'ils faut les utiliser au moment de la décompression, pour détecter si le fichier a été compressé avant ? Doit-on générer une exception lorsqu'on essaye de décompresser un fichier "normal", c'est-à-dire qui n'a pas le format de compression ? J'espère avoir été assez clair
Internet Explorer porte bien les 4 dernières lettres de son nom... Pourquoi payer plus cher pour avoir pire ?! (allitération en p et r) ![]() |
||||||||||||||||||||||||||||||||
Hiura
|
# Posté le 08/06/2008 à 16:27:37 | ||||||||||||||||||||||||||||||||
![]() Groupe : Membres |
Tu peux utiliser les exceptions quand tu rencontres une erreur que tu ne peux pas corriger. Je ne donne pas de réponse trop précise pour ne pas donner de réponse.
|
||||||||||||||||||||||||||||||||
Nanoc
|
# Posté le 08/06/2008 à 17:22:28 | ||||||||||||||||||||||||||||||||
Apprenez à utiliser la STL !!![]() Groupe : Membres |
J'ai mis cette proposition de manière générale. On ne peut pas prévoir à priori les erreurs que pourrait contenir le fichier à compresser ou à décompresser.
L'idée est d'utiliser une exception pour gérer les cas "non-standards". Exercices de C++ pour tous les niveaux ! Mes tutos: Tri de Shell --- [C++] Manipulateurs de flux --- [C++] Notions avancées (suite du cours de M@teo21) |
||||||||||||||||||||||||||||||||
Retour au forum "Langage C++" ou à la liste des forums
Vous devez être inscrit pour pouvoir poster des messages
