¿Cómo se genera una cantidad definida por el usuario de los números primos?

StackOverflow https://stackoverflow.com/questions/2415033

  •  19-09-2019
  •  | 
  •  

Pregunta

Estoy intentando generar números primos en base a la entrada del usuario. Esto es lo que tengo hasta ahora, pero me parece que no puede averiguarlo:

Console.Write("Please enter the number of prime numbers you would like to see:");
int numberOfPrimes = Convert.ToInt32(Console.ReadLine());

for (int x = 0; x < numberOfPrimes; x++)
{
    for (int a = 2; a <= x ; ++a)
    {
        bool prime = true;
        for (int b = 2; b < a; ++b)
        {
            if (a % b == 0)
            {
                prime = false;
            }//end if
        }//end double nested for
        if (prime == true)
        {
            Console.WriteLine(a);
        }//end if
    }//end nested for
}//end for
¿Fue útil?

Solución

Usted debe ser capaz de ver por qué sus resultados son malos con bastante facilidad si nos fijamos en sus estructuras de bucle. Paso a través de ellos con la mano (que no pasará mucho tiempo).

La razón por la que usted está consiguiendo los resultados actuales es que no todos los iteración del bucle exterior (x < numberOfPrimes) produce un resultado - se saltará un buen número de iteraciones debido a la forma en que está estructurado el bucle interno

.

Lo que realmente necesita hacer es reestructurar los bucles internos. Su bucle más interior funciona bien, y debe detectar cualquier números primos. Su segundo bucle, sin embargo, sólo debe probar los números que aún no han sido probados. También, se debe dejar de bucle una vez que encuentre un número primo.

Otros consejos

Usted debe estructurar su código mejor, es muy sucia de la manera que lo hace ahora. IsPrime(int x) tener un método que devuelve verdadero si x es primo y falso en caso contrario.

A continuación, para generar números primos numberOfPrimes, se puede hacer algo como esto:

for ( int primeCount = 0, currentPrime = 2; primeCount < numberOfPrimes; ++currentPrime )
  if ( IsPrime(currentPrime) )
  {
    // do whatever you want with currentPrime, like print it
    ++primeCount;
  }

O utilice el criba de Eratóstenes , que es un método mucho más rápido.

Para averiguar si un x número es primo o no, pruebe todos sus factores entre 2 y Sqrt(x). ¿Por qué sólo Sqrt(x)? Porque si a*b = x, entonces x / b = a y x / a = b, Así que tendría comprobar todo dos veces, y también comprobar cosas que no debería si se acercó a x / 2 o incluso x.

Así que algo como esto si desea utilizar la función IsPrime(x):

// i <= Sqrt(x) <=> i * i <= x
for ( int i = 2; i * i <= x; ++i )
  if ( x % i == 0 )
    return false;

return true;

Pero le sugiero que utilice la criba de Eratóstenes, ya que es mucho más rápido. También puede optimizar las cosas para que no comprueba los números pares, ya que un número aún no es primordial, a excepción de 2 (tanto en el tamiz y el método ingenuo). Tratar x = 2 como un caso borde y luego empezar a comprobar cada otro número (3, 5, 7, 9, 11, etc.)

Lo que usted está buscando se llama "criba de Eratóstenes." Como no estoy en hacer la tarea de la gente, esta es la única pista que voy a dar a usted. El algoritmo es fácil de encontrar en el Internet.

El siguiente número primo (x) - es el número de los que no puedo ser dividida por todos los primos s, que s <= sqrt (x). Así que usted puede utilizar la función como

public bool CheckAndAddPrime(int number,List<int> primes)
{
    var sqrt = Math.Sqrt(number);
    foreach(var prime in primes)
    {
        if(prime>sqrt) break;
        if(number % prime == 0) return false;    
    }

    primes.Add(number);
    return true;
}

Y que se puede obtener números primos como

var primes = new List<int>();
Enumerable.Range(2,int.MaxValue).Where(x => x.CheckAndAddPrime(x,primes)).Take(YouCountOfPrimes);
var primes = Enumerable.Range(1, numberOfPrimes )
    .Where(x => x != 1 &&
      !Enumerable.Range2, (int)Math.Sqrt(x)).Any(y => x != y && x % y == 0));

copiada de codethinked.com

static void Main(string[] args)
{
    foreach (int no in get_first_k_primes(10))
    {
        Console.Write(" "+no.ToString() );
    }
}

public static List<int> get_first_k_primes(int k)
{
    var primes = new List<int>();

    primes.Add(2);

    int i  = 3;


    while(primes.Count < k)
    {
        if(is_prime(i))
            primes.Add(i);

        i += 2;
    }

    return primes;
}

public static bool is_prime(int n)
{
    if (n % 2 == 0 && n != 2) return false;

    int m = (int)Math.Ceiling(Math.Sqrt(n));

    for (int i = 3; i < m; i += 2)
    {
        if (n % i == 0) return false;
    }

    return true;
}

1. Cambiar el nombre de las variables.

En primer lugar, si se trata de la tarea obtendrá malas notas (si el maestro es que se precie) porque tiene los nombres de variables sin sentido (sí, incluso numberOfPrimes está mal y debe ser nombrado requiredNumberOfPrimes. Cuando veo esta variable que estoy pidiendo mí mismo '¿Es así como muchos que quiere, o cuántos ha encontrado?').

En segundo lugar, le ayudará a entender a dónde va mal. Las variables deben ser nombrados, lógicamente, de acuerdo con lo que representan. Si no puede explicar lo que sus variables representan (por ejemplo, A y B), entonces probablemente no puede explicar lo que está haciendo con ellos.

2. Mire sus bucles.

for (int x = 0; x < numberOfPrimes; x++)

La estructura de un bucle es (initialise; 'should I continue?'; 'each loop do this'). Por lo tanto, en su bucle

  • Usted está continuando hasta que x es igual o grande que numberOfPrimes *.
  • Cada vez que vaya a través del lazo que está añadiendo 1 a x.

¿Estás seguro de que esto es lo que quiere hacer? x parece representar el número de primos que ha encontrado. ¿Por qué no se incrementará cuando encuentre un número primo, en lugar de cuando se inicia un bucle?

for (int a = 2; a <= x ; ++a)
for (int b = 2; b < a; ++b)

Se busca en cada entero entre 2 y x, ambos inclusive. Y para cada uno de los números enteros a, que busca en cada número entero entre 2 y a inclusive. ¿Qué vas a hacer con estos números enteros?

Cada vez que se recorre el bucle de nivel superior (el bucle x), que se va a iniciar el bucle a desde cero, y cada vez que se recorre el bucle a se iniciará su bucle b desde cero.

Así que si x es 10, se ejecuta a través de una vez (a = 2), entonces se corre a través de un nuevo (a = 2, a = 3), entonces se corre a través de un nuevo (a = 2, a = 3 , a = 4), entonces ...

3. Recoger sus resultados en lugar de escribirlos en consola.

var primes = new List<int>();

Es tan fácil. Cuando encuentre un número primo, primes.Add(a);. Entonces sabe cuántos números primos que haya encontrado (primes.Count), puede utilizar la lista de los números primos para determinar de manera eficiente el próximo primer, y puede utilizar la lista más adelante si es necesario.

Una vez que consigue los bucles ordenados a cabo, sólo tiene que comprobar si b

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top