Soyez le premier à donner votre avis sur cette source.
Vue 716 fois - Téléchargée 62 fois
#include <iostream> #include <iomanip> #include <fstream> #include <vector> #include <string> #include "gmp.h" #pragma comment(lib, "gmp.lib") int pgcd(int a, int b) { if(b == 0) return a; a %= b; return pgcd(b,a); } // Cette string est-elle valide pour un int ? bool valide(std::string str) { for(unsigned int i=0; i < str.size(); i++) if(str[i] < int('0') || str[i] > int('9')) return false; return true; } // Pour convertir une string en int int str2int(std::string str) { int n = 0; for(unsigned int i=0; i < str.size(); i++) { n = n*10 + (int(str[i]) - int('0')); } return n; } // Calcul et affichage de la i-ième fraction réduite void reduite(int i, std::vector<int> a, std::vector<int> b) { int maxi = b.size()-1; if(i < 0 || i > maxi) return; if(i == 0) {std::cout << b[0] << " : " << std::setprecision(17) << double(b[0]); return;} if(i == 1) { int n = b[0]*b[1]+a[1]; int p = pgcd(n, b[1]); std::cout << n/p << "/" << b[1]/p << " : " << std::setprecision(17) << double(n/p)/double(b[1]/p); return; } if(i == 2) { int d = b[1]*b[2]+a[2]; int n = b[0]*d+a[1]*b[2]; int p = pgcd(n, d); std::cout << n/p << "/" << d/p << " : " << std::setprecision(17) << double(n/p)/double(d/p); return; } mpq_t h2,h1,hn,k2,k1,kn; mpq_init(h2); mpq_init(h1); mpq_init(hn); mpq_init(k2); mpq_init(k1); mpq_init(kn); mpq_t t1, t2, p1, p2; mpq_init(t1); mpq_init(t2); mpq_init(p1); mpq_init(p2); // initialisations mpq_set_ui(h1, 1, 1); mpq_set_ui(hn, b[0], 1); mpq_set_ui(k1, 0, 1); mpq_set_ui(kn, 1, 1); int n = 1; while(n <= i) { // h2 = hn(n-2) et h1=hn(n-1) mpq_set(h2, h1); mpq_set(h1, hn); // k2 = kn(n-2) et k1=kn(n-1) mpq_set(k2, k1); mpq_set(k1, kn); // hn = b[n].h1+a[n].h2 mpq_set_ui(t1, b[n], 1); mpq_mul(p1, t1, h1); mpq_set_ui(t2, a[n], 1); mpq_mul(p2, t2, h2); mpq_add(hn, p1, p2); // kn = b[n].k1+a[n].k2 mpq_mul(p1, t1, k1); mpq_mul(p2, t2, k2); mpq_add(kn, p1, p2); n = n+1; } // La i-ème fraction réduite r = hn/kn // avec le dernier n utilisé = i mpq_t r; mpq_init(r); mpq_div(r, hn, kn); gmp_printf("%Qd", r); std::cout << " : " << std::setprecision(17) << mpq_get_d(r); } // Pour lire les deux premières lignes du fichier nommé : fichier bool lecture(std::string fichier, std::string &firstline, std::string &secndline) { std::string line; std::ifstream filein(fichier.c_str()); if(!std::getline(filein, firstline)) return false; if(!std::getline(filein, secndline)) return false; return true; } // On lit dans la 1-ère ligne : a[1], a[2], a[3], ..., a[n] // avec tous les a[i] positifs. // On lit dans la 2-ième ligne : b[0], b[1], b[2], b[3], ..., b[n] // avec : b[0] positif ou nul et pour i > 0 : b[i] positif // On calcule les fractions réduites successives de : // x = b0 + a1/(b1+a2/(b2+a3/(b3+a4/(b4+...)))) int main(int argc, char** argv) { if(argc < 2 ) { std::cout << "Il faut faire : fraction fichier.txt" << std::endl; return 0; } std::string firstligne, secndligne; if(lecture(argv[1], firstligne, secndligne)) { /* std::cout << "ligne 1 : " << firstligne << std::endl; std::cout << "ligne 2 : " << secndligne << std::endl; */ std::vector<int> a; a.push_back(0); /* ce a[0] est inutilisé */ std::size_t found = firstligne.find(" "); while (found != std::string::npos) { if(found != 0) { std::string firststr = firstligne.substr(0, found); if(!valide(firststr)) { std::cout << "ligne 1 invalide" << std::endl; return 0; } a.push_back(str2int(firststr)); } firstligne = firstligne.substr(found+1); found = firstligne.find(" "); } if(firstligne.size() != 0) { if(!valide(firstligne)) { std::cout << "ligne 1 invalide" << std::endl; return 0; } a.push_back(str2int(firstligne)); } for(unsigned int i = 1; i < a.size(); i++) if(!(a[i] > 0)) { std::cout << "Erreur pour a[" << i << "]" << std::endl; return 0; } std::vector<int> b; found = secndligne.find(" "); while (found != std::string::npos) { if(found != 0) { std::string secndstr = secndligne.substr(0, found); if(!valide(secndstr)) { std::cout << "ligne 2 invalide" << std::endl; return 0; } b.push_back(str2int(secndstr)); } secndligne = secndligne.substr(found+1); found = secndligne.find(" "); } if(secndligne.size() != 0) { if(!valide(secndligne)) { std::cout << "ligne 2 invalide" << std::endl; return 0; } b.push_back(str2int(secndligne)); } if(b[0] < 0) {std::cout << "Erreur pour b[0]" << std::endl; return 0;} for(unsigned int i = 1; i < b.size(); i++) if(!(b[i] > 0)) { std::cout << "Erreur pour b[" << i << "]" << std::endl; return 0; } if(a.size() < b.size()) {std::cout << "Nombre insuffisant de a[i] " << std::endl; return 0;} std::cout << "a[i] successifs : "; for(unsigned int i = 1; i < b.size(); i++) std::cout << " " << a[i]; std::cout << std::endl; std::cout << "b[i] successifs : "; for(unsigned int i = 0; i < b.size(); i++) std::cout << b[i] << " "; std::cout << std::endl; for(unsigned int i = 0; i < b.size(); i++) { std::cout << "r202duite " << i << " : "; reduite(i, a, b); std::cout << std::endl; } return 0; } else { std::cout << "Erreur de lecture du fichier" << std::endl; return 0; } }
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.