Algoritmo de corte de control en Programación

Publicado el Miércoles, 3 de octubre de 2007

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á.

32 comentarios en este post

Feed de comentarios
  1. Avatar

    nobody 7 octubre. 2007 - 03:21

    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. Avatar

    fernando 7 octubre. 2007 - 17:11

    “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.
    Hay 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. Avatar

    nobody 7 octubre. 2007 - 17:29

    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. Avatar

    fernando 28 noviembre. 2007 - 23:55

    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

  5. Avatar

    meli 12 marzo. 2008 - 23:51

    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!!:)

  6. Avatar

    fernando 13 marzo. 2008 - 11:15

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

    Saludos

  7. Avatar

    Cesar 29 marzo. 2008 - 16:32

    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.

  8. Avatar

    fernando 29 marzo. 2008 - 23:42

    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

  9. Avatar

    david 1 junio. 2008 - 18:08

    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

  10. Avatar

    fernando 2 junio. 2008 - 02:16

    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

  11. Avatar

    hola 19 noviembre. 2008 - 21:53

    hola, quisiera saber si tienen este codigo o por lo menos las varibles

    leer cierta cantidad de dia e imprimir su equivalente en segundo.

    por favor si saben como hacerlo por favor me pasan algo por mi email

  12. Avatar

    fernando 21 noviembre. 2008 - 00:25

    hola:
    Si entendí bien tu pregunta, ¡el código es demasiado sencillo!

    Deberías plantearte bien el problema, calcular cuántos segundos hay por día, y devolver ese valor multiplicado por la cantidad de días que recibas.

    Si necesitas más ayuda, visita el foro.

    Saludos

  13. Avatar

    flore 11 diciembre. 2008 - 11:24

    como estas fernando?

    Necesito si por casualidad tenes ejemplos de corte de control pero en diagrama de jackson!, es esto posible?
    Tengo recuperatorio la semana que viene y no quiero recursar 🙁
    Muchas gracias, estoy al tanto..
    PD:tambien de archivos indexados, pero me urge corte d control
    Gracias nuevamente

  14. Avatar

    Flor 15 diciembre. 2008 - 12:01

    te dejo un ejemplo, perdona las molestias

    Un parque de diversiones trabaja desde las 09hs hasta las 24 hs todos los días de la semana y tiene los siguientes archivos para realizar sus controles

    Ticket utilizados, secuencial ordenado por juego, DIA de la semana, hora de ingreso
    Cada ticket es un cliente

    juego|Dia de la semana|Hora de ingreso

    Empleados, indexado por empleado

    Empleado| Hora in|Hora out|categoría

    Horas trabajadas, indexado por juego + empleado + hora in , un empleado puede estar en varios juegos , no necesariamente siempre en uno solo cada dia

    Juego|empleado|Hora in| Hora out

    Categoría, indexado por categorías

    Categoría|sueldo

    Precios, indexado por juego + DIA de la semana

    Juego|DIA de la semana|valor

    Se desea saber

    1.Recaudación total del parque
    2.Que dia de la semana se reciben mas visitantes
    3.Cada empleado , en que juego estuvo mas tiempo

    Ese es el desafio…
    gracias de todas maneras por la ayuda.
    beso

  15. Avatar

    fernando 15 diciembre. 2008 - 12:38

    Flor:
    Este fin de semana estuve sin conexión a internet en mi casa. Hace días que viene así, supuestamente están arreglando no sé qué en Anteldata.

    Postié tu pregunta en el foro, a forma de desafío, a ver si alguien más se prende ayudar.

    Saludos!

  16. Avatar

    alvarodoune 7 mayo. 2010 - 17:27

    hola, estoy estudiando analista programador y tengo poca experiencia, agradezco alguien me pueda ayudar con este corte de control, tengo la tabla movimientos con:
    Codigo:Integer
    NombreArticulo: String
    Cantidad: Double
    Fecha: Date
    Supermercado_Nombre: String
    Articulo_Codigo: Integer

    y quisiera listar:

    * los movimientos a un determinado supermercado
    *todos los movimientos para una fecha dada

    desde ya muchas gracias… mi mail es alvarodoune@hotmail.com

  17. Avatar

    nicolas 30 diciembre. 2010 - 12:00

    hola, tengo que listar una informacion sobre una biblioteca, tengo que hacer un corte de control por rubro de libro. y no hay forma que me salga. si me podria ayudar te lo agradesco

    • Avatar

      Fernando 4 abril. 2011 - 20:57

      No realmente, nunca use Cobol.

      Lo importante es que entiendas la lógica de este ejemplo y luego escribirlo en Cobol. De esta manera, podrías implementarlo en cualquier lenguaje y para cualquier caso que aplique.

      ¡Saludos!

  18. Avatar

    matias 3 diciembre. 2011 - 20:26

    podrias dar el mismo ejemplo en php, yo estoy tratando de hacer un ejercicio de corte de control muy parecido al del ejemplo y no puedo entenderlo bien. gracias

  19. Avatar

    emegeve 23 abril. 2012 - 10:49

    Si por casualidad alguien necesita información sobre los cortes de control pero en inglés, puede buscar sobre control break, que es el nombre del algoritmo en dicho lenguaje.

  1. programame.net | 4 octubre. 2007 - 13:22

    Algoritmos: Corte de Control

    El corte de control es un algoritmo que al principio parece confuso, pero una vez que se asimila el concepto y se aprende a usar, resulta muy útil. Es una forma ordenada de mostrar información en forma jerárquica y consta de usar whiles anidados. A …

  2. Algoritmos: Corte de Control - Noticias externas | 6 octubre. 2007 - 06:03

    […] El corte de control es un algoritmo que al principio parece confuso, pero una vez que se asimila el concepto y se aprende a usar, resulta muy útil. Es una forma ordenada de mostrar información en forma jerárquica y consta de usar whiles anidados. A continuación un ejemplo de corte de control de la forma en que nos enseñaron en el curso:» noticia original […]

  3. » Primera clase de Sistemas Operativos como “profesor” - Picando Código | 27 marzo. 2008 - 17:18

    […] cómo me fue en clase. Por cierto, algunos de los alumnos ya han andado por acá, el post de “Corte de Control” realmente sirvió para […]

  4. programame.net | 4 junio. 2008 - 03:33

    Corte de control en Programación – Algoritmo…

    El corte de control es un algoritmo que al principio parece confuso, pero una vez que se asimila el concepto y se aprende a usar, resulta muy útil. Es una forma ordenada de mostrar información en forma jerárquica y consta de usar whiles anidados. A …

Dejar un comentario

Toasty!