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!

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

  1. nobody a las 3:21 am 7 Octubre. 2007
    Firefox 2.0.0.7Windows XP
    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 a las 5:11 pm 7 Octubre. 2007
    Firefox 2.0.0.7Windows XP
    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 a las 5:29 pm 7 Octubre. 2007
    Firefox 2.0.0.7Windows XP
    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 a las 6:00 pm 7 Octubre. 2007
    Firefox 2.0.0.7Windows XP
    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 a las 8:06 pm 28 Noviembre. 2007
    Internet Explorer 6.0Windows XP
    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 a las 11:55 pm 28 Noviembre. 2007
    Firefox 2.0.0.6GNU/Linux
    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 a las 11:51 pm 12 Marzo. 2008
    Internet Explorer 6.0Windows XP
    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 a las 11:15 am 13 Marzo. 2008
    GNU IceCat 2.0.0.12GNU/Linux
    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 a las 4:32 pm 29 Marzo. 2008
    Safari 525.13Mac OS
    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 a las 11:42 pm 29 Marzo. 2008
    GNU IceCat 2.0.0.12GNU/Linux
    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 a las 6:08 pm 1 Junio. 2008
    Internet Explorer 7.0Windows XP
    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 a las 2:16 am 2 Junio. 2008
    GNU IceCat 2.0.0.13GNU/Linux
    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 a las 12:04 am 13 Octubre. 2008
    Internet Explorer 7.0Windows XP
    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!

  14. hola a las 9:53 pm 19 Noviembre. 2008
    Internet Explorer 7.0Windows XP
    Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; GTB5; InfoPath.2; .NET CLR 1.1.4322)

    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

  15. fernando a las 12:25 am 21 Noviembre. 2008
    GNU IceCat 3.0.3Debian GNU/Linux
    Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.3) Gecko/2008092921 IceCat/3.0.3-g1 Debian GNU/Linux

    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

  16. flore a las 11:24 am 11 Diciembre. 2008
    Firefox 3.0.1Windows XP
    Mozilla/5.0 (Windows; U; Windows NT 5.1; es-ES; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1

    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

  17. fernando a las 11:43 am 11 Diciembre. 2008
    GNU IceCat 3.0.3Kubuntu
    Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.3) Gecko/2008092921 IceCat/3.0.3-g1 Kubuntu

    Florencia:
    Voy a investigar para expresarlo en diagramas de Jackson. Intento publicarlo en estos días, a ver si te sirve para el recuperatorio.

    ¡Saludos!

  18. Flor a las 11:13 am 15 Diciembre. 2008
    Firefox 3.0.1Windows XP
    Mozilla/5.0 (Windows; U; Windows NT 5.1; es-ES; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1

    se complico Fernando no?

  19. Flor a las 12:01 pm 15 Diciembre. 2008
    Firefox 3.0.1Windows XP
    Mozilla/5.0 (Windows; U; Windows NT 5.1; es-ES; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1

    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

  20. fernando a las 12:38 pm 15 Diciembre. 2008
    GNU IceCat 3.0.3Kubuntu
    Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.3) Gecko/2008092921 IceCat/3.0.3-g1 Kubuntu

    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!

Trackbacks y pingbacks:

  1. 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. [...] 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. [...] 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. 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

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.




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="" escaped="">


Additional comments powered by BackType

Búsqueda personalizada