Sobre números primos he escrito bastantes programas y me he dado cuenta de que los profesores de programación tienen cierta fijación con ellos. Pero bueno, el programa de hoy imprime la cantidad de números primos que el usuario quiera y es interesante porque es un buen ejemplo de la utilidad de los ciclos infinitos, que ya habÃamos visto antes.
Ok, el código es este:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| #include<iostream>
using namespace std;
int main()
{
int cnt,i=0,ii,res,nc=0,np=0;
cout << "Introduce la cantidad de numeros: "; cin >> cnt;
for(;;)
{
i++;
for(ii=1;ii<=i;ii++)
{
res=i%ii;
if(res==0)
nc=nc+1;
}
if(nc==2)
{
cout << i << " ";
np++;
}
nc=0;
if(np==cnt)
break;
}
} |
Si tienen problemas para entender cómo obtuvimos los números primos, deberÃan darle una revisada a estos posts: Saber si es primo o no y Primos en un rango.
Lo que hicimos es que todo el programa estuviera dentro de un ciclo infinito que se detendrá cuando nuestra variable que se aumenta cada vez que obtenemos un numero primo np sea igual a la variable con la cantidad deseada de números primos cnt.
Pero recuerden que donde podemos usar un ciclo infinito, queda mucho mejor un ciclo while:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| #include<iostream>
using namespace std;
int main()
{
int cnt,i=0,ii,res,nc=0,np=0;
cout << "Introduce la cantidad de numeros: "; cin >> cnt;
while(np!=cnt)
{
i++;
for(ii=1;ii<=i;ii++)
{
res=i%ii;
if(res==0)
nc=nc+1;
}
if(nc==2)
{
cout << i << " ";
np++;
}
nc=0;
}
} |
Únicamente ponemos la palabra while en lugar de for, copiamos la condición que ‘condicionaba’ (sÃ, lo se) el break y la pegamos dentro de los paréntesis del while pero de manera contraria (de == a != o de < a >).
Bueno, en esta ocasión vamos a ayudarle a un comentarista de este blog con sus problemas, el me ha pedido un programa que cuente la cantidad de números primos que hay en un rango, no se ha conformado con saber si un número es primo o no o con saber cómo mostrar los números primos en un rango, asà que le vamos a ayudar con la única parte de su programa que le falta: saber cómo contar el número de veces que sucede algo.
Para esto vamos a usar una variable tipo int (entero) que va a ir aumentando una unidad cada vez que ocurra ese ‘algo’ que queremos contar. Veamos como funcionarÃa un contador dentro de un ciclo:
#include<iostream>
using namespace std;
int main()
{
int contador=0;
for(int i=0; i<10; i++)
contador++;
cout << contador;
}
Obviamente esto muestra un 10 en pantalla. Porque la variable ‘contador’ aumenta una unidad cada vez que el ciclo da una vuelta.
contador++; es lo mismo que contador = contador + 1;
Ahora veamos como funciona si agregamos una condición:
#include<iostream>
using namespace std;
int main()
{
int contador=0;
for(int i=0; i<10; i++)
{
if(i==5)
contador++;
}
cout << contador;
}
Esto obviamente muestra en pantalla un 1, porque solo una vez i vale 5. Ahora con una condición más complicada:
#include<iostream>
using namespace std;
int main()
{
int contador=0;
for(int i=0; i<10; i++)
{
if(i%2==0)
contador++;
}
cout << contador;
}
Con el operador % se obtiene el residuo de la división de los dos números entre los que está. Si la condición es que i/2 tenga residuo un de 0, significa que estamos dejando pasar sólo los números pares, por lo que deberá mostrarse en pantalla un 5.
Qué fácil no?, ahora nuestro amigo ya tiene todo lo necesario para armar su programa.
Me preguntaban en los comentarios de este post: Primo o no, que si habrÃa alguna forma de hacer ese mismo programa pero sin ciclos. Mmmm…
Pues mi primera respuesta es no. Pero hay una forma muy burda de aproximarse a él. El siguiente programa es para calcular si un número es primo o no sin ciclos y es infalible hasta el 168, a partir de ahà puede que le atine o puede que no.
#include<iostream>
using namespace std;
int main()
{
int n;
cout << "Introduce un numero: "; cin >> n;
if(n!=2 & n%2==0)
cout << "No es primo";
else
{
if(n!=3 & n%3==0)
cout << "No es primo";
else
{
if(n!=5 & n%5==0)
cout << "No es primo";
else
{
if(n!=7 & n%7==0)
cout << "No es primo";
else
{
if(n!=11 & n%11==0)
cout << "No es primo";
else
{
cout << "Es primo";
}
}
}
}
}
}
- Como vemos, primeramente checa si n es igual a 2; si no, checa si el residuo de n/2 es cero. Si si, no es primo; si no, sigue.
- Luego checa si n es igual a 3; si no, checa si el residuo de n/3 es cero. Si si, no es primo; si no, sigue.
- Lo mismo con el 5, el 7 y el 11.
Con eso obtenemos un buen número de números en los que estamos seguros que no fallaremos. Si agregamos el 13, agrandamos esa cantidad; y aún mas con el 17, el 19, … como en esta versión optimizada, que tiene su primer error con el 1681 (que no es primo)
#include<iostream>
using namespace std;
int main()
{
int n;
cout << "Introduce un numero: "; cin >> n;
if((n!=2 & n%2==0)||(n!=3 & n%3==0)||(n!=5 & n%5==0)||(n!=7 & n%7==0)||
(n!=11 & n%11==0)||(n!=13 & n%13==0)||(n!=17 & n%17==0)||(n!=19 & n%19==0)||
(n!=23 & n%23==0)||(n!=29 & n%29==0)||(n!=31 & n%31==0)||(n!=37 & n%37==0))
cout << "No es primo";
else
cout << "Es primo";
}
Pero pues de eso no se trata, los ciclos son para evitar las cantidades interminables de ifs, asà que usémoslos.
Ah y recuerden que si corren un programa y su compilador no se pausa solo, tienen que agregar cin.get();cin.get(); al final del programa, antes de la llave de cierre del main.
Si llegaste aquà buscando un programa para saber si un número es primo o no, sigue el link que está al principio del post.
Anteriormente vimos como imprimir los números primos en un rango determinado por el usuario, ahora la idea es pedirle al usuario un número y decirle si es primo o no es primo.
#include<iostream>
using namespace std;
int main()
{
int num,c,res,nc=0;
cout<<"Introduce un número: "; cin>>num;
for(c=1;c<=num;c++)
{
res=num%c;
if(res==0)
nc++;
if(nc>2)
break;
}
if(nc==2)
cout<<"Es primo";
else
cout<<"No es primo";
cin.get();cin.get();
}
En sÃ, es lo mismo que el anterior. Para darle mas presentación podemos hacer que no se salga a la primera, sino hasta que se introduzca, por ejemplo, un cero. Esto se hace con un ciclo do while.
#include<iostream>
using namespace std;
int main()
{
int num=1,c,res,nc=0,rep=0;
while(num!=0)
{
cout<<"Introduce un número: ";
if(rep==1)
{
cout<<" --> Para salir oprime cero: ";
}
rep++;
cin>>num;
for(c=1;c<=num;c++)
{
res=num%c;
if(res==0)
nc++;
}
if(nc==2)
cout<<"Es primo\n\n";
else
cout<<"No es primo\n\n";
nc=0;
}
}
¿Alguien sabe porqué la variable num empieza en 1 en este caso?
La idea es imprimir en pantalla los números primos entre 1 y un dato introducido por el usuario. Creo que es la primera vez que usamos un ciclo dentro de otro ciclo en este blog. Pero en realidad es muy sencillo:
#include<iostream>
using namespace std;
int main()
{
int n=0,c=0,c2=0,res=0,nc=0;
cout<<"Introduce el limite de numeros: "; cin>>n;
for(c=1;c<=n;c++)
{
for(c2=1;c2<=c;c2++)
{
res=c%c2;
if(res==0)
{
nc=nc+1;
}
}
if(nc==2)
{
cout<<" "<<c;
}
nc=0;
}
}
El operador % obtiene el residuo de la división de dos números. Por ejemplo:
10 % 3 = 1
Porque el 3 cabe 3 veces en el 10 y le sobra 1.
Explicación:
- El primer ciclo lleva la cuenta de los números de 1 a n de uno por uno en la variable c
- Luego se inicia un ciclo de 1 a c en la variable c2. Este ciclo se hará n veces porque está dentro de el primer ciclo
- En la variable res se guarda el residuo de dividir c / c2
- Si el residuo es cero, se incremento al contador nc
- Si al terminarse el segundo ciclo el contador nc es igual a 2, significa que el número es primo y lo imprime
Recuerden que los números primos son los que únicamente se dividen (sin dejar residuo) entre 1 y entre si mismos