Mie
3
Oct

Algoritmo de corte de control en Programación


Una vez mencioné en un post sobre la defensa del integrador, que había usado un corte de control de doble profundidad. Desde entonces mucha gente ha entrado al blog con el string de búsqueda “Corte de control”. Busqué un poco por Google para ver qué resultados me daba, y la verdad que no encontré una explicación teórica completa y un ejemplo bien práctico que lo explique. Si alguien encontró algo, que me avise en los comentarios.
Así que voy a postear un ejemplo de corte de control de la forma en que nos enseñaron en el curso.
Es un algoritmo que al principio parece confuso, pero una vez que se asimila el concepto y se aprende a usar, resulta muy útil.

Concepto:
El corte de control es una forma ordenada de mostrar información en forma jerárquica. Consta de usar un while anidado dentro del otro. Esto sería un corte de control simple, pero se pueden anidar más while dentro de cada uno para hacer un corte de control de doble, triple, hasta n profundidad.
También se suele usar un acumulador para mostrar información como totales de sumas de ventas, cantidad de visitas, o lo que se esté usando. Recordemos que se usa en lugar de usar comando SQL como COUNT, SUM o AVG.

Para empezar el corte, hay que ver qué datos tenemos, y cómo queremos ordenarlos. Los datos que van a entrar al corte tienen que estar ordenados por una columna. Por ejemplo el Id, de forma alfabética, o por fecha. Después hay que elegir bien la tabla por la que se quiere hacer el corte.

Ejemplo:
Tenemos una tabla (que también puede ser una colección de objetos ordenados mediante un algoritmo de orden) de pedidos y una de productos en nuestra base.
Pedidos - Id, Fecha, Cantidad, IdProducto
Productos - Id, Descripción
Dada una fecha, queremos mostrar lo siguiente:

Id Producto Cantidad
64 Monitor LCD 1
34 Sable Láser 3
146 Halo 3 1.700.000
288 Aparato nuevo 9

Como vemos, los ítems están ordenados por ID. Se dice que el corte se va a hacer sobre el id de producto. La información por ejemplo se podría obtener de un “SELECT * FROM Pedidos WHERE FECHA = laFecha ORDER BY IdProducto”.
Ésta se podría guardar en una colección, lista, o demás estructuras de datos según el lenguaje que estemos usando.

El código está en un lenguaje no específico, pero entendiéndolo, se puede pasar a Java, Visual Basic, C#, etc. Hecho con orientación a objetos, pero no es necesariamente aplicable a este paradigma únicamente.
Intenté hacerlo lo más genérico posible, espero que se entienda, sino cualquier consulta en los comentarios:

coleccion listadoCorte(date pFecha){
	//Declaro lo que voy a usar:
	coleccion auxColeccion;
	String auxSql;
	int contador = 0;
	int IdAnterior = 0;
	int cantidad = 0;
 
	auxSql = "SELECT * FROM Pedidos WHERE Fecha = pFecha ORDER BY IdProducto";
	auxColeccion = obtener(auxSql); //obtenemos los pedidos y los guardamos en auxColeccion
	//la función obtener() obtiene los datos desde la base de datos.
	//su aplicación queda a criterio...
 
	while contador < auxColeccion.rowcount{
		//Es el primer while, vamos a usar una variable "contador" o como la llamo yo "recorredor".
		//Ésta se debe mantener menor a la cantidad de registros,
		//ya que va a recorrer la colección hasta llegar a su fin.
		IdAnterior = auxColeccion.item(contador).IdProducto;
		//Principio del corte
		//Hay que igualar el IdAnterior al Id que se recorre.
		//El IdAnterior va a ser el Id del elemento con
		//índice que se está recorriendo en la colección.
		cantidad = 0;
		//Si tenemos un acumulador, hay que igualarlo a 0 aca.
		//Esto se va a ejecutar una vez por Id
		while contador < auxColeccion.rowcount and IdAnterior = auxColeccion.item(contador).IdProducto{
			//El segundo while. El contador se mantiene menor al total de registros.
			//IdAnterior es lo mismo que el Id de lo que recorro.
			//Cuando esto no sea asi, se sale del while.
 
			//LOGICA
			//Aca es donde hacemos lo que necesitamos con los datos.
			//Por ejemplo sumar la cantidad de items
			cantidad += auxColeccion.item(contador).Cantidad;
			//Suponemos que Cantidad es una propiedad de lo que tenemos en la coleccion.
			//Como se ve, para acceder a un item de la coleccion, usamos como indice el contador.
 
			//Al terminar la logica, sumamos uno al contador:
			contador += 1;
		}
		//Termino el "cuerpo" del corte
		//Ahora tengo que decidir como mostrar la informacion.
		//Instancio un nuevo producto, buscandolo con su Id:
		Producto pProducto = buscarProducto(IdAnterior);
		//El buscarProducto queda a criterio...
 
		Mostrar(IdAnterior, Producto.Nombre, cantidad);
		//la función Mostrar puede guardar los datos en un String y agregarlos a otra colección,
		// o lo que decidan.
	}
}

Espero que haya quedado claro. De todas formas acepto cualquier aporte o crítica para que quede mejor. Ya en comentarios anteriores recibí algunos aportes que vinieron bastante bien para mejorar los posts, así que si considerás que me faltó algo, o podés agregar algo para que quede mejor, bienvenido sea en los comentarios.

Voy a intentar postear ejemplos más adelante de distintas aplicaciones en distintos lenguajes. Si tenés algún código de corte guardado por ahí, y te animás a mostrarlo, podés enviarlo para postearlo acá.


Si te gustó éste post, podés apoyar a PicandoCódigo a través de PayPal!



17 Comentarios para “Algoritmo de corte de control en Programación”

  1. nobody



    Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.7) Gecko/20070914 Firefox/2.0.0.7

    Puede ser que esté malinterpretando tu ejemplo, pero ¿Qué diferencia existe entre el “corte de control” y un simple INNER JOIN?

    Me parece que lo estás mostrando se podría hacer perfectamente en SQL así:

    sql = “select prod.id, prod.descripcion, sum(ped.cantidad) cantidad
    from productos prod
    inner join pedidos ped on ped.IdProducto = prod.Id
    where ped.fecha = @fecha
    group by prod.id, prod.descripcion”

    foreach (fila in obtener(sql)) {
    Mostrar(fila["id"], fila["descripcion"], fila["cantidad"])
    }

    Con éste método se estarían ejecutando una petición y se regresarían las cuatro filas que mostraste más arriba.

    Con tu ejemplo se se traen todas las filas de la tabla pedidos de esa fecha (que en el caso de Halo 3 parece que son muchas) y una petición extra por cada producto.

    ¿En qué caso se debe usar tu método en vez del INNER JOIN? (Aparte de cuando no se dispone de una BDD SQL, claro está).

    Gracias.

  2. fernando



    Mozilla/5.0 (Windows; U; Windows NT 5.1; es-AR; rv:1.8.1.7) Gecko/20070914 Firefox/2.0.0.7

    “nobody”:
    El corte de control es un algoritmo que se enseña generalmente en los cursos de programación. Obviamente los listados se pueden solucionar con un query SQL, pero la gracia es que sirve cuando no es así.
    No siempre en los desarrollos vamos a tener un motor de base de datos SQL que nos permita usar sus comandos.
    Además, el SQL del post es como ejemplo, pero la colección podría levantar datos de un archivo plano, o simplemente datos que guarda en memoria y después serializa.
    Como programador tenés que estar preparado para muchas situaciones, y no asumir que si algo se puede hacer con SQL u otra tecnología “nueva”, siempre vas a tenerlo a disposición.
    Gracias por leer!
    Saludos

  3. nobody



    Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.7) Gecko/20070914 Firefox/2.0.0.7

    Ok. Entiendo entonces que si dispongo de una BDD SQL debería usar el INNER JOIN/GROUP BY y solo usar “corte de control” en caso contrario.

    Gracias por la aclaración.

  4. fernando



    Mozilla/5.0 (Windows; U; Windows NT 5.1; es-AR; rv:1.8.1.7) Gecko/20070914 Firefox/2.0.0.7

    Sí, si dispones de un motor SQL, va a ser más rápido y eficiente usar los query con JOIN/GROUP BY y demás.
    Saludos

  5. Meli



    Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2)

    cortes de control en lenguaje SL..???
    HELP ME PLEASE!

  6. fernando



    Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.6) Gecko/20070725 Firefox/2.0.0.6

    Meli:
    No conocía el lenguaje SL. Al ver tu comentario salí a buscarlo por internet, y lo estoy conociendo en este momento.
    Por lo que veo, es un lenguaje realizado en Paraguay y usado en universidades y lugares de estudio como lenguaje de introducción a la programación. Encontré que en ésta página: http://www.cnc.una.py/sl/SL-stdf.html hay una referencia del lenguaje. No sé cómo es bien la sintaxis, pero fijate que auxCol es una colección, pero puede ser una lista, o cualquier estructura de datos ordenada que uses. Ésta estructura a su vez guarda otras estructuras u objetos que debe tener un “Id”, u otro dato único y ordenado por el cual te permita recorrer uno a uno los elementos de la colección (Pedidos). Luego por cada pedido, vas a buscar el producto con un “buscarProducto” que dejé genérico.
    Deberías buscar en el link que te dí con las funciones de SL las equivalentes en dicho lenguaje para hacer el corte.
    Te recomiendo que primero intentes entender el concepto en sí de lo que hace el corte, que después conociendo el lenguaje es mas fácil implementarlo.
    Espero que te haya ayudado, sino vuelve a preguntar que intento de nuevo.
    Saludos y gracias por visitar

  7. meli



    Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.2)

    gracias!!!!! ya comprendi por eso pase al sgte semestre jeje…ahora estamos introduciendonos en visual fox…en cualquier momento seguro estare por aqui con alguna pregunta!

    gracias!!:)

  8. fernando



    Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.12) Gecko/20080217 IceCat/2.0.0.12-g1

    meli:
    Me alegro mucho que te haya servido. Felicitaciones por haber salvado el semestre.
    Cualquier consulta, acá estamos!

    Saludos

  9. Cesar



    Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_4_11; es) AppleWebKit/525.13 (KHTML, like Gecko) Version/3.1 Safari/525.13

    Creo que con respecto a la consulta de “nobody”, es algo incompleta la respuesta porque a veces tienes una base de datos y necesitas un corte de control, usualmente pasa cuando haces reportes, por ejemplo si necesitas mostrar un reporte en una página web necesitas los cortes de control para poder escribir los encabezados de cada grupo.

  10. fernando



    Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.12) Gecko/20080217 IceCat/2.0.0.12-g1

    Cesar:
    Es verdad, que en algunos casos se puede usar un corte de control sobre una base de datos, pero siempre es mejor resolverlo dentro de la consulta SQL, porque va a ser más rápido y eficiente.
    Pero en el caso concreto que mencionas, puede ser útil también.
    Lo bueno de programar es que hay varias formas distintas de resolver lo mismo :)

    Saludos y gracias por comentar

  11. david



    Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; InfoPath.2; .NET CLR 2.0.50727)

    queria saber si no me podes enviar al mail o como comentario en esta pagina, un ejemplo de corte de control en lenguaje c borland. al igual que vos estube buscando en google y no encontre practicamente nada. rindo un examen el martes 03/06/08 para entrar a un trabajo y tengo que hacer un algoritmo de corte de control. desde ya muchas gracias y si yo no tengo que dar esto en sql sino en c se complica

  12. fernando



    Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.13) Gecko/20080409 IceCat/2.0.0.13-g1

    david:
    El código es bastante genérico, en el caso de C lo que tendrías que cambiar es el auxColeccion por una estructura de datos que puedas ir recorriendo con un índice (un array, o similar).
    Estaba pensando repasar éste concepto nuevamente, orientado a algún lenguaje estructurado como C. Probablemente lo haga más adelante.
    Mucha suerte en tu examen!

    Saludos

  13. Michel



    Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)

    me salvastes la vida, gracias!

Trackbacks

  1. programame.net
  2. Algoritmos: Corte de Control - Noticias externas
  3. » Primera clase de Sistemas Operativos como “profesor” - Picando Código
  4. programame.net

Dejar un comentario

Si quieres mostrar código, enciérralo entre los tags pre de esta forma:
<pre lang="L"> y </pre>, donde L es un lenguaje compatible GeSHI. Más info.

XHTML: Las siguientes tags están permitidas: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="">


Al agregar un comentario en esta página, usted acepta la siguiente licencia para su publicación:
Creative Commons License Creative Commons Attribution-Share Alike 3.0 Unported License.