Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cstdlib>
- #include <fstream>
- #include <math.h> //Se usa alguna raiz por ahi
- using namespace std;
- void aumentarArchivo(char nombre[], int veces);
- int recuperarUltimo(char nombre[]);
- void insertar(char nombre[],int n);
- int siguientePrimo(int numero);
- void EscribirVector(int v[],int n);
- void EscribirDescomposicion(int bases[],int exponentes[], int dimension);
- void descomponer(char nombre[],int n,int bases[],int exponentes[], int &ComponentesOcupadas);
- void Almacenar(int n,int bases[],int exponentes[],int &ComponentesOcupadas);
- int main(){
- char nombre[]="primos.DAT"; // Nombre del fichero con el que trabajaremos
- int bases[100],exponentes[100],n; // Almacenan bases, exponentes y el numero a descomponer.
- int ComponentesOcupadas=0; // Almacena la dimension de bases y exponentes
- // Entrada de datos
- cout<<"Numero a descomponer: ";
- cin>>n;
- // Con esta primera llamada, nos aseguramos de que el archivo, si no existe, se cree para evitar errores despues
- aumentarArchivo(nombre,2);
- // Descomponemos el numero y escribimos el resultado
- descomponer(nombre,n,bases,exponentes, ComponentesOcupadas);
- EscribirDescomposicion(bases,exponentes,ComponentesOcupadas);
- cout<<endl;
- system("PAUSE");
- return 0;
- }
- // Añade "veces" primos al archivo "nombre" de primos;
- void aumentarArchivo(char nombre[], int veces)
- {
- int n=recuperarUltimo(nombre),i=1;
- while (i<veces) {
- n=siguientePrimo(n);
- insertar(nombre,n);
- i++;
- }
- }
- // Devuelve el ultimo numero del archivo "nombre". Tambien se encarga de crearlo si no existe
- int recuperarUltimo(char nombre[]){
- // Se declara un auxiliar y el fichero, y se abre
- int aux;
- ifstream f;
- f.open(nombre,ios::in);
- // Si el fichero se abre, se recorre hasta el final, se cierra y se devuelve su ultimo dato
- if (f) {
- f>>aux;
- while(!f.eof()){
- f>>aux;
- }
- f.close();
- return aux;
- }
- // Si el fichero no se abre se intenta crear uno nuevo con unos cuantos primos iniciales (si se ponen menos primos hay un problemilla que no se de donde sale).
- else {
- cout<<endl<<"No se puedo leer el fichero de primos. Creando uno nuevo..."<<endl;
- ofstream g;
- g.open(nombre,ios::out);
- if (g) {
- cout<<"Archivo creado"<<endl;
- g<<2<<endl<<3<<endl<<5<<endl<<7<<endl<<11<<endl<<13<<endl<<15<<endl<<17<<endl<<21<<endl;
- g.close();
- return 21; //Esta funcion devolvia el ultimo elemento del archivo, si lo acabamos de crear, es ese
- }
- else {
- cout<<"No se puedo crear un nuevo archivo"<<endl;
- }
- }
- }
- // Inserta el entero n al final del fichero "nombre"
- void insertar(char nombre[],int n){
- ofstream f;
- f.open(nombre,ios::app);
- if (f) {
- f<<n<<endl;
- f.close();
- }
- else cout<<"Error al escribir el primo"<<n;
- }
- // Dado un numero, devuelve el menor primo mayor que ese numero
- int siguientePrimo(int numero){
- bool primo=true; // El numero es primo hasta que se demuestre lo contrario
- int n=numero+1,d=3; // Empezaremos a mirar el siguiente numero al que nos han pasado, e intentaremos dividir por 3
- if (n%2==0) n++; // Descartaamos los pares
- // La razon de tratar los pares a parte es para luego poder incrementar el divisor de dos en dos
- // sin tener que hacer ifs de por medio.
- float raizn=sqrt(n); // Calculamos la raiz de n, de esta forma nuestro algoritmo es más eficiente ya que
- // comprueba los menos numeros posibles (hasta donde yo se)
- do {
- raizn=sqrt(n); //Actualizamos el limite a comprobar (raiz de n)
- do {
- if (n%d==0) primo=false; // Si el numero no es primo lo marcamos
- d+=2; //basta con divisores impares
- } while (d<=raizn && primo);
- if (primo==true) return n;
- n+=2; // Se prueba con el siguiente entero
- // Se resetean las variables para el nuevo n
- d=3;
- primo=true;
- } while (1);
- }
- // Escribe un vector
- void EscribirVector(int v[],int n){
- int i;
- cout<<endl<<endl<<"[";
- for(i=0;i<n-1;i++){
- cout<<v[i]<<",";
- }
- cout<<v[n-1];
- cout<<"]";
- }
- // Dados dos vectores de bases y exponentes y su dimensión, los escribe.
- void EscribirDescomposicion(int bases[],int exponentes[], int dimension){
- int i;
- cout<<endl<<"Descomposicion: ";
- for(i=0;i<dimension-1;i++){
- cout<<bases[i];
- if (exponentes[i]!=1) cout<<"^"<<exponentes[i];
- cout<<" * ";
- }
- cout<<bases[dimension-1];
- if (exponentes[dimension-1]!=1) cout<<"^"<<exponentes[dimension-1];
- cout<<endl<<endl<<endl;
- }
- // Descompone n y va llamando a Almacenar(d,bases,exponentes) con cada d divisor primo de n
- void descomponer(char nombre[],int n,int bases[],int exponentes[], int &ComponentesOcupadas){
- double raizn=sqrt(n);
- int d=2,aux;
- ifstream f;
- f.open(nombre,ios::in);
- if (f) {
- f>>d;
- }
- else cout<<endl<<"Error al intentar leer primos desde "<<nombre<<endl;
- //Simplemente evitar el 1 que peude causar problemas
- if (n==1){
- Almacenar(1,bases,exponentes, ComponentesOcupadas);
- }
- else {
- // Bucle que va descomponiendo el número y llamando a Almacenar para almacenar sus divisores.
- while (d<=raizn) {
- while (n%d==0) {
- n=n/d;
- Almacenar(d,bases,exponentes, ComponentesOcupadas);
- raizn=sqrt(n);
- }
- // Si se acaba el fichero...
- if (f.eof()) {
- aux=d; // Guardamos el divisor por el que vamos
- f.close(); //Cerramos el fichero (para poder ahora escribir en el)
- aumentarArchivo(nombre,100); //Aumentamos el fichero
- cout<<recuperarUltimo(nombre);
- system("PAUSE");
- f.close();
- cout<<"nombre es "<<nombre;
- // Recorremos el fichero hasta alcanzar el divisor por el que ibamos
- f.open(nombre,ios::in);
- if (f)
- {
- cout<<"Entré al if y d vale: "<<d; //debug
- d=1;
- cout<<endl<<"D="<<d;
- f>>d;
- cout<<"aqui estoy";
- while (d<aux) {
- cout<<"f,d, = "<<f<<" "<<d<<endl;
- f>>d;
- cout<<"f,d, = "<<f<<" "<<d<<endl;
- system("PAUSE");
- }
- }
- else cout<<endl<<"Fallo"<<endl;
- }
- //Siguiente divisor
- f>>d;
- }
- }
- // Cuando el 2 es el unico divisor, hace falta evitar que almacene el 1
- if (n!=1) Almacenar(n,bases,exponentes,ComponentesOcupadas);
- f.close();
- }
- /* Almacena un primo 'n' en los vectoers bases exponentes de la siguiente manera:
- Si n esta en bases, incrementa su correspondiente posicion en exponentes en 1
- si n no esta en bases, la añade en el lugar adecuado (ordenado de menor a mayor) y crea un indice para ese exponente
- */
- void Almacenar (int n,int bases[],int exponentes[],int &ComponentesOcupadas) {
- int i,j=0; // j será el punto de insercción
- // Recorremos el vector hasta el punto de inserccion
- while (bases[j]<n && j<ComponentesOcupadas){
- j++;
- }
- // Si la bas eya esta en el vector, se incremente el exponente
- if (n==bases[j]) {
- exponentes[j]++;
- }
- // Si la base no sta en el vector, se inserta, para ello:
- else {
- // Se corren todas las componentes desde el punto de inserccionhacia la derecha
- for(i=ComponentesOcupadas; i>j;i--){
- bases[i+1]=bases[i];
- exponentes[i+1]=exponentes[i];
- }
- // Se almacena n en el punto de inserccion, y se asigna su exponente. Despues se adecua la dimension del vector
- bases[i]=n;
- exponentes[i]=1;
- ComponentesOcupadas++;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement