// PROGRAMME DE CALCUL DE NOMBRES PREMIERS
// (c) YANNVAG 2008
// http://nombrespremiersliste.free.fr/
// ATTENTION !
// Le code n'est pas très propre, ça peut être pour vous un grand fouillis
// Je n'ai pas non plus créé de fonctions pour calculer les nombres premiers pour une raison de rapidité
// En effet le programme mettra moins de temps à les calculer si les instructions de calcul sont intégrées directement, sans passer par de fonctions
// Donc si je n'ai pas fait un programme standard POO ou je ne sais trop quoi, c'est bien volontairement
// ===========
#include <iostream>
#include <vector>
#include <fstream>
#include <cmath>
#include <sstream>
using namespace std;
template<typename T>
bool from_string( const string & Str, T & Dest )
{
// créer un flux à partir de la chaîne donnée
istringstream iss( Str );
// tenter la conversion vers Dest
return iss >> Dest != 0;
}
int main(int argc, char *argv[])
{
vector<unsigned long> nombrespremiers;
// Le tableau (vecteur) contenant tous les nombres premiers
unsigned long nombreencours = 5;
// Le dernier nombre premier trouvé
unsigned long minlimit=0;
// Limite minimum (servira par la suite)
bool newfile = true;
// Créer un nouveau fichier ? (servira par la suite)
cout << "Bienvenue dans le programme de generation de nombres premiers" <<endl;
cout << "(c) Yannvag 2007" <<endl <<endl;
cout << "Vous pourrez arreter le programme a touts moments, il suffit de faire CTRL+C" <<endl <<endl;
cout << "Demarrage du systeme de fichier..." <<endl;
char response_loadfic;
cout << "Voulez-vous reprendre une ancienne sauvegarde ? (o ou n) : ";
cin >> response_loadfic;
string nomfic;
_Ios_Openmode ios_config; // Le mode d'ouverture du fichier
if(response_loadfic == 'o') // Si la personne veux reprendre depuis un ancien fichier...
{
newfile = false; // On ne créera pas un nouveau fichier pour la sauvegarde
cout << "Entrez le nom du fichier a charger : ";
cin >> nomfic;
ifstream lfichier(nomfic.c_str());
if(!lfichier || lfichier == NULL) // Si le fichier n'a pas pu être ouvert...
{
cout << "Le programme n'a pas reussit a charger le fichier...\nFin du programme" <<endl;
cin.ignore();
cin.ignore();
return 0; // On arrete tout
}
cout << "Fichier ok en ouverture\nChargement du fichier... (cette operation peut prendre du temps)" <<endl;
// On met en memoire les nombres premiers inscrits dans le fichier de sauvegrade
string linebuffer;
unsigned long linebufferlong;
while(getline(lfichier,linebuffer))
{
from_string(linebuffer,linebufferlong);
if(linebufferlong != 0)
{
nombrespremiers.push_back(linebufferlong);
//cout << "\rLigne " << ++minlimit;
}
}
// ==============================================================================
cout << "\nFichier en memoire : operation reussie !" <<endl;
nombreencours = nombrespremiers[nombrespremiers.size()-1]+1;
if(nombreencours%2 == 0)
nombreencours++;
ios_config = ios_base::app; // Mode : continuer le fichier
}
else // Si la personne ne veux pas utiliser une ancienne sauvergarde
{
nombrespremiers.push_back(2);
nombrespremiers.push_back(3);
cout << "Entrez le nom du fichier d'ecriture (ou vont etre inscrit les nombres premiers) : "; // On lui demande quel fichier il faut utiliser
cin >> nomfic;
ios_config = ios::out; // Mode : écraser le fichier
}
ofstream fichier(nomfic.c_str(), ios_config); // On ouvre le fichier de sauvegarde
if(!fichier || fichier == NULL) // Si le fichier ne peut être créé, alors on arrete tout
{
cout << "Fichier erronne, reessayez" <<endl;
cin.ignore();
cin.ignore();
return 0;
}
if(newfile) fichier << "2\n3\n"; // Si on a commencé un nouveau fichier, alors on y ajoute les 2 premiers nombres premiers (vous me suivez ? ;) )
cout << "\nLe fichier a ete ouvert correctement\nSysteme de fichier operationnel, tout est ok" <<endl <<endl;
cout << "Entrez la limite (min : " << nombrespremiers[nombrespremiers.size()-1]+1 << ") : 0 pour aucune limite : "; // On demande la limite
unsigned long limit;
cin >> limit;
if(limit<1) limit = 0;
if(limit==0) // Si la limite est nul, ça veut tout simplement dire qu'il n'y en a pas : vers l'infini et au delà !
{
cout << "Rappel : CTRL+C pour arreter" <<endl << "Calcul en cours des nombres premiers..." <<endl;
while(1)
{
bool estnombrepremier = true;
unsigned long vectorsize = nombrespremiers.size();
unsigned long i=0;
while(i*i<vectorsize) // On calcul...
{
if(nombreencours%nombrespremiers[i] == 0) // Si le nombre en cours de test est divisible par un des autres nombres premiers, alors c'est qu'il n'est pas premier
{
estnombrepremier = false;
break; // On arrête le while
}
i++; // Sinon, on continu
}
if(estnombrepremier) // Si il est premier
{
nombrespremiers.push_back(nombreencours); // On l'inscrit dans la mémoire
fichier << nombreencours << endl; // Et on l'enregistre
cout << "\rDernier nombre premier trouve : " << nombreencours << " - Testes : " << vectorsize; // Et on le dit !
}
nombreencours+=2; // Pas la penne de tester les nombres pairs...
}
}
else // Mais si il y a une limite...
{
while(limit < nombrespremiers[nombrespremiers.size()-1]+1)
{ // On regarde d'abord si elle n'est pas inférieure aux nombre de nombres premiers déjà trouvés
cout << "La limite est trop petite, entrez-en une autre plus grande ou egale a " << nombrespremiers[nombrespremiers.size()-1]+1 << " : ";
cin >> limit;
}
// Dans cette partie, on va demander le type d'interface voulue
int avancement;
cout << "Que voulez-vous ?\n1 : Affichage normal (vitesse normale, on peut se situer par rapport a l'avancement, pas d'economie du processeur)\n\n2 : Sans aucun affichage (rapide, economie du processeur, mais pas pratique) " << endl << "Votre choix : ";
cin >> avancement;
if(avancement < 2)
avancement = 1;
else
avancement = 0;
// ============================================================
if(avancement == 1) // Si on a choisi le mode normal, c'est comme avant...
{
cout << "\nRappel : CTRL+C pour arreter" <<endl;
while(nombreencours<=limit)
{
bool estnombrepremier = true;
unsigned long vectorsize = nombrespremiers.size();
unsigned long i=0;
while(i*i<vectorsize)
{
if(nombreencours%nombrespremiers[i] == 0)
{
estnombrepremier = false;
break;
}
i++;
}
if(estnombrepremier)
{
nombrespremiers.push_back(nombreencours);
fichier << nombreencours << endl;
cout << "\rDernier nombre premier trouve : " << nombreencours << "/" << limit << " - Testes : " << vectorsize;
}
nombreencours+=2;
}
}
else // Sinon, on fait comme avant, mais on n'affiche rien
{
cout << "\nRappel : CTRL+C pour arreter" <<endl << "Calcul en cours des nombres premiers..." <<endl;
while(nombreencours<=limit)
{
bool estnombrepremier = true;
unsigned long vectorsize = nombrespremiers.size();
unsigned long i=0;
while(i*i<vectorsize)
{
if(nombreencours%nombrespremiers[i] == 0)
{
estnombrepremier = false;
break;
}
i++;
}
if(estnombrepremier)
{
nombrespremiers.push_back(nombreencours);
fichier << nombreencours << endl;
}
nombreencours+=2;
}
}
}
// Voilà, c'est terminé !!!
// OUF !
cout << "\nTermine !!!\nLe dernier nombre premier ayant ete trouve est " << nombrespremiers[nombrespremiers.size()-1] << "\nAppuyez sur une touche pour arreter le programme" <<endl;
cin.ignore();
cin.ignore();
return EXIT_SUCCESS; // On dit au revoir au programme
}
// J'espere que vous avez tout compris !