Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //============================================================================
- // Name : Erastotenes.cpp
- // Author : Miguel Angel Pau Diaz
- // Version :
- // Copyright : Fundamentos de Programación 2010
- // Description : Criba de Erastótenes para hallar números primos
- //============================================================================
- #define _WIN32_WINNT 0x0500 // Para GetConsoleWindow()
- #include <iostream>
- #include <stdio.h>
- #include <iomanip>
- #include <stdlib.h>
- #include <time.h>
- #include <windows.h>
- using namespace std;
- 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
- 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
- void CompletaLista(int MatriNum[], int const UltiRang, int indMat, int ListP[], int& indLis);
- 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
- int main() {
- int const TMat = 201; //Se pierden 2 bytes, a cambio se gana comodidad en lectura del código
- 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)
- int iMatNum[TMat], iRango;
- int iListaPrimos[100], iLis, icheck; //iLis: tamaño de la lista de primos encontrados
- int ialto=200, iancho=800, ih;
- HWND Consola = GetConsoleWindow(); //Handle de consola para mover y/o cambiar su tamaño
- RECT r; //Estructura de datos para almacenar coordenadas de rectangulos
- HANDLE hStdout; //Handle genérico (puntero a objeto)
- CONSOLE_SCREEN_BUFFER_INFO csbINFO; //Estructura de datos para trabajar con objetos tipo consola
- GetWindowRect(Consola, &r); //almacena datos de la consola en r
- 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))
- hStdout = GetStdHandle(STD_OUTPUT_HANDLE); //Carga el handle de la salida a consola.
- do{
- system("cls");
- cout << "\n CRIBA DE ERASTOTENES PARA EL CALCULO DE NUMEROS PRIMOS" << endl;
- cout << "\n Indica el limite superior del rango a calcular [(1 - XXX) max. 200]:" << endl;
- cin >> iRango;
- }while (iRango<0 && iRango>200);
- ih=((iRango/10)+14)*14; //14 pixels por línea de consola
- if (ih>ialto){ //Comprueba que el tamaño de consola es apropiado para mostrar el resultado
- ialto+= ih-ialto;//(iRango/10)*25;
- MoveWindow(Consola, r.left, r.top, iancho, ialto, TRUE); //Redimensiona consola
- }
- InitMatriz(iMatNum, TMat, IniCod, iRango);
- iLis = 0; //Se puede inicializar en la declaración, pero así queda más clara la lógica
- system("cls"); //Limpia consola para presentar datos
- ShowResult(iMatNum,iListaPrimos,iRango,iLis, hStdout, csbINFO);
- for (int i=2; i<=iRango ; i++){
- if (i*i<=iRango){
- icheck = Criba (iMatNum, TMat, i);
- if (icheck!=0){
- iListaPrimos[iLis]=icheck;
- iLis++;
- }
- }else{
- CompletaLista(iMatNum, iRango, i, iListaPrimos, iLis);
- ShowResult(iMatNum,iListaPrimos,iRango,iLis, hStdout, csbINFO);
- i=iRango+1; //Para terminar el bucle en el próximo ciclo for
- }
- ShowResult(iMatNum,iListaPrimos,iRango,iLis, hStdout, csbINFO);
- }
- cout << endl;
- cout << "\n Todos los primos del rango encontrados.\n Fin de programa." << endl;
- fflush(stdin);
- cin.get();
- return 0;
- }
- //Inicializa Matriz numérica
- 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
- int Top;
- if (RSup<DimMatri) Top=RSup; //Establece número de elementos a tratar
- else Top=DimMatri;
- for (int l=0; l<Top; l++)
- switch (InitCode){
- case 0:
- MatriNum[l]=InitCode;
- break;
- case 1:
- MatriNum[l]=InitCode;
- break;
- case 2:
- MatriNum[l]=l;
- break;
- }
- }
- //Va eliminando los múltiplos de NCrib de la Matriz
- 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
- int iCrib=0;
- if (NCrib!=0){
- 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)
- iCrib = MatriNum[NCrib]; //Si ya estaba cribado 0 ó -1, si no, es primo
- if (iCrib <0) iCrib=0; //No queremos que los -1 aparezcan como primos
- for (int i=0; i<DimMatri; i++)
- if (MatriNum[i]==0) MatriNum[i]= -1; //Cribas anteriores a -1 a efectos de presentación gráfica
- for (int i=NCrib; i<DimMatri; i+=NCrib){
- if (i>NCrib) MatriNum[i]=0; //Dejamos el primo sin cribar, sus múltiplos a cero
- }
- }
- return iCrib;
- }
- //Completa la lista de primos con los que quedan en la Matriz sin cribar
- void CompletaLista(int MatriNum[], int const UltiRang, int indMat, int ListP[], int& indLis){
- int icheck;
- for(int i=indMat; i<UltiRang; i++){
- icheck = MatriNum[i];
- if(icheck>0){
- ListP[indLis]=icheck; //Es primo, <=0 -> cribados
- indLis++;
- }
- }
- }
- //Muestra Matriz y lista de primos en pantalla
- void ShowResult (int Matr[], int ListP[], int const Rango, int const TLis, HANDLE Consola, CONSOLE_SCREEN_BUFFER_INFO BufInfo){
- int const Sangrado = 15;
- int Retardo = 256; //Retardo en milisegundos para mejorar la presentación
- int iN; //iN - comprobación para sangrado en bucle de presentación datos
- double dclock, dTimeOut;
- BufInfo.dwCursorPosition.X = 0; //como "gotoxy()" de conio.h (Bordland), pero genérico de Windows
- BufInfo.dwCursorPosition.Y = 0;
- SetConsoleCursorPosition(Consola, BufInfo.dwCursorPosition); // Coloca el cursor en esquina sup. izda para reescribir pantalla
- cout << "\n\n BUSCANDO PRIMOS:\n" << endl; // Para que quede gonito
- for(int l=0; l<=(Rango/10); l++){
- cout << "\n" << setw(Sangrado) << setfill(' ') << " ";
- for (int j=0; j<10; j++){
- if (((l*10)+j)<Rango){
- iN = Matr[(l*10)+j];
- if (iN==0) cout << " x ";
- else if (iN<0) cout << " . ";
- else if (iN<10) cout << " " << iN << " ";
- else if (iN<100) cout << " " << iN << " ";
- else cout << iN << " ";
- }
- }
- }
- cout << endl;
- if (TLis>0){ //Sólo los muestra si ya hay al menos 1 en la lista
- cout << "\n Numeros primos encontrados:\n [";
- for (int l=0; l<TLis; l++){
- if (l!=TLis-1) cout << ListP[l] << ",";
- else cout << ListP[l];
- }
- cout << "]";
- }
- dclock = clock();
- dTimeOut = dclock+Retardo;
- while (clock()<(dTimeOut)); //Retardo para mejorar presentación
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement