Factorización de números primos

Hola experto, recurro a ti ya que eres experto en matemáticas y tienes conocimiento en programación. Mi consulta es la siguiente:

Tengo que realizar un pseudocodigo que reciba un número y lo descomponga en factores primos.

Mi solución en pseudocódigo es la siguiente:

Variables:

num1,pr,n1 = enteros

a = cadena

Inicio

Escribir "Ingrese número"

Leer n1

num1 = n1

'busco primos

desde i = 2 hasta i <= 1000 hacer

desde j = 1 hasta 1000 hacer

si i %j =0 And j <> 0 And j <> n1 entonces

salir desde

si no

pr = i

fin si

fin desde

mientras n1 % pr = 0 And n1 >= 0

n1 = n1 / pr

a = a + pr + "*"

fin mientras

fin desde

Escribir a, "= ", num1

Fin

He hecho una prueba mental con el 12 y si no me falla el procedimiento me da:

2*2*3* = 12

Quisiera saber si he fallado en mi comprobación.

Desde ya muchas gracias y disculpa mis molestias!!!

1 Respuesta

Respuesta
1

La verdad es que muy difícil de entender el método que has empleado. El uso de bucles fijos hasta mil es algo excesivo cuando tengamos que descomponer un número pequeño y será insuficiente cuando el número sea grande. Aparte no le encuentro ningún sentido a la condicional

si i %j =0 And j <> 0 And j <> n1

Hay que fijarse como se hace a mano, probamos a dividir por el 2, luego por el 3, el 5, 7, etc. hasta que obtenemos una división exacta. Si la conseguimos dividimos por ese número y repetimos las pruebas.

El final será cuando el divisor sea mayor que la raíz cuadrada del dividendo, ya que si se puede dividir uno de los dos divisores es menor que ella y ya habría salido antes. No obstante esto significa que no hay dos factores primos, pero si el dividendo es mayor que 1 todo el contará como factor primo y se añade al final.

Una optimización es que cuando hallamos una división entera y dividimos no volveremos a empezar con el divisor 2 sino que nos quedaremos en el que estábamos, ya que los factores primos var a ir apareciendo por orden, cuando no se pudo dividir por un divisor una vez ya no se puede volver a dividir en el futuro por el.

Permíteme que la haga todo el programa entero porque hay poco aprovechable y es una mala base de partida.

En las respuestas no dejan poner sangrías, pondré guiones al principio de línea. Precisamente para no tener que hacer muchas sangrías prohibiré que se introduzca el número 1

Variables:

Numero, dividendo, divisor, limite_divisor: enteros

a: Cadena

INICIO

Repetir

__ leer número

Hasta que número > 1

dividendo = numero

Mientras dividendo % 2 = 0

__ a = a + " 2 * "

__ dividendo = dividendo / 2

Fin mientras

Si dividendo > 8

__ divisor = 3

__ limite divisor = raiz_cuadrada(dividendo)

__ Repetir

____ Si dividendo % divisor = 0

______ dividendo = dividendo / divisor

______ limite_divisor = raiz_cuadrada(dividendo)

______ a = a + convertir_en_cadena(divisor) + " * "

____ Si no

______divisor = divisor + 2

____ Fin Si

__ Hasta que divisor > limite divisor

Fin si

Si dividendo > 1 entonces a = a + convertir_en_cadena(dividendo)

Escribir: numero, " = " , a

FIN

Como ya te dije el editor este no permite sangrías, ahora voy a copiar el programa en Lazarus FreePascal con el que he probado el pseudocodigo, pero la sangría no aparecerá. Funciona muy rápido y bien. No pruebes con un número de mas de nueve cifras, a mi se me cuelga el ordenador si lo hago. Habría que hacer gestión de excepciones cuando lees un número que excede la capacidad de los enteros, pero eso excede la simplicidad que queremos del programa.

program FactoresPrimos;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes
{ you can add units after this }, sysutils;
{$R *.res}
var numero, dividendo, divisor, limite_divisor: integer;
a, respuesta: string;
begin
repeat
a:='';
repeat
write ('Escriba el numero mayor que 1: ');
readln(numero);
until (numero>1);
dividendo := numero;
while (dividendo mod 2) = 0 do
begin
dividendo := dividendo div 2;
a := a + '2 * ';
end;
if dividendo>8 then
begin
divisor := 3;
limite_divisor:=trunc(sqrt(dividendo));
repeat
if (dividendo mod divisor) = 0 then
begin
dividendo:=dividendo div divisor;
a := a + inttostr(divisor)+' * ';
limite_divisor := trunc(sqrt(dividendo));
end
else
divisor:=divisor+2;
until divisor > limite_divisor;
end;
if dividendo > 1 then a := a + inttostr(dividendo);
writeln (a);
write ('Otro? (S/N) ');
Readln(respuesta)
until (respuesta = 'N') or (respuesta = 'n');
end.

Y eso es todo.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas