//
import java.util.PriorityQueue;
import java.util.Scanner;
public class AnalisisDeAlgoritmos1 {
static Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
try
{
long n = forceReadPositiveLong();
showDivisorsData(n);
showDivisorsData_REFACTORED(n);
showDivisorsData_ORDERED(n);
}
catch (Exception e) {
System.out.println("Error al realizar los cálculos, probablemente se necesite ¡BigInteger! para este número.");
}
}
static long forceReadPositiveLong()
{
long n = 0;
while(true)
{
try
{
System.out.print("Introduzca el valor de N: ");
n = Long.parseLong(scanner.nextLine());
if(n <= 0 )
{
System.out.println("El valor de N debe ser positivo.");
continue;
}
return n;
}
catch(Exception ex)
{
System.out.println("Se introdujo un número inválido, reintente.");
}
}
}
//region Retroalimentación
/*
showDivisorsData es una excelente solución al enunciado planteado
Determinar cuáles y cuántos son los divisores de un número positivo (validado)
ingresado por el usuario.
Calcular el promedio de los divisores.
Utiliza una estructura de datos PriorityQueue
es una colección ordenada de elementos almacenados en forma de secuencia (lista)
permite agregar elementos manteniendo el orden y extraer el menor de los elementos
La complejidad de PriorityQueue en la operación agregar es O(log(n))
al incluir esa operación en un ciclo, la complejidad del médoto es O(nlog(n))
Muestra los divisores de menor a mayor
Trata de ser eficiente, analiza los valores hasta sqrt(n)
*/
//endregion
static void showDivisorsData(long n)
{
long startTime = System.currentTimeMillis();
float sumDiv = 0;
PriorityQueue<Long> divisors = new PriorityQueue<Long>();
for(long i = 1; i*i <= n; i++)
{
if(n%i == 0)
{
divisors.add(i);
sumDiv+= i;
if(i*i == n) {
continue;
}
divisors.add(n/i);
sumDiv+=(n/i);
}
}
System.out.println("Cantidad.: "+ divisors.size());
System.out.println("Promedio.: "+ sumDiv/divisors.size());
System.out.print("Divisores: [");
while(!divisors.isEmpty())
{
System.out.print(divisors.remove() + ((divisors.isEmpty() ? "]\n" : ",")));
}
long elapsedTime = System.currentTimeMillis() - startTime;
System.out.println("Ejecución: " + elapsedTime + " milisegundos");
}
//region Retroalimentación
/*
showDivisorsData_REFACTORED es otra solución al enunciado planteado
Determinar cuáles y cuántos son los divisores de un número positivo (validado)
ingresado por el usuario.
Calcular el promedio de los divisores.
Se implementa un ciclo, de manera que la complejidad del método es O(n)
Muestra los elementos en el orden en que los encuentra
Trata de ser eficiente, analiza los valores hasta sqrt(n)
La salida es desordenada
*/
//endregion
static void showDivisorsData_REFACTORED(long n)
{
long startTime = System.currentTimeMillis();
float sumDiv = 1L;
int countDiv = 1;
System.out.print("\n\nDivisores: [1");
if (n > 1L) {
for (long i = 2; i*i <= n; i++) {
if (n % i == 0) {
sumDiv += i;
countDiv++;
System.out.print("," + i);
if(i*i == n) {
continue;
}
sumDiv += n/i;
countDiv++;
System.out.print("," + n/i);
}
}
sumDiv += n;
countDiv++;
System.out.print("," + n +"]\n");
}
System.out.println("Cantidad.: " + countDiv);
System.out.println("Promedio.: "+ sumDiv/countDiv);
long elapsedTime = System.currentTimeMillis() - startTime;
System.out.println("Ejecución: " + elapsedTime + " milisegundos");
}
//region Retroalimentación
/*
showDivisorsData_ORDERED es otra solución al enunciado planteado
Determinar cuáles y cuántos son los divisores de un número positivo (validado)
ingresado por el usuario.
Calcular el promedio de los divisores.
Se implementa un ciclo, de manera que la complejidad del método es O(n)
La salida es ordenada
*/
//endregion
static void showDivisorsData_ORDERED(long n)
{
long startTime = System.currentTimeMillis();
float sumDiv = 1L;
int countDiv = 1;
System.out.print("\n\nDivisores: [1");
if (n > 1L) {
for (long i = 2; i < n; i++) {
if (n % i == 0) {
sumDiv += i;
countDiv++;
System.out.print("," + i);
}
}
sumDiv += n;
countDiv++;
System.out.print("," + n +"]\n");
}
System.out.println("Cantidad.: " + countDiv);
System.out.println("Promedio.: "+ sumDiv/countDiv);
long elapsedTime = System.currentTimeMillis() - startTime;
System.out.println("Ejecución: " + elapsedTime + " milisegundos");
}
}
Comments