Advertisement
Guest User

Untitled

a guest
Jun 28th, 2017
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.67 KB | None | 0 0
  1. //============================================================================
  2. // Name        : Erastotenes.cpp
  3. // Author      : Miguel Angel Pau Diaz
  4. // Version     :
  5. // Copyright   : Fundamentos de Programación 2010
  6. // Description : Criba de Erastótenes para hallar números primos
  7. //============================================================================
  8.  
  9. #define _WIN32_WINNT 0x0500 // Para GetConsoleWindow()
  10.  
  11. #include <iostream>
  12. #include <stdio.h>
  13. #include <iomanip>
  14. #include <stdlib.h>
  15. #include <time.h>
  16. #include <windows.h>
  17.  
  18. using namespace std;
  19.  
  20.  
  21. void InitMatriz (int MatriNum[], int const DimMatri, int const InitCode, int const RSup); //InitCode: 0 - a ceros, 1 - a unos, 2 - con el valor del índice
  22. int  Criba(int MatriNum[], int const DimMatri, int const NCrib); //NCrib: número con el que cribar sus múltiplos - Retorna: 0 o siguiente primo hallado
  23. void CompletaLista(int MatriNum[], int const UltiRang, int indMat, int ListP[], int& indLis);
  24. void ShowResult (int Matr[], int ListP[], int const Rango, int const TLis, HANDLE Consola, CONSOLE_SCREEN_BUFFER_INFO BufInfo); //Muestra  en pantalla la Matriz y la lista de primos encontrados
  25.  
  26.  
  27. int main() {
  28.     int const TMat = 201;   //Se pierden 2 bytes, a cambio se gana comodidad en lectura del código
  29.     int const IniCod = 2;   //Indica que hay que rellenar la matriz con los números que corresponden a sus indices (a efectos de presentación de datos)
  30.     int iMatNum[TMat], iRango;
  31.     int iListaPrimos[100], iLis, icheck; //iLis: tamaño de la lista de primos encontrados
  32.     int ialto=200, iancho=800, ih;
  33.     HWND Consola = GetConsoleWindow();  //Handle de consola para mover y/o cambiar su tamaño
  34.     RECT r;     //Estructura de datos para almacenar coordenadas de rectangulos
  35.     HANDLE hStdout;                     //Handle genérico (puntero a objeto)
  36.     CONSOLE_SCREEN_BUFFER_INFO csbINFO; //Estructura de datos para trabajar con objetos tipo consola
  37.  
  38.     GetWindowRect(Consola, &r);     //almacena datos de la consola en r
  39.     MoveWindow(Consola, r.left, r.top, iancho, ialto, TRUE);    //Mueve y/o cambia el tamaño de la consola: MoveWindow(handle, x, y, ancho (pixels), alto(pixesl), Repintar_ventana(true/false))
  40.     hStdout = GetStdHandle(STD_OUTPUT_HANDLE);  //Carga el handle de la salida a consola.
  41.  
  42.     do{
  43.         system("cls");
  44.         cout << "\n CRIBA DE ERASTOTENES PARA EL CALCULO DE NUMEROS PRIMOS" << endl;
  45.         cout << "\n Indica el limite superior del rango a calcular [(1 - XXX) max. 200]:" << endl;
  46.         cin >> iRango;
  47.     }while (iRango<0 && iRango>200);
  48.  
  49.     ih=((iRango/10)+14)*14; //14 pixels por línea de consola
  50.     if (ih>ialto){  //Comprueba que el tamaño de consola es apropiado para mostrar el resultado
  51.         ialto+= ih-ialto;//(iRango/10)*25;
  52.         MoveWindow(Consola, r.left, r.top, iancho, ialto, TRUE);    //Redimensiona consola
  53.     }
  54.  
  55.     InitMatriz(iMatNum, TMat, IniCod, iRango);
  56.  
  57.     iLis = 0;   //Se puede inicializar en la declaración, pero así queda más clara la lógica
  58.     system("cls");  //Limpia consola para presentar datos
  59.     ShowResult(iMatNum,iListaPrimos,iRango,iLis, hStdout, csbINFO);
  60.     for (int i=2; i<=iRango ; i++){
  61.         if (i*i<=iRango){
  62.             icheck = Criba (iMatNum, TMat, i);
  63.             if (icheck!=0){
  64.                 iListaPrimos[iLis]=icheck;
  65.                 iLis++;
  66.             }
  67.         }else{
  68.             CompletaLista(iMatNum, iRango, i, iListaPrimos, iLis);
  69.             ShowResult(iMatNum,iListaPrimos,iRango,iLis, hStdout, csbINFO);
  70.             i=iRango+1;     //Para terminar el bucle en el próximo ciclo for
  71.         }
  72.         ShowResult(iMatNum,iListaPrimos,iRango,iLis, hStdout, csbINFO);
  73.     }
  74.  
  75.     cout << endl;
  76.     cout << "\n Todos los primos del rango encontrados.\n Fin de programa." << endl;
  77.     fflush(stdin);
  78.     cin.get();
  79.  
  80.     return 0;
  81. }
  82.  
  83.  
  84. //Inicializa Matriz numérica
  85. void InitMatriz (int MatriNum[], int const DimMatri, int const InitCode, int const RSup){ //InitCode: 0 - a ceros, 1 - a unos, 2 - con el valor del índice
  86.     int Top;
  87.  
  88.     if (RSup<DimMatri) Top=RSup; //Establece número de elementos a tratar
  89.     else Top=DimMatri;
  90.  
  91.     for (int l=0; l<Top; l++)
  92.         switch (InitCode){
  93.             case 0:
  94.                 MatriNum[l]=InitCode;
  95.                 break;
  96.             case 1:
  97.                 MatriNum[l]=InitCode;
  98.                 break;
  99.             case 2:
  100.                 MatriNum[l]=l;
  101.                 break;
  102.         }
  103. }
  104.  
  105. //Va eliminando los múltiplos de NCrib de la Matriz
  106. int Criba(int MatriNum[], int const DimMatri, int const NCrib){ //NCrib: número con el que cribar sus múltiplos - Retorna: 0 o siguiente primo hallado
  107.     int iCrib=0;
  108.  
  109.     if (NCrib!=0){
  110.         if (NCrib==2) MatriNum[1]=0; //Cribamos el 1 por defecto la primera vez que se entra (se empieza a buscar primos a partir del 2)
  111.  
  112.         iCrib = MatriNum[NCrib];     //Si ya estaba cribado 0 ó -1, si no, es primo
  113.         if (iCrib <0) iCrib=0;       //No queremos que los -1 aparezcan como primos
  114.  
  115.         for (int i=0; i<DimMatri; i++)
  116.             if (MatriNum[i]==0) MatriNum[i]= -1;    //Cribas anteriores a -1 a efectos de presentación gráfica
  117.         for (int i=NCrib; i<DimMatri; i+=NCrib){
  118.             if (i>NCrib) MatriNum[i]=0;     //Dejamos el primo sin cribar, sus múltiplos a cero
  119.             }
  120.     }
  121.     return iCrib;
  122. }
  123.  
  124.  
  125. //Completa la lista de primos con los que quedan en la Matriz sin cribar
  126. void CompletaLista(int MatriNum[], int const UltiRang, int indMat, int ListP[], int& indLis){
  127.     int icheck;
  128.  
  129.     for(int i=indMat; i<UltiRang; i++){
  130.         icheck = MatriNum[i];
  131.         if(icheck>0){
  132.             ListP[indLis]=icheck;   //Es primo, <=0 -> cribados
  133.             indLis++;
  134.         }
  135.     }
  136. }
  137.  
  138.  
  139. //Muestra Matriz y lista de primos en pantalla
  140. void ShowResult (int Matr[], int ListP[], int const Rango, int const TLis, HANDLE Consola, CONSOLE_SCREEN_BUFFER_INFO BufInfo){
  141.     int const Sangrado = 15;
  142.     int Retardo = 256; //Retardo en milisegundos para mejorar la presentación
  143.     int iN; //iN - comprobación para sangrado en bucle de presentación datos
  144.     double dclock, dTimeOut;
  145.  
  146.     BufInfo.dwCursorPosition.X = 0; //como "gotoxy()" de conio.h (Bordland), pero genérico de Windows
  147.     BufInfo.dwCursorPosition.Y = 0;
  148.     SetConsoleCursorPosition(Consola, BufInfo.dwCursorPosition); // Coloca el cursor en esquina sup. izda para reescribir pantalla
  149.  
  150.     cout << "\n\n BUSCANDO PRIMOS:\n" << endl; // Para que quede gonito
  151.     for(int l=0; l<=(Rango/10); l++){
  152.         cout << "\n" << setw(Sangrado) << setfill(' ') << " ";
  153.         for (int j=0; j<10; j++){
  154.             if (((l*10)+j)<Rango){
  155.                 iN = Matr[(l*10)+j];
  156.                 if (iN==0) cout << "  x ";
  157.                 else if (iN<0) cout << "  . ";
  158.                 else if (iN<10) cout << "  " << iN << " ";
  159.                 else if (iN<100) cout << " " << iN << " ";
  160.                 else cout << iN << " ";
  161.             }
  162.         }
  163.     }
  164.     cout << endl;
  165.     if (TLis>0){    //Sólo los muestra si ya hay al menos 1 en la lista
  166.         cout << "\n Numeros primos encontrados:\n [";
  167.         for (int l=0; l<TLis; l++){
  168.             if (l!=TLis-1) cout << ListP[l] << ",";
  169.             else cout << ListP[l];
  170.         }
  171.         cout << "]";
  172.     }
  173.     dclock = clock();
  174.     dTimeOut = dclock+Retardo;
  175.     while (clock()<(dTimeOut)); //Retardo para mejorar presentación
  176. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement