Solución a la práctica de Algoritmos I – Grupo A

Estándar

La práctica tomada por el profesor el día de hoy nos sorprendió un poco con el tiempo dado para resolverla. Aún así, logré ver que la mayoría logró resolverla en una escala media.

El trabajo que ahora tenemos consta en desarrollar la práctica. Y como es una oportunidad para mejorar lo que hicimos durante el tiempo dado, pues aquí expongo la mejora de mi código (el que hice en clase me lo reservo).

Codificación

public class Fraccion {
    
    private int num;
    private int den;
    
    /**
     * Crea una nueva Fraccion.
     */
    public Fraccion() {
        num = 0;
        den = 1;
    }
    
    /**
     * Copia la Fraccion en f a esta Fraccion.
     * @param f Fraccion a copiar
     */
    public Fraccion(Fraccion f) {
        num = f.num;
        den = f.den;
    }
    
    /**
     * Inicializa los valores de esta Fraccion.
     * @param num numerador
     * @param den denominador
     */
    public Fraccion(int num, int den) {
        this.num = num;
        this.den = den;
    }
    
    /**
     * Obtiene el numerador de esta Fraccion.
     * @return numerador
     */
    public int getNum() {
        return num;
    }
    
    /**
     * Obtiene el denominador de esta Fraccion.
     * @return denominador
     */
    public int getDen() {
        return den;
    }
    
    /**
     * Asigna el numerador de esta Fraccion.
     * @param num numerador a asignar
     */
    public void setNum(int num) {
        this.num = num;
    }
    
    /**
     * Asigna el denominador de esta Fraccion.
     * @param den denominador a asignar
     */
    public void setDen(int den) {
        this.den = den;
    }
    
    /**
     * Suma dos Fracciones.
     * @param f segunda Fraccion a sumar
     * @return Fraccion suma
     */
    public Fraccion sumar(Fraccion f) {
        return new Fraccion(num * f.den + f.num * den, den * f.den);
    }
    
    /**
     * Multiplica dos Fracciones.
     * @param f segunda Fraccion a multiplicar
     * @return Fraccion producto
     */
    public Fraccion multiplicar(Fraccion f) {
        return new Fraccion(num * f.num, den * f.den);
    }
    
    /**
     * Simplifica una Fraccion.
     * @return Fraccion simplificada
     */
    public Fraccion simplificar() {
        int n = num;
        int d = den;
        int res;
        // Calculamos el MCD
        while (d != 0) {
            res = n % d;
            n = d;
            d = res;
        }
        return new Fraccion(num / n, den / n);
    }
    
    /**
     * Compara fracciones.
     * @param f Fraccion a comparar
     * @return true si esta Fraccion es mayor a f.
     */
    public boolean esMayor(Fraccion f) {
        if (num * f.den > f.num * den) {
            return true;
        }
        return false;
    }
    
    /**
     * Devuelve la Fraccion como cadena.
     * @return Fraccion como String
     */
    public String toString() {
        return num + "/" + den;
    }
    
}
import java.util.Random;
import java.util.Scanner;

public class PruebaFraccion {
    
    private static void generar(Fraccion[] v) {
        Random r = new Random();
        for (int i = 0; i < v.length; i++) {
            int num = r.nextInt(10);
            int den = r.nextInt(10);
            // El denominador no puede ser 0
            while (den == 0) {
                den = r.nextInt(10);
            }
            v[i] = new Fraccion(num, den);
        }
    }
    
    private static void mostrar(Fraccion[] v) {
        System.out.println();
        for (int i = 0; i < v.length; i++) {
            // No es necesario llamar a toString()
            // pues lo llama de manera automatica
            System.out.println(v[i]);
        }
        System.out.println();
    }
    
    private static Fraccion mayor(Fraccion[] v) {
        Fraccion mayor = new Fraccion(v[0]);
        // i = 1 porque ya asignamos arriba
        // la fraccion mayor a 0
        for (int i = 1; i < v.length; i++) {
            if (v[i].esMayor(mayor)) {
                mayor = new Fraccion(v[i]);
            }
        }
        return mayor;
    }
    
    private static Fraccion suma(Fraccion[] v) {
        Fraccion suma = new Fraccion(v[0]);
        // i = 1 tambien
        for (int i = 1; i < v.length; i++) {
            suma = suma.sumar(v[i]);
        }
        return suma;
    }
    
    private static Fraccion producto(Fraccion[] v) {
        Fraccion producto = new Fraccion(v[0]);
        // i = 1 tambien
        for (int i = 1; i < v.length; i++) {
            producto = producto.multiplicar(v[i]);
        }
        return producto;
    }
    
    public static void main(String[] args) {
        
        Scanner sc = new Scanner(System.in);
        
        System.out.print("Numero de elementos: ");
        int n = sc.nextInt();
        sc.close();
        
        Fraccion[] v = new Fraccion[n];
        
        generar(v);
        mostrar(v);
        
        // Tener en cuenta que el toString()
        // ya no debe ser llamado porque Java
        // automaticamente sabe llamarlo
        System.out.println("Fraccion mayor: " + mayor(v));
        System.out.println("Suma: " + suma(v).simplificar());
        System.out.println("Producto: " + producto(v).simplificar());
        
    }
    
}

Espero sus comentarios, observaciones, y otros 🙂

Anuncios

compareTo en JavaScript

Estándar

Todos alguna vez hemos estudiado los métodos de ordenamiento, si hemos visto lenguajes de programación. Y, los que lo hemos visto, nos podremos dar cuenta que no son difíciles de entender y aprender, siempre y cuando no nos den datos del tipo String. Esos sí que son problemáticos en su totalidad. Pues, uno al comparar dos números, puede establecer una relación de orden fácilmente. Ahora, aplica eso en una cadena. Puedes obtener el código ASCII del primer carácter, pero si te muestro “ANALGÉSICO” y “ANALÓGICO”, ¿qué haces?

Pensando en esto, es que decidí ver el código fuente de la clase String de Java, viendo cómo trabaja el compareTo. La verdad en un momento pensé que sería algo grande, y lo fue. Creo que se declaran variables hasta por las puras. Menos mal que en JavaScript no es necesario convertir un String a char[], sino de una sola usando String.charAt().

Entonces, aquí presento el código del prototipo “compareTo” de String, codificado en JavaScript:


String.prototype.compareTo = function( cadena ) {
  cadena += "";
  var l1 = this.length,
  l2 = cadena.length,
  limite = Math.min( l1, l2 ),
  k = 0,
  c1,
  c2;
  while ( k < limite ) {
    c1 = this[ k ];
    c2 = cadena[ k ];
    if ( c1 !== c2 ) {
      return c1.charCodeAt( 0 ) - c2.charCodeAt( 0 );
    }
    k++;
  }
  return l1 - l2;
};

Histograma en Java

Estándar

Tras haber visto varios artículos por Internet, vi algunos interesantes acerca de cómo generar un histograma con asteriscos en Java.

La verdad me decepcioné demasiado al saber que no saben ni siquiera pensar para subir algún contenido. Sólo suben lo que piensan con un título sugestivo para así poder ganar un poco de dinero con las visitas en su blog. Parece que yo, sin ganar dinero, publico contenido de calidad antes que eso, que lo único que nos hace perder a la mayoría de estudiantes es tiempo.

En este artículo muestro el código de un programa que me pidieron en la Universidad, para generar un histograma básico mediante el ingreso y tratamiento de vectores.

Aquí expongo el código:

package vectores; // El paquete que estoy usando

import java.util.Scanner; // Para el ingreso de datos

public class Histograma {
	
	public static void generarV(int[] v) { // Generamos un vector
		for (int i = 0; i < v.length; i++) {
			v[i] = (int) (Math.random() * 101);
		}
	}
	
	public static void histogramaV(int[] v) { // Hace el histograma
		int[] rep = new int[v.length]; // Repeticiones
		for (int i = 0; i < v.length; i++) {
			int ca = 0; // Cantidad (frecuencia)
			for (int j = 0; j < v.length; j++) {
				if (v[i] == v[j]) {
					ca++;
				}
			}
			if (rep[i] == 0) { // Si aún no se ha repetido
				System.out.print(v[i] + ": ");
				for (int k = 0; k < ca; k++) {
					System.out.print("*"); // Un '*' por cada punto frecuencial
				}
				System.out.println();
			}
			for (int j = 0; j < v.length; j++) {
				if (v[i] == v[j]) {
					rep[j]++; // Si ya está visto esta parte
				}
			}
		}
	}
	
	public static void main(String[] args) {
		
		Scanner sc = new Scanner(System.in); // Creamos el ingreso de datos
		
		System.out.print("Cantidad de elementos: ");
		int n = sc.nextInt(); // Almacenamos cantidad de elementos

		int[] v = new int[n]; // Creamos el vector

		generarV(v); // Lo generamos
		
		histogramaV(v); // Mostramos el histograma
		
	}
	
}

Sé que al código le falta optimizar ciertos aspectos. Aquel que logre esto, puede publicarlo en los comentarios. Así contribuiría con todos los lectores 🙂
Por cierto, puedes descargar el código desde aquí (me brindas unos cuantos céntimos al hacer clic).