Advertisement
Guest User

Untitled

a guest
Jul 28th, 2017
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.23 KB | None | 0 0
  1. #include <iostream>
  2. #include <cstdlib>
  3. #include <fstream>
  4. #include <math.h> //Se usa alguna raiz por ahi
  5.  
  6. using namespace std;
  7.  
  8. void aumentarArchivo(char nombre[], int veces);
  9. int recuperarUltimo(char nombre[]);
  10. void insertar(char nombre[],int n);
  11. int siguientePrimo(int numero);
  12. void EscribirVector(int v[],int n);
  13. void EscribirDescomposicion(int bases[],int exponentes[], int dimension);
  14. void descomponer(char nombre[],int n,int bases[],int exponentes[], int &ComponentesOcupadas);
  15. void Almacenar(int n,int bases[],int exponentes[],int &ComponentesOcupadas);
  16.  
  17.  
  18. int main(){
  19.    
  20.     char nombre[]="primos.DAT"; // Nombre del fichero con el que trabajaremos
  21.    
  22.    
  23.    
  24.     int bases[100],exponentes[100],n; // Almacenan bases, exponentes y el numero a descomponer.
  25.     int ComponentesOcupadas=0; // Almacena la dimension de bases y exponentes
  26.    
  27.     // Entrada de datos
  28.     cout<<"Numero a descomponer: ";
  29.     cin>>n;
  30.    
  31.     // Con esta primera llamada, nos aseguramos de que el archivo, si no existe, se cree para evitar errores despues
  32.     aumentarArchivo(nombre,2);
  33.    
  34.     // Descomponemos el numero y escribimos el resultado
  35.     descomponer(nombre,n,bases,exponentes, ComponentesOcupadas);
  36.     EscribirDescomposicion(bases,exponentes,ComponentesOcupadas);
  37.    
  38.      
  39.     cout<<endl;
  40.     system("PAUSE");
  41.     return 0;
  42. }
  43.  
  44. // Añade "veces" primos al archivo "nombre" de primos;
  45. void aumentarArchivo(char nombre[], int veces)
  46. {
  47.     int n=recuperarUltimo(nombre),i=1;
  48.     while (i<veces) {
  49.          n=siguientePrimo(n);
  50.          insertar(nombre,n);
  51.          i++;
  52.          }
  53. }
  54.  
  55. // Devuelve el ultimo numero del archivo "nombre". Tambien se encarga de crearlo si no existe
  56. int recuperarUltimo(char nombre[]){
  57.  
  58.     // Se declara un auxiliar y el fichero, y se abre
  59.     int aux;
  60.     ifstream f;
  61.     f.open(nombre,ios::in);
  62.    
  63.     // Si el fichero se abre, se recorre hasta el final, se cierra y se devuelve su ultimo dato
  64.     if (f) {
  65.            f>>aux;
  66.            while(!f.eof()){
  67.                            f>>aux;
  68.                            }
  69.            f.close();
  70.            return aux;
  71.            }
  72.            
  73.            // 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).
  74.            else {
  75.                 cout<<endl<<"No se puedo leer el fichero de primos. Creando uno nuevo..."<<endl;
  76.                 ofstream g;
  77.                 g.open(nombre,ios::out);
  78.                 if (g) {
  79.                        cout<<"Archivo creado"<<endl;
  80.                        g<<2<<endl<<3<<endl<<5<<endl<<7<<endl<<11<<endl<<13<<endl<<15<<endl<<17<<endl<<21<<endl;
  81.                        g.close();
  82.                        return 21; //Esta funcion devolvia el ultimo elemento del archivo, si lo acabamos de crear, es ese
  83.                        }
  84.                        
  85.                 else {
  86.                      cout<<"No se puedo crear un nuevo archivo"<<endl;
  87.                 }
  88.            }
  89. }
  90.  
  91. // Inserta el entero n  al final del fichero "nombre"
  92.  
  93. void insertar(char nombre[],int n){
  94.      ofstream f;
  95.      f.open(nombre,ios::app);
  96.      if (f) {
  97.             f<<n<<endl;
  98.             f.close();
  99.      }
  100.      else cout<<"Error al escribir el primo"<<n;
  101. }
  102.    
  103.  // Dado un numero, devuelve el menor primo mayor que ese numero
  104.    
  105. int siguientePrimo(int numero){
  106.    
  107. bool primo=true;    // El numero es primo hasta que se demuestre lo contrario
  108. int n=numero+1,d=3;  // Empezaremos a mirar el siguiente numero al que nos han pasado, e intentaremos dividir por 3
  109. if (n%2==0) n++; // Descartaamos los pares
  110.  
  111. // La razon de tratar los pares a parte es para luego poder incrementar el divisor de dos en dos
  112. // sin tener que hacer ifs de por medio.
  113.  
  114. float raizn=sqrt(n); // Calculamos la raiz de n, de esta forma nuestro algoritmo es más eficiente ya que
  115.                      // comprueba los menos numeros posibles (hasta donde yo se)
  116.    
  117.        
  118.         do {              
  119.             raizn=sqrt(n); //Actualizamos el limite a comprobar (raiz de n)
  120.             do {        
  121.                if (n%d==0) primo=false;  // Si el numero no es primo lo marcamos
  122.                d+=2; //basta con divisores impares
  123.                } while (d<=raizn && primo);  
  124.         if (primo==true) return n;
  125.        
  126.         n+=2;  // Se prueba con el siguiente entero
  127.         // Se resetean las variables para el nuevo n      
  128.         d=3;
  129.         primo=true;
  130.     } while (1);    
  131. }
  132.  
  133. // Escribe un vector
  134. void EscribirVector(int v[],int n){
  135.      int i;
  136.      cout<<endl<<endl<<"[";
  137.      for(i=0;i<n-1;i++){
  138.                       cout<<v[i]<<",";
  139.                       }
  140.      cout<<v[n-1];
  141.      cout<<"]";
  142. }
  143.  
  144. // Dados dos vectores de bases y exponentes y su dimensión, los escribe.
  145. void EscribirDescomposicion(int bases[],int exponentes[], int dimension){
  146.      int i;
  147.      cout<<endl<<"Descomposicion: ";
  148.      for(i=0;i<dimension-1;i++){
  149.                         cout<<bases[i];
  150.                         if (exponentes[i]!=1) cout<<"^"<<exponentes[i];
  151.                         cout<<" * ";
  152.      }
  153.      cout<<bases[dimension-1];
  154.      if (exponentes[dimension-1]!=1) cout<<"^"<<exponentes[dimension-1];
  155.      cout<<endl<<endl<<endl;
  156. }
  157.  
  158.  
  159.  
  160. // Descompone n y va llamando a Almacenar(d,bases,exponentes) con cada d divisor primo de n
  161. void descomponer(char nombre[],int n,int bases[],int exponentes[], int &ComponentesOcupadas){
  162.      
  163.      double raizn=sqrt(n);
  164.      int d=2,aux;
  165.  
  166.      ifstream f;
  167.      f.open(nombre,ios::in);
  168.      
  169.      if (f) {
  170.             f>>d;
  171.             }
  172.      else cout<<endl<<"Error al intentar leer primos desde "<<nombre<<endl;
  173.      
  174.      
  175.      
  176.      //Simplemente evitar el 1 que peude causar problemas
  177.      if (n==1){
  178.               Almacenar(1,bases,exponentes, ComponentesOcupadas);
  179.               }
  180.      
  181.      
  182.      
  183.      else {
  184.          
  185.      //  Bucle que va descomponiendo el número y llamando a Almacenar para almacenar sus divisores.
  186.      while (d<=raizn) {
  187.            
  188.            while (n%d==0) {
  189.                 n=n/d;
  190.                 Almacenar(d,bases,exponentes, ComponentesOcupadas);
  191.                 raizn=sqrt(n);              
  192.            }
  193.            
  194.            
  195.      // Si se acaba el fichero...
  196.     if (f.eof()) {
  197.                  aux=d; // Guardamos el divisor por el que vamos
  198.                  f.close(); //Cerramos el fichero (para poder ahora escribir en el)
  199.                  aumentarArchivo(nombre,100); //Aumentamos el fichero
  200.                  cout<<recuperarUltimo(nombre);
  201.  
  202.                  system("PAUSE");
  203.                  f.close();
  204.                  cout<<"nombre es "<<nombre;
  205.                  // Recorremos el fichero hasta alcanzar el divisor por el que ibamos
  206.                  f.open(nombre,ios::in);
  207.                  if (f)
  208.                  {    
  209.                        cout<<"Entré al if y d vale: "<<d; //debug
  210.                        d=1;
  211.                        cout<<endl<<"D="<<d;
  212.                        f>>d;
  213.                        cout<<"aqui estoy";
  214.                         while (d<aux) {
  215.                               cout<<"f,d, = "<<f<<" "<<d<<endl;
  216.                               f>>d;
  217.                               cout<<"f,d, = "<<f<<" "<<d<<endl;
  218.                               system("PAUSE");
  219.                               }
  220.              
  221.                  }          
  222.                  else cout<<endl<<"Fallo"<<endl;
  223.                  
  224.     }
  225.     //Siguiente divisor
  226.     f>>d;
  227.    
  228.     }
  229.     }  
  230.    
  231.     // Cuando el 2 es el unico divisor, hace falta evitar que almacene el 1  
  232.     if (n!=1) Almacenar(n,bases,exponentes,ComponentesOcupadas);
  233.     f.close();
  234. }
  235.  
  236.  
  237. /* Almacena un primo 'n' en los vectoers bases exponentes de la siguiente manera:
  238.         Si n esta en bases, incrementa su correspondiente posicion en exponentes en 1
  239.         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
  240. */
  241.    
  242. void Almacenar (int n,int bases[],int exponentes[],int &ComponentesOcupadas) {
  243.      int i,j=0; // j será el punto de insercción
  244.  
  245.          
  246.           // Recorremos el vector hasta el punto de inserccion
  247.           while (bases[j]<n && j<ComponentesOcupadas){
  248.                 j++;
  249.           }
  250.          
  251.           // Si la bas eya esta en el vector, se incremente el exponente
  252.           if (n==bases[j]) {
  253.                            exponentes[j]++;
  254.                            }
  255.          
  256.           // Si la base no sta en el vector, se inserta, para ello:          
  257.           else {
  258.                
  259.                // Se corren todas las componentes desde el punto de inserccionhacia la derecha
  260.                for(i=ComponentesOcupadas; i>j;i--){
  261.                                           bases[i+1]=bases[i];
  262.                                           exponentes[i+1]=exponentes[i];
  263.                                           }
  264.                // Se almacena n en el punto de inserccion, y se asigna su exponente. Despues se adecua la dimension del vector                        
  265.                bases[i]=n;
  266.                exponentes[i]=1;
  267.                ComponentesOcupadas++;
  268.                }
  269.          
  270.                                          
  271.    
  272. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement