Programacion Logica

170
Materia: Programación Lógica Profesor: Ing. Silvia Carrera - 1 - Lectura 1: Algoritmos introducción Unidad 1: Algoritmos introducción 1.1 Sistemas de procesamiento de la información Un lenguaje de programación es un idioma artificial diseñado para ser usado en las computadoras. Pueden usarse para crear programas que controlen el comportamiento físico y lógico de una máquina, para expresar algoritmos con precisión, o como modo de comunicación humana. Está formado de un conjunto de símbolos y reglas sintácticas y semánticas que definen su estructura y el significado de sus elementos y expresiones. Existe un error común que trata por sinónimos los términos: lenguaje de programación y lenguaje informático. Los lenguajes informáticos engloban a los lenguajes de programación y a otros más, como por ejemplo el HTML (lenguaje para páginas web que no es propiamente un lenguaje de programación sino un conjunto de instrucciones que permiten diseñar el contenido y el texto de los documentos). Permite especificar de manera precisa sobre qué datos debe operar una computadora, cómo deben ser almacenados o transmitidos y qué acciones debe tomar bajo una variada gama de circunstancias. Todo esto, a través de un lenguaje que intenta estar relativamente próximo al lenguaje humano o natural. Una característica relevante de los lenguajes de programación es precisamente que más de un programador puedan tener un conjunto común de instrucciones que puedan ser comprendidas entre ellos para realizar la construcción del programa de forma colaborativa. Los procesadores usados en las computadoras entienden únicamente instrucciones en lenguaje máquina (combinación de ceros y unos). Todo programa escrito en otro lenguaje puede ser ejecutado de dos maneras: Mediante un programa que va adaptando las instrucciones conforme son encontradas. A este proceso se lo llama interpretar y a los programas que lo hacen se los conoce como intérpretes. Ejemplos de esto son bash, clásico interprete en estaciones unix que fue escrito para el proyecto GNU o Python. Traduciendo el código escrito del lenguaje (código fuente), a su equivalente en lenguaje máquina. A este proceso se le llama compilar y al programa traductor se le denomina compilador. Ejemplos de esto son: El lenguaje C, que combina características de medio y bajo nivel y el compilador gcc usado en el proyecto GNU. La necesidad de recordar secuencias de programación para las acciones usuales llevó a denominarlas con nombres fáciles de memorizar y asociar: ADD (sumar), SUB (restar), MUL

description

Programacion Logica

Transcript of Programacion Logica

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 1 -

Lectura 1: Algoritmos introducción

Unidad 1: Algoritmos introducción

1.1 Sistemas de procesamiento de la información

Un lenguaje de programación es un idioma artificial diseñado para ser usado en las computadoras. Pueden usarse para crear programas que controlen el comportamiento físico y lógico de una máquina, para expresar algoritmos con precisión, o como modo de comunicación humana. Está formado de un conjunto de símbolos y reglas sintácticas y semánticas que definen su estructura y el significado de sus elementos y expresiones.

Existe un error común que trata por sinónimos los términos: lenguaje de programación y lenguaje informático. Los lenguajes informáticos engloban a los lenguajes de programación y a otros más, como por ejemplo el HTML (lenguaje para páginas web que no es propiamente un lenguaje de programación sino un conjunto de instrucciones que permiten diseñar el contenido y el texto de los documentos).

Permite especificar de manera precisa sobre qué datos debe operar una computadora, cómo deben ser almacenados o transmitidos y qué acciones debe tomar bajo una variada gama de circunstancias. Todo esto, a través de un lenguaje que intenta estar relativamente próximo al lenguaje humano o natural. Una característica relevante de los lenguajes de programación es precisamente que más de un programador puedan tener un conjunto común de instrucciones que puedan ser comprendidas entre ellos para realizar la construcción del programa de forma colaborativa.

Los procesadores usados en las computadoras entienden únicamente instrucciones en lenguaje máquina (combinación de ceros y unos). Todo programa escrito en otro lenguaje puede ser ejecutado de dos maneras:

Mediante un programa que va adaptando las instrucciones conforme son encontradas. A este proceso se lo llama interpretar y a los programas que lo hacen se los conoce como intérpretes. Ejemplos de esto son bash, clásico interprete en estaciones unix que fue escrito para el proyecto GNU o Python.

Traduciendo el código escrito del lenguaje (código fuente), a su equivalente en lenguaje máquina. A este proceso se le llama compilar y al programa traductor se le denomina compilador. Ejemplos de esto son: El lenguaje C, que combina características de medio y bajo nivel y el compilador gcc usado en el proyecto GNU.

La necesidad de recordar secuencias de programación para las acciones usuales llevó a denominarlas con nombres fáciles de memorizar y asociar: ADD (sumar), SUB (restar), MUL

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 2 -

(multiplicar), CALL (ejecutar subrutina), etc. A esta secuencia de posiciones se le denominó "instrucciones", y a este conjunto de instrucciones se le llamó lenguaje ensamblador.

Posteriormente aparecieron diferentes lenguajes de programación, los cuales reciben su denominación porque tienen una estructura sintáctica similar a los lenguajes escritos por los humanos.

Los lenguajes de programación se pueden clasificar atendiendo a varios criterios:

Según el nivel de abstracción Según el paradigma de programación que poseen cada uno de ellos

Según su nivel de abstracción:

Lenguajes de Máquina

Están escritos en lenguajes directamente legibles por la máquina (computadora), ya que sus instrucciones son cadenas binarias (0 y 1). Da la posibilidad de cargar (transferir un programa a la memoria) sin necesidad de traducción posterior lo que supone una velocidad de ejecución superior, solo que con poca fiabilidad y dificultad de verificar y poner a punto los programas.

Lenguajes de bajo nivel

Los lenguajes de bajo nivel son lenguajes de programación que se acercan al funcionamiento de una computadora. El lenguaje de más bajo nivel por excelencia es el código máquina. A éste le sigue el lenguaje ensamblador, ya que al programar en ensamblador se trabajan con los registros de memoria de la computadora de forma directa. Ejemplo en lenguaje ensamblador intel x86.

Lenguajes de medio nivel

Hay lenguajes de programación que son considerados por algunos expertos como lenguajes de medio nivel (lenguaje C) al tener ciertas características que los acercan a los lenguajes de bajo nivel pero teniendo, al mismo tiempo, ciertas cualidades que lo hacen un lenguaje más cercano al humano y, por tanto, de alto nivel.

Lenguajes de alto nivel

Los lenguajes de alto nivel son normalmente fáciles de aprender porque están formados por elementos de lenguajes naturales, como el inglés. En BASIC, uno de los lenguajes de alto nivel más conocidos, los comandos como "IF CONTADOR = 10 THEN STOP" pueden utilizarse para pedir a la computadora que pare si el CONTADOR es igual a 10. Esta forma de trabajar puede dar la sensación de que las computadoras parecen comprender un lenguaje natural; en realidad lo hacen de una forma rígida y sistemática, sin que haya cabida, por ejemplo, para ambigüedades o dobles sentidos.

Según el paradigma de programación:

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 3 -

Un paradigma de programación representa un enfoque particular o filosofía para la construcción del software. No es mejor uno que otro, sino que cada uno tiene ventajas y desventajas. Dependiendo de la situación un paradigma resulta más apropiado que otro.

Atendiendo al paradigma de programación, se pueden clasificar los lenguajes en:

El paradigma imperativo es considerado el más común y está representado, por ejemplo, por el C o por BASIC.

El paradigma funcional está representado por la familia de lenguajes LIPS (en particular Schema), ML o Haskell.

El paradigma lógico, un ejemplo es PROLOG. El paradigma orientado a objetos. Un lenguaje completamente orientado a objetos es

Smalltalk.

Si bien puede seleccionarse la forma pura de estos paradigmas a la hora de programar, en la práctica es habitual que se mezclen, dando lugar a la programación multiparadigma.

Actualmente el paradigma de programación más usado debido a múltiples ventajas respecto a sus anteriores, es la programación orientada a objetos.

Lenguajes imperativos

Son los lenguajes que dan instrucciones a la computadora, es decir, órdenes.

Lenguajes Funcionales

Paradigma Funcional: este paradigma concibe a la computación como la evaluación de funciones matemáticas y evita declarar y cambiar datos. En otras palabras, hace hincapié en la aplicación de las funciones y composición entre ellas, más que en los cambios de estados y la ejecución secuencial de comandos (como lo hace el paradigma procedimental). Permite resolver ciertos problemas de forma elegante y los lenguajes puramente funcionales evitan los efectos secundarios comunes en otro tipo de programaciones.

Lenguajes Lógicos

La computación lógica direcciona métodos de procesamiento basados en el razonamiento formal. Los objetos de tales razonamientos son "hechos" o reglas "if then". Para computar lógicamente se utiliza un conjunto de tales estamentos para calcular la verdad o falsedad de ese conjunto de estamentos. Un estamento es un hecho si sus tuplas verifican una serie de operaciones.

Un hecho es una expresión en la que algún objeto o conjunto de objetos satisface una relación específica. Una tupla es una lista inmutable. Una tupla no puede modificarse de ningún modo después de su creación.

Una regla if then es un estamento que informa acerca de conjuntos de tuplas o estamentos relacionados que pueden predecir si otras tuplas verificaran otras relaciones.

Un estamento que es probado verdadero como resultado de un proceso se dice que es una inferencia del conjunto original. Se trata por tanto de una descripción de cómo obtener la veracidad de un estamento dado que unas reglas son verdaderas.

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 4 -

La computación lógica está por tanto relacionada con la automatización de algún conjunto de métodos de inferencia.

Lenguajes orientados a objetos

La Programación Orientada a Objetos (POO u OOP según sus siglas en inglés) es un paradigma de programación que usa objetos y sus interacciones para diseñar aplicaciones y programas de computadora. Está basado en varias técnicas, incluyendo herencia, modularidad, polimorfismo y encapsulamiento. Su uso se popularizó a principios de la década de 1990. Actualmente son muchos los lenguajes de programación que soportan la orientación a objetos.

SISTEMA DE INFORMACION

Un sistema de información es un conjunto de elementos que interactúan entre sí con el fin de apoyar las actividades de un negocio.

Un sistema de información realiza cuatro actividades básicas: entrada, almacenamiento, procesamiento y salida de información.

Entrada de Información: Es el proceso mediante el cual el Sistema de Información toma los datos que requiere para procesar la información. Las entradas pueden ser manuales o automáticas. Las manuales son aquellas que se proporcionan en forma directa por el usuario, mientras que las automáticas son datos o información que provienen o son tomados de otros sistemas o módulos. Esto último se denomina interfaces automáticas.

Las unidades típicas de entrada de datos a las computadoras son las terminales, las cintas magnéticas, las unidades de diskette, los códigos de barras, los escáners, la voz, los monitores sensibles al tacto, el teclado y el mouse, entre otras.

Almacenamiento de información: El almacenamiento es una de las actividades o capacidades más importantes que tiene una computadora, ya que a través de esta propiedad el sistema puede recordar la información guardada en la sección o proceso anterior. Esta información suele ser almacenada en estructuras de información denominadas archivos. La unidad típica de almacenamiento son los discos magnéticos o discos duros, los discos flexibles o diskettes y los discos compactos (CD-ROM).

Procesamiento de Información: Es la capacidad del Sistema de Información para efectuar cálculos de acuerdo con una secuencia de operaciones preestablecida.

Estos cálculos pueden efectuarse con datos introducidos recientemente en el sistema o bien con datos que están almacenados. Esta característica de los sistemas permite la transformación de datos fuente en información que puede ser utilizada para la toma de decisiones, lo que hace posible, entre otras cosas, que un tomador de decisiones genere una proyección financiera a partir de los datos que contiene un estado de resultado o un balance general de un año base.

Salida de Información: La salida es la capacidad de un Sistema de Información para sacar la información procesada o bien datos de entrada al exterior. Las unidades típicas de salida son las

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 5 -

impresoras, terminales, cintas magnéticas, la voz, los graficadores y los plotters, entre otros. Es importante aclarar que la salida de un Sistema de Información puede constituir la entrada a otro Sistema de Información o módulo. En este caso, también existe una interface automática de salida. Por ejemplo, el Sistema de Control de Clientes tiene una interface automática de salida con el Sistema de Contabilidad, ya que genera las pólizas contables de los movimientos procesales de los clientes.

A continuación se muestran las diferentes actividades que puede realizar un Sistema de Información de Control de Clientes:

Actividades que realiza un Sistema de Información:

Entradas:

Datos generales del cliente: nombre, dirección, tipo de cliente, etc.

Políticas de crédito: límite de crédito, plazo de pago, etc.

Facturas (interface automático).

Pagos, depuraciones, etc.

Proceso:

Cálculo de antigüedad de saldos.

Cálculo de intereses moratorios.

Cálculo del saldo de un cliente.

Almacenamiento:

Movimientos del mes (pagos, depuraciones).

Catálogo de clientes.

Facturas.

Salidas:

Reporte de pagos.

Estados de cuenta.

Pólizas contables (interface automática)

Consultas de saldos en pantalla de una terminal.

Las diferentes actividades que realiza un Sistema de Información se pueden observar en el diseño conceptual ilustrado en la figura 1.

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 6 -

Tipos y Usos de los Sistemas de Información

Durante los próximos años, los Sistemas de Información cumplirán tres objetivos básicos dentro de las organizaciones:

Automatización de procesos operativos.

Proporcionar información que sirva de apoyo al proceso de toma de decisiones.

Lograr ventajas competitivas a través de su implantación y uso.

Los Sistemas de Información que logran la automatización de procesos operativos dentro de una organización, son llamados frecuentemente Sistemas Transaccionales, ya que su función primordial consiste en procesar transacciones tales como pagos, cobros, pólizas, entradas, salidas, etc. Por otra parte, los Sistemas de Información que apoyan el proceso de toma de decisiones son los Sistemas de Soporte a la Toma de Decisiones, Sistemas para la Toma de Decisión de Grupo, Sistemas Expertos de Soporte a la Toma de Decisiones y Sistema de Información para Ejecutivos.

Entrada de datos

Proceso

Informes

reportes

Interface automática de entrada Almacenamiento

Interface automática de salida

Figura 1

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 7 -

El tercer tipo de sistema, de acuerdo con el uso u objetivo que cumplen, es el de los Sistemas Estratégicos, los cuales se desarrollan en las organizaciones con el fin de lograr ventajas competitivas, a través del uso de la tecnología de información.

A continuación se mencionan las principales características de estos tipos de Sistemas de Información.

Sistemas Transaccionales. Sus principales características son:

A través de éstos suelen lograrse ahorros significativos de mano de obra, debido a que automatizan tareas operativas de la organización.

Con frecuencia son el primer tipo de Sistemas de Información que se implanta en las organizaciones. Se empieza apoyando las tareas a nivel operativo de la organización.

Son intensivos en entrada y salid de información; sus cálculos y procesos suelen ser simples y poco sofisticados.

Tienen la propiedad de ser recolectores de información, es decir, a través de estos sistemas se cargan las grandes bases de información para su explotación posterior.

Son fáciles de justificar ante la dirección general, ya que sus beneficios son visibles y palpables.

Sistemas de Apoyo de las Decisiones. Las principales características de estos son:

Suelen introducirse después de haber implantado los Sistemas Transaccionales más relevantes de la empresa, ya que estos últimos constituyen su plataforma de información.

La información que generan sirve de apoyo a los mandos intermedios y a la alta administración en el proceso de toma de decisiones.

Suelen ser intensivos en cálculos y escasos en entradas y salidas de información. Así, por ejemplo, un modelo de planeación financiera requiere poca información de entrada, genera poca información como resultado, pero puede realizar muchos cálculos durante su proceso.

No suelen ahorrar mano de obra. Debido a ello, la justificación económica para el desarrollo de estos sistemas es difícil, ya que no se conocen los ingresos del proyecto de inversión.

Suelen ser Sistemas de Información interactivos y amigables, con altos estándares de diseño gráfico y visual, ya que están dirigidos al usuario final.

Apoyan la toma de decisiones que, son repetitivos y de decisiones no estructuradas que no suelen repetirse. Por ejemplo, un Sistema de Compra de Materiales que indique cuándo debe hacerse un pedido al proveedor o un Sistema de Simulación de Negocios que apoye la decisión de introducir un nuevo producto al mercado.

Estos sistemas pueden ser desarrollados directamente por el usuario final sin la participación operativa de los analistas y programadores del área de informática.

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 8 -

Este tipo de sistemas puede incluir la programación de la producción, compra de materiales, flujo de fondos, proyecciones financieras, modelos de simulación de negocios, modelos de inventarios, etc.

Sistemas Estratégicos. Sus principales características son:

Su función más importante no es la de apoyar la automatización de procesos operativos ni proporcionar información para apoyar la toma de decisiones.

Suelen desarrollarse dentro de la organización, por lo tanto no pueden adaptarse fácilmente a paquetes disponibles en el mercado.

Típicamente su forma de desarrollo es a base de incrementos y a través de su evolución dentro de la organización. Se inicia con un proceso o función en particular y a partir de ahí se van agregando nuevas funcionalidades o procesos.

Su función es lograr ventajas que los competidores no posean, tales como ventajas en costos y servicios diferenciados con clientes y proveedores. En este contexto, los Sistema Estratégicos son creadores de barreras de entrada al negocio. Por ejemplo, el uso de cajeros automáticos en los bancos en un Sistema Estratégico, ya que brinda ventaja sobre un banco que no posee tal servicio. Si un banco nuevo decide abrir sus puertas al público, tendrá que dar este servicio para tener un nivel similar al de sus competidores.

Apoyan el proceso de innovación de productos y proceso dentro de la empresa debido a que buscan ventajas respecto a los competidores y una forma de hacerlo en innovando o creando productos y procesos.

Un ejemplo de estos Sistemas de Información dentro de la empresa puede ser un sistema MRP (Manufacturing Resoure Planning) enfocado a reducir sustancialmente el desperdicio en el proceso productivo, o bien, un Centro de Información que proporcione todo tipo de información; como situación de créditos, embarques, tiempos de entrega, etc. En este contexto los ejemplos anteriores constituyen un Sistema de Información Estratégico si y sólo sí, apoyan o dan forma a la estructura competitiva de la empresa.

Por último, es importante aclarar que algunos autores consideran un cuarto tipo de sistemas de información denominado Sistemas Personales de Información, el cual está enfocado a incrementar la productividad de sus usuarios.

Evolución de los Sistemas de Información

De la sección anterior se desprende el concepto de evolución que tienen los Sistemas de Información en las organizaciones. Con frecuencia se implantan en forma inicial los Sistemas Transaccionales y, posteriormente, se introducen los Sistemas de Apoyo a las Decisiones. Por último, se desarrollan los Sistemas Estratégicos que dan forma a la estructura competitiva de la empresa.

En la década de los setenta, se estableció que la función de la Informática en las organizaciones evoluciona a través de ciertas etapas de crecimiento, las cuales se explican a continuación:

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 9 -

Etapa inicial: Comienza con la adquisición de la primera computadora y normalmente se justifica por el ahorro de mano de obra y el exceso de papeles.

Las aplicaciones típicas que se implantan son los Sistemas Transaccionales tales como nóminas o contabilidad.

El pequeño Departamento de Sistemas depende en la mayoría de los casos del área de contabilidad.

El tipo de administración empleada es escaso y la función de los sistemas suele ser manejada por un administrador que no posee una preparación formal en el área de computación.

El personal que labora en este pequeño departamento consta a lo sumo de un operador y/o un programador. Este último podrá estar bajo el régimen de honorarios, o bien, puede recibirse el soporte de algún fabricante local de programas de aplicación.

En esta etapa es importante estar consciente de la resistencia al cambia del personal y usuario (ciberfobia) que están involucrados en los primeros sistemas que se desarrollan, ya que estos sistemas son importantes en el ahorro de mano de obra.

Esta etapa termina con la implantación exitosa del primer Sistema de Información. Cabe recalcar que algunas organizaciones pueden vivir varias etapas de inicio en las que la resistencia al cambio por parte de los primeros usuarios involucrados aborta el intento de introducir la computadora a la empresa.

Etapa de contagio o expansión. Los aspectos sobresalientes que permiten diagnosticar rápido que una empresa se encuentra en esta etapa son:

Se inicia con la implantación exitosa del primer Sistema de Información en la organización. Como consecuencia de lo anterior, el primer ejecutivo usuario se transforma en el paradigma o persona que se habrá que imitar.

Las aplicaciones que con frecuencia se implantan en esta etapa son el resto de los Sistemas Transaccionales no desarrollados en la etapa de inicio, tales como facturación, inventarios, control de pedidos de clientes y proveedores, cheques, etc.

El pequeño departamento es promovido a una categoría superior, donde depende de la Gerencia Administrativa o Contraloría.

El tipo de administración empleada está orientada hacia la venta de aplicaciones a todos los usuarios de la organización; en este punto suele contratarse a un especialista de la función con preparación académica en el área de sistemas.

Se inicia la contratación de personal especializado y nacen puestos tales como analista de sistemas, analista-programador, programador de sistemas, jefe de desarrollo, jefe de soporte técnico, etc.

Las aplicaciones desarrolladas carecen de interfaces automáticas entre ellas, de tal forma que las salidas que produce un sistema se tienen que alimentar en forma manual a otro sistema, con la consecuente irritación de los usuarios.

Los gastos por concepto de sistemas empiezan a crecer en forma importante, lo que marca la pauta para iniciar la racionalización en el uso de los recursos computacionales dentro de la empresa. Este problema y el inicio de su solución marcan el paso a la siguiente etapa.

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 10 -

Etapa de control o formalización. Para identificar a una empresa que transita por esta etapa es necesario considerar los siguientes elementos:

Esta etapa de evolución de la Informática dentro de las empresas se inicia con la necesidad de controlar el uso de los recursos computacionales a través de las técnicas utilizadas para realizar presupuestos a base cero (partiendo de que no se tienen nada) y la implantación de sistemas de cargos a usuarios (por el servicio que se presta).

Las aplicaciones están orientadas a facilitar el control de las operaciones del negocio para hacerlas más eficaces, tales como sistemas para control de flujo de fondos, control de órdenes de compra a proveedores, control de inventarios, control y manejo de proyectos, etc.

El departamento de sistemas de la empresa suele ubicarse en una posición gerencial, dependiendo del organigrama de la Dirección de Administración o Finanzas.

El tipo de administración empleado dentro del área de Informática se orienta al control y a la justificación económica de las aplicaciones a desarrollar. Nace la necesidad de establecer criterios para las prioridades en el desarrollo de nuevas aplicaciones. La cartera de aplicaciones pendientes por desarrollar empieza a crecer.

En esta etapa se inician el desarrollo y la implantación de estándares de trabajo dentro del departamento, tales como: estándares de documentación control de proyectos, desarrollo y diseño de sistemas de información, auditoría de sistemas y programación.

Se integra a la organización del departamento de sistemas, personal con habilidad administrativa y preparación técnica.

Se inicia el desarrollo de interfaces automáticas entre los diferentes sistemas.

Etapa de integración. Las características de esta etapa son las siguientes:

La integración de los datos y de los sistemas surge como un resultado directo de la centralización del departamento de sistemas bajo una sola estructura administrativa.

Las nuevas tecnologías relacionadas con bases de datos, sistemas administradores de bases de datos y lenguajes de cuarta generación, hicieron posible la integración.

En forma paralela a los cambios tecnológicos, cambió el rol del usuario y del departamento de Sistemas de Información. El departamento de sistemas evolucionó hacia una estructura descentralizada, permitiendo al usuario utilizar herramientas para el desarrollo de sistemas.

Los usuarios y el departamento de sistema iniciaron el desarrollo de nuevos sistemas, reemplazando los sistemas antiguos, en beneficio de la organización.

Etapa de administración de datos. Entre las características que destacan en esta etapa están las siguientes:

El departamento de Sistemas de Información reconoce que la información es un recurso muy valioso que debe estar accesible para todos los usuarios.

Para poder cumplir con lo anterior resulta necesario administrar los datos en forma apropiada, es decir, almacenarlos y mantenerlos en forma adecuada para que los usuarios puedan utilizar y compartir este recurso.

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 11 -

El usuario de la información adquiere la responsabilidad de la integridad de la misma y debe manejar niveles de acceso diferentes.

Etapa de madurez. Entre los aspectos sobresalientes que indican que una empresa se encuentra en esta etapa, se incluyen los siguientes:

Al llegar a esta etapa, la Informática dentro de la organización se encuentra definida como una función básica y se ubica en los primeros niveles del organigrama (dirección).

Los sistemas que se desarrollan son Sistemas de Manufactura Integrados por Computadora, Sistemas Basados en el Conocimiento y Sistemas Expertos, Sistemas de Soporte a las Decisiones, Sistemas Estratégicos y, en general, aplicaciones que proporcionan información para las decisiones de alta administración y aplicaciones de carácter estratégico.

En esta etapa se tienen las aplicaciones desarrolladas en la tecnología de base de datos y se logra la integración de redes de comunicaciones con terminales en lugares remotos, a través del uso de recursos computacionales.

BIBLIOGRAFIA OBLIGATORIA:

“Fundamentos de programación. Algoritmos, Estructuras de datos y Objetos”, Luis Joyanes Aguilar. Mc Graw Hill. Tercera edición. Capítulo 1 (páginas 3 a 37)

1.2 Algoritmo. Concepto. Características

En matemáticas, ciencias de la computación y disciplinas relacionadas, un algoritmo (del latín, dixit algorithmus y éste a su vez del matemático persa Al Juarism) es una lista bien definida, ordenada y finita de operaciones que permite hallar la solución a un problema. Dado un estado inicial y una entrada, a través de pasos sucesivos y bien definidos se llega a un estado final, obteniendo una solución. Los algoritmos son objeto de estudio de la algoritmia.

En la vida cotidiana se emplean algoritmos en multitud de ocasiones para resolver diversos problemas. Algunos ejemplos se encuentran en los instructivos (manuales de usuario), los cuales muestran algoritmos para usar el aparato en cuestión o inclusive en las instrucciones que recibe un trabajador por parte de su empleador. También existen ejemplos de índole matemática, como el algoritmo de la división para calcular el cociente de dos números, el algoritmo de Euclides para calcular el máximo común divisor de dos enteros positivos, o el método de Gauss para resolver un Sistema lineal de ecuaciones.

Un algoritmo es un método para resolver un problema. La resolución de un problema exige el diseño de un algoritmo que resuelva el problema propuesto. En la figura 2 se muestra un esquema en bloques de tres etapas fundamentales en la resolución de un problema.

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 12 -

CARACTERISTICAS PRINCIPALES DE LOS ALGORITMOS

En general no existe ningún consenso definitivo en cuanto a la definición formal de algoritmo.

Muchos autores los señalan como listas de instrucciones para resolver un problema abstracto, es decir, que en un número finito de pasos convierten los datos de un problema (entrada) en una solución (salida).

Sin embargo cabe notar que algunos algoritmos no necesariamente tienen que terminar o resolver un problema en particular. Por ejemplo, una versión modificada de la criba de Eratóstenes que nunca termine de calcular números primos, no deja de ser un algoritmo.

A lo largo de la historia varios autores han tratado de definir formalmente a los algoritmos utilizando modelos matemáticos como máquinas de Turing entre otros. Sin embargo estos modelos están sujetos a un tipo particular de datos como son números, símbolos o gráficas mientras que, en general, los algoritmos funcionan sobre una vasta cantidad de estructuras de datos. En general, la parte común en todas las definiciones se puede resumir en las siguientes tres propiedades siempre y cuando no consideremos algoritmos paralelos.

Tiempo secuencial. Un algoritmo funciona en tiempo discreto es decir: paso a paso, definiendo así una secuencia de estados "computacionales" por cada entrada válida (la entrada son los datos que se le suministran al algoritmo antes de comenzar).

Estado abstracto. Cada estado computacional puede ser descrito formalmente utilizando una estructura de primer orden y cada algoritmo es independiente de su implementación (los algoritmos son objetos abstractos) de manera que en un algoritmo las estructuras de primer orden son invariantes bajo isomorfismo.

Exploración acotada. La transición de un estado al siguiente queda completamente determinada por una descripción fija y finita; es decir, entre cada estado y el siguiente solamente se puede tomar en cuenta una cantidad fija y limitada de términos del estado actual.

En resumen, un algoritmo es cualquier cosa que funcione paso a paso, donde cada paso se pueda describir sin ambigüedad y sin hacer referencia a una computadora en particular, y además tiene un límite fijo en cuanto a la cantidad de datos que se pueden leer/escribir en un solo paso.

Esta amplia definición abarca tanto a algoritmos prácticos como aquellos que solo funcionan en teoría, por ejemplo el método de Newton y la eliminación de Gauss-Jordan funcionan, al menos en principio, con números de precisión infinita; sin embargo no es posible programar la precisión infinita en una computadora, y no por ello dejan de ser algoritmos.

Problema Diseño del

algoritmo

Programa de

computadora

Figura 2

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 13 -

En particular es posible considerar una cuarta propiedad que puede ser usada para validar la tesis de Church-Turing de que toda función calculable se puede programar en una máquina de Turing (o equivalentemente, en un lenguaje de programación suficientemente general):

Aritmetizabilidad. Solamente operaciones innegablemente calculables están disponibles en el paso inicial.

Los algoritmos pueden ser expresados de muchas maneras, incluyendo en el lenguaje natural, pseudocódigo, diagrama de flujo y lenguajes de programación entre otros. Las descripciones en lenguaje natural tienden a ser ambiguas y extensas. El usar pseudocódigo y diagramas de flujo evita muchas ambigüedades del lenguaje natural. Dichas expresiones son formas más estructuradas para representar algoritmos; no obstante, se mantienen independientes de un lenguaje de programación específico.

La descripción de un algoritmo usualmente se hace en tres niveles:

Descripción de alto nivel. Se establece el problema, se selecciona un modelo matemático y se explica el algoritmo de manera verbal, posiblemente con ilustraciones y omitiendo detalles.

Descripción formal. Se usa pseudocódigo para describir la secuencia de pasos que encuentran la solución.

Implementación. Se muestra el algoritmo expresado en un lenguaje de programación específico o algún objeto capaz de llevar a cabo instrucciones.

También es posible incluir un teorema que demuestre que el algoritmo es correcto, un análisis de complejidad o ambos.

DIAGRAMA DE FLUJO:

Un diagrama de flujo es una forma de representar gráficamente los detalles algorítmicos de un proceso multifactorial. Se utiliza principalmente en programación, economía y procesos industriales. Estos diagramas utilizan una serie de símbolos con significados especiales y son la representación gráfica de los pasos de un proceso. En computación, son modelos tecnológicos utilizados para comprender los rudimentos de la programación lineal.

Los diagramas de flujo son descripciones gráficas de algoritmos; usan símbolos conectados con flechas para indicar la secuencia de instrucciones y están regidos por ISO.

Los diagramas de flujo son usados para representar algoritmos pequeños, ya que abarcan mucho espacio y su construcción es laboriosa. Por su facilidad de lectura son usados como introducción a los algoritmos, descripción de un lenguaje y descripción de procesos a personas ajenas a la computación.

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 14 -

Los símbolos que se utilizan para diseño se someten a una normalización, es decir, se hicieron símbolos casi universales, ya que, en un principio cada usuario podría tener sus propios símbolos para representar sus procesos en forma de Diagrama de flujo. Esto trajo como consecuencia que sólo aquel que conocía sus símbolos, los podía interpretar. La simbología utilizada para la elaboración de diagramas de flujo es variable y debe ajustarse a las normas preestablecidas universalmente para dichos símbolos o datos.

En los diagramas de flujo se presuponen los siguientes aspectos:

Existe siempre un camino que permite llegar a una solución (finalización del algoritmo).

Existe un único inicio del proceso.

Existe un único punto de fin para el proceso de flujo (salvo del rombo que indica una comparación con dos caminos posibles).

Desarrollo del diagrama de flujo

Las siguientes son acciones previas a la realización del diagrama de flujo:

Identificar las ideas principales a ser incluidas en el diagrama de flujo. Deben estar presentes el dueño o responsable del proceso, los dueños o responsables del proceso anterior y posterior y de otros procesos interrelacionados, otras partes interesadas.

Definir qué se espera obtener del diagrama de flujo.

Identificar quién lo empleará y cómo.

Establecer el nivel de detalle requerido.

Determinar los límites del proceso a describir.

Los pasos a seguir para construir el diagrama de flujo son:

1. Establecer el alcance del proceso a describir. De esta manera quedará fijado el comienzo y el final del diagrama. Frecuentemente el comienzo es la salida del proceso previo y el final la entrada al proceso siguiente.

2. Identificar y listar las principales actividades/subprocesos que están incluidos en el proceso a describir y su orden cronológico.

3. Si el nivel de detalle definido incluye actividades menores, listarlas también.

4. Identificar y listar los puntos de decisión.

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 15 -

5. Construir el diagrama respetando la secuencia cronológica y asignando los correspondientes símbolos.

6. Asignar un título al diagrama y verificar que esté completo y describa con exactitud el proceso elegido.

A su vez, es importante que al construir diagramas de flujo, se observen las siguientes recomendaciones:

Evitar sumideros infinitos, burbujas que tienen entradas pero no salidas.

Evitar las burbujas de generación espontánea, que tienen salidas sin tener entradas, porque son sumamente sospechosas y generalmente incorrectas.

VENTAJAS DEL USO DE DIAGRAMA DE FLUJO

Las ventajas del uso de los diagramas de flujos son numerosas, entre ellas podemos citar:

Favorecen la comprensión del proceso a través de mostrarlo como un dibujo. El cerebro humano reconoce fácilmente los dibujos. Un buen diagrama de flujo reemplaza varias páginas de texto.

Permiten identificar los problemas y las oportunidades de mejora del proceso. Se identifican los pasos redundantes, los flujos de los re-procesos, los conflictos de autoridad, las responsabilidades, los cuellos de botella, y los puntos de decisión.

Muestran las interfaces cliente-proveedor y las transacciones que en ellas se realizan, facilitando a los empleados el análisis de las mismas.

Son una excelente herramienta para capacitar a los nuevos empleados y también a los que desarrollan la tarea, cuando se realizan mejoras en el proceso.

TIPOS DE DIAGRAMA DE FLUJO

Los diagramas de flujo son una manera de representar visualmente el flujo de datos a través de sistemas de tratamiento de información. Los diagramas de flujo describen que operaciones y en que secuencia se requieren para solucionar un problema dado.

Los tipos de diagrama de flujo, se refiere a la presentación en el espacio del diagrama. Hay varios modelos, por ejemplo:

1) Formato vertical: En él el flujo o la secuencia de las operaciones, va de arriba hacia abajo. Es una lista ordenada de las operaciones de un proceso con toda la información que se considere necesaria, según su propósito.

2) Formato horizontal: En él, el flujo o la secuencia de las operaciones, va de izquierda a derecha.

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 16 -

3) Formato panorámico: El proceso entero está representado en una sola carta y puede apreciarse de una sola mirada mucho más rápido que leyendo el texto, lo que facilita su comprensión, aun para personas no familiarizadas. Registra no solo en línea vertical, sino también horizontal, distintas acciones simultáneas y la participación de más de un puesto o departamento que el formato vertical no registra.

4) Formato Arquitectónico: Describe el itinerario de ruta de una forma o persona sobre el plano arquitectónico del área de trabajo.

Inicio o fin del programa

Pasos, procesos o líneas de instrucciones de programa de cómputo.

Operaciones de entrada y salida.

Toma de decisión y Ramificación.

Conector para unir el flujo a otra parte del diagrama.

Cinta magnética.

Disco magnético.

Conector de página.

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 17 -

Entonces, un diagrama de flujo u organigrama es una representación diagramática que ilustra la secuencia de las operaciones que se realizarán para conseguir la solución de un problema. Los diagramas de flujo se dibujan generalmente antes de comenzar a programar el código frente a la computadora. Los diagramas de flujo facilitan la comunicación entre los programadores y la gente del negocio. Estos diagramas de flujo desempeñan un papel vital en la programación de un problema y facilitan la comprensión de problemas complicados y sobre todo muy largos. Una vez que se dibuja el diagrama de flujo, llega a ser fácil escribir el programa en cualquier lenguaje de alto nivel. Vemos a menudo cómo los diagramas de flujo nos dan ventaja al momento de explicar el programa a otros. Por lo tanto, está correcto decir que un diagrama de flujo es una necesidad para la documentación mejor de un programa complejo.

Los Diagramas de flujo se dibujan generalmente usando algunos símbolos estándares; sin embargo, algunos símbolos especiales pueden también ser desarrollados cuando así sea necesario. Algunos símbolos estándares, que se requieren con frecuencia para diagramar programas de computadora se muestran a continuación:

Dentro de los símbolos fundamentales para la creación de diagramas de flujo, están los que se usan para las operaciones aritméticas y relacionales o de condición. La siguiente es una lista de símbolos utilizados:

+ Sumar

- Menos

* Multiplicación

/ División

± Mas o menos

= Equivalente a

Líneas de flujo.

Anotación.

Display, para mostrar datos.

Envía datos a la impresora.

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 18 -

> Mayor que

< Menor que

>= Mayor o igual que

<= Menor o igual que

<> Diferente de

Si

No

True

False

Los Diagramas de flujo deben escribirse de arriba hacia abajo, y/o de izquierda a derecha.

Los símbolos se unen con líneas, las cuales tienen en la punta una flecha que indica la dirección que fluye la información procesos, se deben de utilizar solamente líneas de flujo horizontal o verticales (nunca diagonales).

Se debe evitar el cruce de líneas, para lo cual se quisiera separar el flujo del diagrama a un sitio distinto, se pudiera realizar utilizando los conectores. Se debe tener en cuenta que solo se vana utilizar conectores cuando sea estrictamente necesario.

No deben quedar líneas de flujo sin conectar

Todo texto escrito dentro de un símbolo debe ser legible, preciso, evitando el uso de muchas palabras.

Todos los símbolos pueden tener más de una línea de entrada, a excepción del símbolo final.

Solo los símbolos de decisión pueden y deben tener más de una línea de flujo de salida.

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 19 -

Para realizar diagramas más sencillos de realizar, se empleará un número reducido de símbolos como se muestra en la figura 3.

Ejemplo de diagramas de flujo

Ejemplo 1: Realizar un diagrama de flujo que determine y muestre por pantalla los números pares entre 2 y 100 (figura 4).

conector

Subprograma

Proceso

Entrada / salida

no

si

Decisión Inicio / fin

Figura 3

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 20 -

Ejemplo 2: Realizar un diagrama de flujo que permita el ingreso de 10 números enteros, determine y muestre por pantalla solamente los números positivos que se hayan ingresado por teclado (figura 5).

inicio

Suma 2

Numero4

Sumasuma +numero

Numeronumero+2

Numero< =100

Escribir

SUMA

fin

si

no

Figura 4

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 21 -

Ejemplo 3: Crear un diagrama de flujo que permita intercambiar los valores de dos variables numéricas (tomas desde el teclado) (figura 6).

no

si

inicio

cantidad 1

Cantidadcantidad +1

Cantidad<10

Mostrar num

fin

si

no

Leer num Num>0

Figura 5

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 22 -

El pseudocódigo es la descripción de un algoritmo que asemeja a un lenguaje de programación pero con algunas convenciones del lenguaje natural (de ahí que tenga el prefijo pseudo, que significa falso). Tiene varias ventajas con respecto a los diagramas de flujo, entre las que se destaca el poco espacio que se requiere para representar instrucciones complejas. El pseudocódigo no está regido por ningún estándar.

La teoría de autómatas y la teoría de funciones recursivas proveen modelos matemáticos que formalizan el concepto de algoritmo. Los modelos más comunes son la máquina de Turing, máquinas de registro y funciones u-recursivas. Estos modelos son tan precisos como un lenguaje máquina, careciendo de expresiones coloquiales o ambigüedad, sin embargo se mantienen independientes de cualquier computadora y de cualquier implementación.

Muchos algoritmos son ideados para implementarse en un programa. Sin embargo, los algoritmos pueden ser implementados en otros medios, como una red neuronal, un circuito eléctrico o un

inicio

AuxA

AB

BAux

Escribir

A, B

fin

Figura 6

Leer A,B

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 23 -

aparato mecánico y eléctrico. Algunos algoritmos inclusive se diseñan especialmente para implementarse usando lápiz y papel. El algoritmo de multiplicación tradicional, el algoritmo de Euclides, la criba de Eratóstenes y muchas formas de resolver la raíz cuadrada, son sólo algunos ejemplos.

Como medida de la eficiencia de un algoritmo, se suelen estudiar los recursos (memoria y tiempo) que consume el algoritmo. El análisis de algoritmos se ha desarrollado para obtener valores que de alguna forma indiquen (o especifiquen) la evolución del gasto de tiempo y memoria en función del tamaño de los valores de entrada.

El análisis y estudio de los algoritmos es una disciplina de las ciencias de la computación y, en la mayoría de los casos, su estudio es completamente abstracto sin usar ningún tipo de lenguaje de programación ni cualquier otra implementación; por eso, en ese sentido, comparte las características de las disciplinas matemáticas. Así, el análisis de los algoritmos se centra en los principios básicos del algoritmo, no en los de la implementación particular. Una forma de plasmar (o algunas veces "codificar") un algoritmo es escribirlo en pseudocódigo o utilizar un lenguaje muy simple tal como Léxico, cuyos códigos pueden estar en el idioma del programador.

Algunos escritores restringen la definición de algoritmo a procedimientos que deben acabar en algún momento, mientras que otros consideran procedimientos que podrían ejecutarse eternamente sin pararse, suponiendo el caso en el que existiera algún dispositivo físico que fuera capaz de funcionar eternamente.

En este último caso, la finalización con éxito del algoritmo no se podría definir como la terminación de éste con una salida satisfactoria, sino que el éxito estaría definido en función de las secuencias de salidas dadas durante un periodo de vida de la ejecución del algoritmo. Por ejemplo, un algoritmo que verifica que hay más ceros que unos en una secuencia binaria infinita debe ejecutarse siempre para que pueda devolver un valor útil. Si se implementa correctamente, el valor devuelto por el algoritmo será válido, hasta que evalúe el siguiente dígito binario. De esta forma, mientras evalúa la siguiente secuencia podrán leerse dos tipos de señales: una señal positiva (en el caso de que el número de ceros sea mayor que el de unos) y una negativa en caso contrario.

Finalmente, la salida de este algoritmo se define como la devolución de valores exclusivamente positivos si hay más ceros que unos en la secuencia y, en cualquier otro caso, devolverá una mezcla de señales positivas y negativas.

TECNICAS DE DISEÑO DE ALGORITMOS

Algoritmos voraces (greedy): seleccionan los elementos más prometedores del conjunto de candidatos hasta encontrar una solución. En la mayoría de los casos la solución no es óptima.

Algoritmos paralelos: permiten la división de un problema en subproblemas de forma que se puedan ejecutar de forma simultánea en varios procesadores.

Algoritmos probabilísticos: algunos de los pasos de este tipo de algoritmos están en función de valores pseudoaleatorios.

Algoritmos determinísticos: El comportamiento del algoritmo es lineal: cada paso del algoritmo tiene únicamente un paso sucesor y otro antecesor.

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 24 -

Algoritmos no determinísticos: El comportamiento del algoritmo tiene forma de árbol y a cada paso del algoritmo puede bifurcarse a cualquier número de pasos inmediatamente posteriores, además todas las ramas se ejecutan simultáneamente.

Divide y vencerás: dividen el problema en subconjuntos disjuntos obteniendo una solución de cada uno de ellos para después unirlas, logrando así la solución al problema completo.

Metaheurísticos: encuentran soluciones aproximadas (no óptimas) a problemas basándose en un conocimiento anterior (a veces llamado experiencia) de los mismos.

Programación dinámica: intenta resolver problemas disminuyendo su coste computacional aumentando el coste espacial.

Ramificación y acotación: se basa en la construcción de las soluciones al problema mediante un árbol implícito que se recorre de forma controlada encontrando las mejores soluciones.

Vuelta Atrás (Backtracking): se construye el espacio de soluciones del problema en un árbol que se examina completamente, almacenando las soluciones menos costosas.

ELEMENTOS BASICOS DE UN PROGRAMA

Los elementos básicos que constituyen un programa o algoritmo son:

Palabras reservadas (inicio, fin, mientras, desde, escribir, mostrar leer, etc) Identificadores (nombre de variables u objetos en general) Caracteres especiales (coma, apóstrofe, comillas, etc) Constantes Variables Expresiones Instrucciones

Además de estos elementos básicos, existen otros elementos que forman parte de los programas, estos elementos son:

Bucles

Acumuladores

Contadores

Banderas o flag

Estructuras: secuenciales, selectivas y repetitivas

BIBLIOGRAFIA OBLIGATORIA:

“Fundamentos de programación. Algoritmos, Estructuras de datos y Objetos”, Luis Joyanes Aguilar. Mc Graw Hill. Tercera edición. Capítulo 1 y 2 (páginas 3 a 79)

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 25 -

1.3 Datos. Tipos. Datos numéricos, lógicos y de carácter

En lenguaje de programación un tipo de dato es un atributo de una parte de los datos que indica al ordenador (y/o al programador) algo sobre la clase de datos sobre los que se va a procesar. Esto incluye imponer restricciones en los datos, como qué valores pueden tomar y qué operaciones se pueden realizar. Tipos de datos comunes son: enteros, números de coma flotante (decimales), cadenas alfanuméricas, fechas, horas, colores, coches o cualquier cosa que se nos ocurra. Por ejemplo, en Java, el tipo "int" representa un conjunto de enteros de 32 bits cuyo rango va desde el -2.147.483.648 al 2.147.483.647, así como las operaciones que se pueden realizar con los enteros, como la suma, resta y multiplicación. Los colores, por otra parte, se representan como tres bytes denotando la cantidad de rojo, verde y azul, y una cadena de caracteres representando el nombre del color; las operaciones permitidas incluyen la adición y sustracción, pero no la multiplicación.

El tipo de dato tiene relación con el espacio (en byte) que se utiliza en memoria dinámica para almacenar los valores (variables, constantes).

Éste es un concepto propio de la informática, más específicamente de los lenguajes de programación, aunque también se encuentra relacionado con nociones similares de las matemáticas y la lógica.

En un sentido amplio, un tipo de datos define un conjunto de valores y las operaciones sobre estos valores. Casi todos los lenguajes de programación explícitamente incluyen la notación del tipo de datos, aunque lenguajes diferentes pueden usar terminología diferente. La mayor parte de los lenguajes de programación permiten al programador definir tipos de datos adicionales, normalmente combinando múltiples elementos de otros tipos y definiendo las operaciones del nuevo tipo de dato. Por ejemplo, un programador puede crear un nuevo tipo de dato llamado "Persona" que especifica que el dato interpretado como Persona incluirá un nombre y una fecha de nacimiento.

Un tipo de dato puede ser también visto como una limitación impuesta en la interpretación de los datos en un sistema de tipificación, describiendo la representación, interpretación y la estructura de los valores u objetos almacenados en la memoria del ordenador. El sistema de tipificación usa información de los tipos de datos para comprobar la verificación de los programas que acceden o manipulan los datos.

DATOS NUMERICOS:

El tipo numérico es el conjunto de los valores numéricos. Estos pueden representarse en dos formas distintas:

Tipo numérico entero ( entero)

Tipo numérico real ( real)

ENTEROS:

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 26 -

Los son números sin coma, es decir, sin parte fraccionaria y pueden ser positivos o negativos, algunos ejemplos de números enteros son:

5

-12

0

31

111144

20

-5556

17

51

999

-999

REALES:

Los números reales, son como lo entendemos con el concepto de algebra, es decir comprende a los enteros positivos, negativos el cero, más los números decimales.

Los números reales tienen mayor número de byte para ser almacenados en memoria dinámica (memoria de sistema) que los enteros. Por lo tanto, a veces necesitamos guardar en una variable un número entro cuya magnitud excede el máximo permitido, en estos casos se utiliza una variable de tipo real en lugar de tipo entero (aunque el número en cuestión no tenga parte fraccionaria).

Algunos ejemplos de números reales son:

1.003

-1.5

100.08

2345000000

-444567,234

0.00178

DATOS LOGICOS:

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 27 -

El tipo de dato lógico, es aquel que solo puede tomar dos valores, cierto o verdadero, y falso.

DATOS DE TIPO CARÁCTER:

El tipo de dato carácter es el conjunto finito y ordenado de caracteres que la computadora reconoce. Un dato de tipo carácter contiene un solo carácter.

Algunos ejemplos de este tipo son:

A

N

M

V B

b

a

0

2

;

:

En pseudocódigo la A es distinta de la a, es decir mayúsculos y minúsculas son distintas. Cada uno de estos caracteres se representa por un entero en código ASCII.

Por ejemplo la A mayúscula se representa por el número entero 65 mientras que la letra a minúscula se representa con el entero 97.

BIBLIOGRAFIA OBLIGATORIA:

“Fundamentos de programación. Algoritmos, Estructuras de datos y Objetos”, Luis Joyanes Aguilar. Mc Graw Hill. Tercera edición. Capítulo 3 (páginas 83 a 92).

1.4 Variables y constantes

Las constantes son ciertos valores que no pueden cambiar durante la ejecución del programa. Existen otros valores que pueden cambiar a lo largo de la ejecución del programa, estas son las variables.

Ejemplo de constantes numéricas conocidas son:

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 28 -

PI = 3.14

E= 2.718229

Se pueden definir constantes de todos los tipos primitivos de variables.

En general las constantes se designan con identificadores o nombres en mayúscula.

Una variable en cambio, es un objeto cuyo valor puede cambiar.

Una variable tiene asociado: un identificador o nombre, un tipo asociado (entero, real, lógica de carácter y de cadena) y un valor según el tipo con el cual se haya declarado la variable.

La variable solo puede tomar valores permitido según su tipo. Por ejemplo una variable real, puede tomar valores positivos, negativos, con o sin como decimal e incluso el cero.

Si se intenta asignar un valor no permitido (según su tipo) se producirá un error de tipo.

En cuanto al identificador o nombre de un objeto, este es un conjunto de caracteres alfanuméricos, el primer carácter generalmente en todos los lenguajes es una letra.

Algunos ejemplos de variables son:

Dato

aa

c1

num1

num2

contador

índice

Todos los lenguajes tienen un conjunto de palabras reservadas, estas son como su nombre lo indica palabras que no pueden utilizarse para identificar objetos, están reservadas al lenguaje.

En pseudocódigo hay palabras reservadas que no pueden utilizarse como identificadores como por ejemplo:

Inicio

fin

entero

real

mientras

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 29 -

si

entonces

para

segun

sea

repetir

función

lógico

carácter

cadena

sino

Declaraciones correctas de objetos son:

entero dato

entero numero

lógico valor

real promedio1

real promedio2

carácter letra

Declaraciones incorrectas son:

entero 11ª

real -num

entero para

lógico inicio

BIBLIOGRAFIA OBLIGATORIA:

“Fundamentos de programación. Algoritmos, Estructuras de datos y Objetos”, Luis Joyanes Aguilar. Mc Graw Hill. Tercera edición. Capítulo 3 (páginas 83 a 125)

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 30 -

1.5 Expresiones. Aritméticas. Operadores. Reglas de prioridades.

Las expresiones son combinaciones de constantes, variables, símbolos de operación, paréntesis y nombres de funciones especiales. Por ejemplo: a+ (b*c) +c en este caso los paréntesis indican el orden de cálculo.

Cada expresión toma un valor que determina tomando los valores de las variables y constantes implicadas y la ejecución de las operaciones indicadas.

Una expresión consta de operadores y operandos. Según el tipo de objetos que manipulan, las expresiones se clasifican en:

Aritméticas

Relacionales

Lógicas

Carácter

El resultado de una expresión aritmética es de tipo numérico, mientras que el resultado de una expresión de tipo lógico y de tipo relacional es lógico y el resultado de una expresión de tipo carácter es de tipo carácter.

EXPRESIONES ARITMETICAS

Las expresiones aritméticas son análogas a las que se utilizan en el álgebra. Las variables y constantes son de tipo numérico (entero, real) y las operaciones son las aritméticas:

+ suma

- Resta

* multiplicación

/ división

^ ** exponenciación

div división entera

mod módulo (resto de una división entera)

Los símbolos +, -, *, ^, /, y las palabras reservadas mod y div se conocen como operadores aritméticos.

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 31 -

En la expresión:

3+5

El 3 y 3l número 5 se llaman operandos y el símbolo que los vincula, es decir, +, es el operador.

El valor de la expresión, se conoce como el resultado de la expresión.

OPERADORES DIV Y MOD

El operador / se usa en la división real y el operador div en la división entera..

Por ejemplo:

A div B solo es válido si el objeto A y B son ambos enteros.

La expresión 9 div 2, da como resultado 4, mientras que la expresión 9 div 3 da como resultado 3.

En la primera expresión, es decir 9 div 2, como el resultado debe ser entero, los decimales se pierden, hay que notar que no se produce redondeo alguno.

El operador mod, da como resultado el resto de una división entera.

Por ejemplo:

9 mod 3 da como resultado 0

9 mod 11 da como resultado 9

8 mod 3 da como resultado 2

20 mod 2 da como resultado 0

REGLAS DE PRIORIDAD

Las reglas de prioridad determinan el orden en el que se ejecutan las operaciones.

Las reglas de precedencia o prioridad son:

1. Las operaciones que están encerradas entre paréntesis se evalúan primero. Si existen paréntesis anidados (interiores unos a otros), las expresiones internas se evalúan primero

2. Las operaciones aritméticas dentro de una expresión suelen seguir el siguiente orden de prioridad:

Operador exponencial

Operadores de producto y división

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 32 -

Operadores div y mod

Operadores suma y resta

En caso de coincidir varios operadores de igual prioridad en una expresión o subexpresión encerada entre paréntesis, el orden de precedencia en este caso es de izquierda a derecha.

Ejemplos de aplicación:

Ejemplo1: ¿cuál es el resultado de la siguiente expresión?

3 + 6 * 14

Rta: 87

Ejemplo2: ¿cuál es el resultado de la siguiente expresión?

8 + 7 * 3 +4 * 6

Rta: 53

Ejemplo3: ¿cuál es el resultado de la siguiente expresión?

-4 * 7 + 2 ** ¾ -5

Rta: -31

Ejemplo4: ¿cuál es el resultado de la siguiente expresión?

(8 + 7) * 3 +4 * 6

Rta: 69

Ejemplo5: ¿cuál es el resultado de la siguiente expresión?

8 + 7 * (3 +4) * 6

Rta: 302

Ejemplo6: ¿cuál es el resultado de la siguiente expresión?

(8 + 7) * (3 +4) * 6

Rta: 630

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 33 -

BIBLIOGRAFIA OBLIGATORIA:

“Fundamentos de programación. Algoritmos, Estructuras de datos y Objetos”, Luis Joyanes Aguilar. Mc Graw Hill. Tercera edición. Capítulo 3 (páginas 83 a 125)

1.6 Expresiones lógicas. Operadores de relación.

Las expresiones lógicas o booleanas, son aquellas cuyo valor es verdadero o falso. En esencia una expresión lógica es aquella que solo puede tomar dos valores.

Las expresiones lógicas se forman combinando constantes lógicas, variables lógicas y otras expresiones lógicas, utilizando los operadores lógicos: not, and y or y los operadores relacionales (o de comparación): =, <, >, <=, >= y <>

= igual que

< menor que

>mayo que

<=menor o igual que

= mayor igualque

distinto de

Los operadores relacionales son binarios, es de necesitan dos operandos para cumplir su función.

Los operadores lógicos, expresan su funcionalidad a través de una tabla de verdad.

La tabla de verdad del operador and. La tabla tiene a su izquierda las combinaciones posibles de estados válidos para los objetos A y B, donde 0 lógico representa el falso, y el 1 lógico representa el verdadero (Figura 7):

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 34 -

Del lado derecho representa la salida, según la combinación de los estados de la entrada.

La tabla muestra que en el único caso en que el resultado de la expresión A and B da verdadero o

1 lógico, es cuando ambos objetos están en 1 lógico o en verdadero.

La tabla de verdad del operador or o simplemente o. La tabla tiene a su izquierda las combinaciones posibles de estados válidos para los objetos A y B, donde 0 lógico representa el falso, y el 1 lógico representa el verdadero (Figura 8):

A or B A B

0 0

0 1

1 0

1 1

0

1

1

1

Figura 8

A and B A B

1 0

2 1

3 0

1 1

0

0

0

1

Figura 7

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 35 -

La salida de la tabla (lado derecho) muestra que esta relación da verdadero como resultado, siempre que al menos uno de los dos objetos (A o B) sea verdadero.

La tabla de verdad del operador lógico not o simplemente no, es bastante sencilla, el operador not es unario, es decir se aplica a un solo objeto (variable o constante); da como resultado el estado opuesto del que tienen el objeto (Figura 9)

En las expresiones lógicas se pueden mezclar operadores de relación y lógicos, por ejemplo:

( 2 < 5) y (10< 34) la expresión es verdadera

( 4<6) or (23 <4) la expresión es verdadera

( 2> 5) y (10< 34) la expresión es falsa

( 4>6) or (23 <4) la expresión es falsa

( 4<6) or (2 <4) la expresión es verdadera

( 2> 5) y (100< 34) la expresión es falsa

no 5 la expresión es falsa

3 <>4 la expresión verdadera

no ( 3<>4) la expresión falsa

BIBLIOGRAFIA OBLIGATORIA:

“Fundamentos de programación. Algoritmos, Estructuras de datos y Objetos”, Luis Joyanes Aguilar. Mc Graw Hill. Tercera edición. Capítulo 3 (páginas 83 a 125).

no A A

0

1

1

0

Figura 9

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 36 -

1.7 Operación de asignación.

La operación de asignación es el modo de almacenar valores de una variable. La operación de asignación se representa con el símbolo u operador flecha . La operación de asignación se conoce como instrucción o sentencia de asignación cuando se refiere a un lenguaje de programación real.. El formato general de una operación de asignación es:

Variable expresión

La operación A 10, significa que al contenido de la variable A se le asigna el número entero 10.

Es importante notar que la operación de asignar es destructiva ya que el contenido previo a la asignación que tenia la variable, se pierde y se reemplaza por un nuevo valor.

Por ejemplo:

A 10

A 1

A 5

El objeto A contiene el valor entro 5, todos los datos previos se perdieron.

Las acciones de asignar se clasifican en tres grandes grupos: aritméticas, lógicas y de carácter.

ASIGNACION ARITMETICA

Las expresiones en las operaciones de asignación son aritméticas, por ejemplo:

Ant 6+7

tt A + B

producto con1 *con2

ASIGNACION LOGICA

La expresión que se evalúa en la operación de asignación es lógica.

Suponiendo que A, B y P son variables de tipo lógico

A 5<7

B A or ( 3 <>3)

P 10< 2

Después de realizarse las siguientes operaciones, las variables A, B y P tienen los valores Verdadero, verdadero y falso

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 37 -

ASIGNACIÓN DE CADENAS DE CARACTERES

La expresión que se evalúa es de tipo cadena:

Cadena x

X „hola‟

La instrucción de asignación asigna a la variable x de tipo cadena, la cadena de caracteres „hola‟

BIBLIOGRAFIA OBLIGATORIA:

“Fundamentos de programación. Algoritmos, Estructuras de datos y Objetos”, Luis Joyanes Aguilar. Mc Graw Hill. Tercera edición. Capítulo 3 (páginas 83 a 125)

1.8 Operaciones de entrada/salida

Las operaciones de entrada, permiten ingresar valores desde fuera de la computadora (teclado) a objetos de un programa. Esta entrada se conoce como operación de lectura. Los datos de entrada se introducen mediante dispositivos de entrada de datos (teclados, etc).

La operación de salida se denomina escritura.

En la escritura de algoritmos las acciones de lectura y escritura se representan por el siguiente formato:

leer ( lista de variables de entrada separadas por coma)

escribir (lista de variables de salida separadas por coma)

También se usan ingresar y mostrar. Ingresar es equivalente a leer, con el mismo formato. Mostrar es equivalente a escribir con el mismo formato.

Por ejemplo:

leer ( a, b, c) esta línea de pseudocódigo, representa el ingreso de tres valores por teclado y que se guardan en las variables a, b y c

mostrar ( suma) esta línea de pseudocódigo permite mostrar por pantalla el contenido de la variable suma.

BIBLIOGRAFIA OBLIGATORIA:

“Fundamentos de programación. Algoritmos, Estructuras de datos y Objetos”, Luis Joyanes Aguilar. Mc Graw Hill. Tercera edición. Capítulo 3 (páginas 83 a 125)

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 38 -

1.9 Ejercicios de aplicación.

La escritura de algoritmos mediante herramientas de programación debe ser lo más clara posible y estructurada, de modo que la lectura facilite la comprensión del algoritmo en sí, y su posterior codificación en un lenguaje específico.

Un algoritmo constará de dos componentes: una cabecera de programa y un bloque algoritmo. La cabecera de programa es una acción simple que comienza con la palabra algoritmo. Esta palabra estará seguida por el nombre asignado al programa completo. El bloque algoritmo es el resto del programa y consta de dos componentes: las acciones de declaración y las acciones ejecutables.

Las declaraciones definen o declaran las variables y constantes que tengan nombre. Las acciones ejecutables son las acciones que posteriormente deberá realizar la computadora cuando el algoritmo convertido en programa se ejecute.

Por ejemplo:

1) Implementar un programa que permita sumar dos números enteros introducidos por teclado. Mostrar el resultado por teclado. En la figura 10 se muestra el diagrama de flujo.

Algoritmo Suma-numeros

inicio

Sumaa +b

Escribir (suma)

fin

Figura 10

Leer ( a,b)

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 39 -

var

entero: a,b,suma

inicio

ingresar ( a,b)

Suma a + b

mostrar (suma)

fin

EXPLICACIÓN:

El algoritmo llamado Suma-numeros tiene dos secciones claras una de declaración de variables, corresponde a la palabra reservada var y otra que representa el algoritmo en sí, representada por la palabra reservada inicio.

En la parte para las variables declaramos los tipos, en este ejemplo las variables son enteras, hay tres variables a y b, éstas contienen los valores de entrada tomados desde el teclado y la variable suma, que contendrá el resultado del algoritmo ( suma del contenido de la variable a y b).

En la sección correspondiente al algoritmo en sí, donde comenzaría la parte ejecutable de cualquier lenguaje, encontramos la línea ingresar (a,b) esta sentencia permite tomar valores desde el teclado. La función ingresar puede llevar uno o más variables. Las funciones se reconocen porque a continuación del nombre o identificador de la función se colocan los paréntesis (apertura y cierre). Dentro de los paréntesis, se puede no colocar nada, lo cual estaría indicando que la función no recibe parámetros, es decir no necesita recibir información alguna para realizar la tarea que esta función en particular realiza. Si la función necesita recibir información, o ella devolver información, o ambas cosa, entonces se colocan los parámetros separados por coma, tantos como se necesite.

La sentencia Suma a + b es una sentencia de asignación, por la cual el contenido de memoria llamado a se suma al contenido de memoria llamada b, y su suma se asigna a la variable Suma, tanto a como b conservan los valores que tenían previos a la sentencia de asignación.

La sentencia mostrar (Suma), permite escribir o mostrar por pantalla el contenido de la variable Suma. Mostrar ( ) o escribir ( ) son funciones que permiten mostrar o escribir (es lo mismo) por pantalla el contenido de los parámetros que se coloquen entre los paréntesis.

Finalmente el algoritmo termina cuando se encuentra la palabra reservada fin.

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 40 -

2) Implementar un programa que permita ingresar un número entero por teclado. Se deberá mostrar en pantalla el cuadrado del número ingresado, en la Figura 11 se muestra el diagrama de flujo.

Algoritmo Calcula-cuadrado

var

entero: a,,Resul

inicio

ingresar ( a)

Resul a**2

mostrar (Resul)

fin

inicio

Resula**2

Escribir (Resul)

fin

Figura 11

Leer ( a)

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 41 -

3) Implementar un programa que permita ingresar la longitud de un lado de un cuadrado, medido en centímetros, el algoritmo deberá calcular y mostrar por pantalla la superficie y el perímetro. En la figura 12 se muestra el diagrama de flujo.

Algoritmo Calcula-Per-Super

var

real: lado, Perim, Superf

inicio

mostrar ( ´ingresar el lado del cuadrado en cm´)

ingresar ( lado)

Perim lado * 4

Superf lado ** 2

mostrar (Perim, Superf)

fin

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 42 -

BIBLIOGRAFIA OBLIGATORIA:

“Fundamentos de programación. Algoritmos, Estructuras de datos y Objetos”, Luis Joyanes Aguilar. Mc Graw Hill. Tercera edición. Capítulo 3 (páginas 83 a 125)

inicio

Perim lado *4

Superf lado **2

Escribir (lado)

fin

Figura 12

mostrar (´ingresar el lado en cm´)

Mostrar (Perim, Superf)

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 1 -

Lectura 2: Programación Estructurada Unidad 2: Programación Estructurada

2.1. Estructuras de programación Hay algunas consideraciones muy importantes a la hora de diseñar algoritmos. La legibilidad de los algoritmos y posteriormente de los programas que los codifican, exige que su diseño sea fácil de comprender y su flujo lógico fácil de seguir. La programación modular nos enseña a descomponer un programa en módulos más simples de programar, y la programación estructurada permite la escritura de programas fáciles de leer y modificar. La programación estructurada es una forma de escribir programas de forma clara. Para ello utiliza únicamente tres estructuras: secuencia, selección e iteración o repetitivas Hoy en día las aplicaciones informáticas son mucho más ambiciosas que las necesidades de programación existentes en los años 1960, principalmente debido a las aplicaciones gráficas, por lo que las técnicas de programación estructurada no son suficientes. Ello ha llevado al desarrollo de nuevas técnicas, tales como la programación orientada a objetos y el desarrollo de entornos de programación que facilitan la programación de grandes aplicaciones. A finales de los años 1960 surgió una nueva forma de programar que no solamente daba lugar a programas fiables y eficientes, sino que además estaban escritos de manera que facilitaba su comprensión posterior. El teorema del programa estructurado, fue enunciado y demostrado por Böhm-Jacopini. Este teorema demuestra que todo programa puede escribirse utilizando únicamente tres tipos de instrucciones de control. Solamente con esas tres estructuras se pueden escribir todos los programas y aplicaciones posibles. Si bien los lenguajes de programación tienen un mayor repertorio de estructuras de control, éstas pueden ser construidas mediante tres básicas. En un programa estructurado el flujo lógico se gobierna por las estructuras de control básicas, estas son:

1. Secuenciales. 2. Repetitivas. 3. Selección.

Ventajas de la programación estructurada 1. Los programas son más fáciles de entender, ya que pueden ser leídos de forma secuencial, sin necesidad de hacer seguimiento a saltos de línea (GOTO) dentro de los bloques de código para entender la lógica.

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 2 -

2. La estructura del programa es clara, puesto que las instrucciones están más ligadas o relacionadas entre sí. 3. Reducción del esfuerzo en las pruebas. El seguimiento de los fallos o errores del programa ("debugging") se facilita debido a la estructura más visible, por lo que los errores se pueden detectar y corregir más fácilmente. 4. Reducción de los costos de mantenimiento de los programas. 5. Programas más sencillos y más rápidos (ya que es más fácil su optimización). 6. Los bloques de código son auto explicativos, lo que facilita la documentación. 7. Los GOTO se reservan para construir las instrucciones básicas. Aunque no se usan de forma directa, por estar prohibida su utilización, están incluidas implícitamente en las instrucciones de selección e iteración. 8. Un programa escrito de acuerdo a estos principios no solamente tendrá una mejor estructura sino también una excelente presentación. 9. La programación estructurada ofrece estos beneficios, pero no se la debe considerar como una panacea ya que el desarrollo de programas es, principalmente, una tarea de dedicación, esfuerzo y creatividad.

Inconvenientes de la programación estructurada: El principal inconveniente de este método de programación es que se obtiene un único bloque de programa, que cuando se hace demasiado grande puede resultar problemático su manejo; esto se resuelve empleando la programación modular, definiendo módulos interdependientes programados y compilados por separado (en realidad esto no es necesario, pero es recomendable para su mantenimiento y funcionalidad). En realidad, cuando se programa hoy en día (inicios del siglo XXI) se suelen utilizar, tanto las técnicas de programación estructurada como las de programación modular, de forma conjunta y por lo tanto es posible que cuando uno haga referencia a la programación estructurada esté considerando también las técnicas de modularizaciones.

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 3 -

Un método un poco más sofisticado es la programación por capas, en la que los módulos tienen una estructura jerárquica en la que se pueden definir funciones dentro de funciones o de procedimientos.

2.2. Estructuras secuencial Una estructura secuencial, es aquella en la que una acción (instrucción) sigue a otra en secuencia. Las tareas se desarrollan de tal manera que la salida de una es la entrada de la siguiente y así sucesivamente, hasta alcanzar el final del proceso. La estructura secuencial tiene una entrada y una salida. Su representación gráfica se muestra a continuación junto con la codificación en pseudocódigo:

2.3. Ejercicios usando estructura secuencial. Entrada y salida de información Ej1) Calcular y mostrar por pantalla la suma y el producto de dos números enteros ingresados por teclado. Pseudocódigo: Algoritmo CalcularSumProd Var: entero: a, b, suma, prod //declaración de variables Inicio: Escribir („ingresar dos números enteros‟) // se solicita el ingreso de datos desde el teclado Leer (a,b ) // se toman los valores del teclado y se guardan en las posiciones de memoria //llamadas a y b suma a +b // se realiza la suma de los contenidos de a y b prod a * b // se realiza el producto de los contenidos de las variables a y b

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 4 -

escribir ( ´la suma es:´, suma, ´y el producto es ´, prod) // se muestra por pantalla un mensaje //junto a los valores calculados fin // fin del algoritmo El diagrama de flujo se muestra en la figura 1

Las dos barras inclinadas “//” indican que lo que sigue a continuación de ellas hacia la derecha es un comentario. Ej2) Calcular el salario neto de un trabajador, en función del número de horas trabajadas, precio de la hora de trabajo. Se considerarán descuentos fijos 20% del salario bruto. El salario neto se calcula como el salario bruto menos los impuestos.

Inicio

Escribir („ingresar dos números enteros‟)

Leer (a,b)

suma a +b prod a*b

Escribir („la suma es‟, suma, „y el producto es‟,prod)

fin

Figura 1

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 5 -

Ingresar nombre, precio hora y cantidad de horas, mostrar por pantalla nombre, salario bruto y neto. Pseudocódigo: Algoritmo Calcula_salarios Var: real: precioHora, salBruto, salNeto, impuesto //declaración de variables cadena: nombre real: cantHoras Inicio: // se solicita el ingreso de datos desde el teclado Escribir( ´ingresar nombre, cantidad horas trabajadas, monto por hora ´) Leer (nombre,precioHora, cantHora) salBruto cantHora * precioHora impuesto 0.20* salBruto salNeto salBruto – impuesto escribir ( nombre, salBruto, salNeto) fin // fin del algoritmo El diagrama de flujo se muestra en la figura 2

2.4. Estructura condicional. La especificación formal de algoritmo tiene realmente utilidad cuando el algoritmo requiere una descripción más complicada que una lista sencilla de instrucciones. Este es el caso cuando existe un número de terminado de posibles alternativas resultantes de la evaluación de una determinada condición. Las instrucciones selectivas o de condición, se utilizan para tomar decisiones lógicas, de ahí que también se llaman estructuras de decisión o alternativa Recordemos que una expresión se evalúa como verdadera o falsa. Las estructuras condicionales se clasifican en:

Simples

Dobles

Múltiples Palabras reservadas de esta estructuras son: si entonces fin-si, si entonces si-no fin-si, Según-sea caso de. Estas estructuras establecen distintas posibilidades o caminos a seguir según el resultado de una expresión.

2.5. Condicional simple: Si entonces

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 6 -

Evalúa una expresión, si esta es verdadera ejecuta la acción o acciones especificadas, si es falsa no realiza ninguna acción, es decir se saltean las instrucciones asociadas al si, y se prosigue con la programación. Es decir la estructura alternativa simple si-entonces ejecuta una o varias acciones cuando se cumple determinada condición. Palabras reservadas de esta estructura: si entonces fin-si Pseudocódigo

…… si (expresión lógica) entonces

Inicio

Escribir(„ingresar nombre, cantidad horas trabajadas, monto por hora‟)

Leer (nombre, precioHora, cantHora)

salBruto cantHoras* precioHora impuesto 0.20 * salBruto salNeto salBruto - impuesto

Escribir (nombre, salBruto, salNeto)

fin

Figura 2

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 7 -

sentencia1 sentencia2 sentenciaN fin-si sentencia4 sentencia5 ……… Observar que en el pseudocódigo las acciones que siguen a la palabra reservada, entonces, y las que sigue al si-no, se encuentran indentadas en relación a las palabreas reservadas si y fin-si. Esta forma de escribir aumenta la legibilidad de la estructura y este es el medio más idóneo para representar algoritmos. En la figura 3, se muestra el diagrama de flujo, de esta estructura de selección simple.

2.6. Condicional doble: si entonces si-no fin-si La estructura anterior es bastante limitada y normalmente se necesitará una estructura que permita elegir entre dos opciones o alternativas posibles, en función del cumplimiento o no de una determinada condición Evalúa una expresión lógica, si esta es verdadera ejecuta la acción o acciones especificadas, que se encuentran a continuación de la palabra reservada entonces. Si la expresión lógica resulta ser falsa, se saltean las acciones que se encuentras ubicadas después del entonces, y se ejecutan las acciones asociadas al si-no. Palabras reservadas de esta estructura: si entonces si-no fin-si El pseudocódigo de esta estructura de selección doble es: …… si (expresión lógica) entonces sentencia1 sentencia2 ………. si-no sentencia4 sentencia5 ……… fin-si sentencia 7 sentencia 8 ………. En la figura 4, se muestra el diagrama de flujo de esta estructura de selección doble.

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 8 -

Este tipo de estructura se utiliza cuando el problema se presenta naturalmente dividido claramente en dos posibilidades, por ejemplo preguntarse si un número es primo o no lo es, determinar si un número es par o impar, y cuestiones de este tipo.

Por ejemplo:

1) Desarrollar un algoritmo que permita determinar si un número ingresado por teclado es positivo o negativo. Claramente en este requerimiento, el número ingresado o es positivo o es negativo, no hay otra posibilidad, el problema podría ser el ingreso del número 0, por lo tanto se puede implementar un filtro para impedir el ingreso de este elemento, lo cual se puede hacer por codificación o desplegando un mensaje en pantalla, que advierta al usuario que no debe ingresar el número 0.

Una codificación posible es:

verdadera

falsa Expresión lógica

Sentencia1 Sentencia2 sentenciaN

Sentencia4 Sentencia5 ……………

Figura 3

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 9 -

Algoritmo ClasificaNum Var: entero: num

inicio: mostrar ( „ingresar un número entero que no sea 0‟) leer ( num) si num > 0 entonces mostrar ( „el numero ingresado es positivo‟) si-no mostrar („el numero ingresado es negativo‟) fin si fin EXPLICACION:

verdadera falsa

Expresión lógica

Sentencia1 Sentencia2 ………

Sentencia4 Sentencia5 ……………

Figura 4

Sentencia 7 Sentencia 8 ………

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 10 -

En la sección de declaración de variables, se declara una sola variable de tipo entero llamada num. En la sección de inicio (que se corresponde con la parte que es ejecutable en una codificación de cualquier lenguaje) la función estándar mostrar ( ) despliega una cadena de caracteres (conjunto de caracteres) en la pantalla. A continuación la función estándar leer () permite guardar el dato ingresado desde el teclado en la variable entera num. A continuación comienza la estructura de selección doble, en este caso la expresión lógica que se utiliza para determinar si un número es positivo, consiste en comparar el valor del número ingresado (num) con 0. Si num es mayor que 0 entonces se despliega el mensaje ´el número ingresado es positivo. Si la condición resulta falsa, se despliega el mensaje en pantalla: ´el número ingresado es negativo´. Luego termina la estructura de selección doble con la palabra reservada fin-si. La palabra reservada fin, indica que el algoritmo terminará. El diagrama de flujo, se muestra en la figura 5.

2) Desarrollar un algoritmo que permita determinar si un número ingresado por teclado es par

o impar. En este requerimiento, como el anterior, el número entero ingresado o es par o es impar, no hay otra posibilidad, una situación problemática es el ingreso del número 0, por lo tanto se puede implementar un filtro para impedir el ingreso de este elemento, lo cual se puede hacer por codificación (para lo cual necesitaríamos una estructura repetitiva que aún no se han visto) o desplegando un mensaje en pantalla, que advierta al usuario que no debe ingresar el número 0, emplearemos esta segunda opción. Una codificación posible es: Algoritmo ClasificamParImpar Var: entero: num inicio: mostrar („ingresar un número entero que no sea 0‟) leer ( num) si (num mod 2) = 0 entonces mostrar („el numero ingresado es par‟) si-no mostrar („el numero ingresado es impar‟) fin si fin EXPLICACION: En la sección de declaración de variables, se declara una sola variable de tipo entero llamada num. En la sección de inicio (donde comienza la ejecución) la función estándar mostrar ( ) despliega una cadena de caracteres (conjunto de caracteres) en la pantalla. A continuación la función estándar leer () permite guardar el dato ingresado desde el teclado en la variable entera num.

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 11 -

A continuación comienza la estructura de selección doble, en este caso la expresión lógica que se utiliza para determinar si un número es par, consiste en comparar el resultado de la operación num mod 2 con cero. Recordemos que el operador binario mod determina el resto de una división entera entre num (dividendo) y 2 (divisor). El valor de esta expresión se compara lógicamente con cero. Si el número ingresado fue par el resto de la división entera entre num y 2 da 0 (cero). Este resultado, luego se compara con 0, la comparación da como resultado verdadero, con lo cual se despliega en pantalla un mensaje indicando esta situación. En caso contrario el programa toma el otro camino lógico, desplegando el mensaje opuesto en pantalla.

El rombo en el diagrama de flujo, muestra un punto de bifurcación en el programa.

El diagrama de flujo, se muestra en la figura 6.

2.7. Alternativa múltiple: Según… en caso de. Es bastante común tener situaciones donde se deba elegir entre más de dos alternativas. L estructura de decisión múltiple evaluará una expresión que podrá tomar n valores distintos, 1, 2, 3,…n. Según que se elija uno de estos valores en la condición, se realizará una de las n acciones.

verdadera falsa

Expresión lógica

Sentencia1 Sentencia2 ………

Sentencia4 Sentencia5 ……………

Figura 5

Sentencia 7 Sentencia 8 ………

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 12 -

Esta expresión requiere una variable, que solo puede ser entera o de tipo carácter, con la cual se controla cual es el camino que se va a elegir. Según el valor que asuma esta variable, será el

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 13 -

verdadero falso num > 0

Mostrar (él número ingresado es positivo´)

Figura 6

inicio

Ingresar (num)

Mostrar (´Ingresar un número entero que no sea 0´)

Mostrar (el numero ingresado es negativo

fin

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 14 -

camino lógico que se seguirá. También es posible que el contenido de esta variable no sea igual a ninguno de los valores que expresamente se indique en los casos, en esta situación, el flujo del programa realiza las acciones asociadas al si-no, si esta palabra reservada se decide usar. La codificación en pseudocódigo es: …… Según-sea opción hacer caso op1: accion1 accion2 …. caso op2: accion3 accion4 …. ……. caso opN: accionN1 accionN2 …. si-no: accion5 accion6 fin-segun ………. El diagrama de flujo se muestra en la figura 7. A continuación se presentan algunos ejemplos de esta estructura selectiva. Ej1) Se desea implementar un algoritmo que escriba por pantalla el nombre del día de la semana, según cuál sea el valor que una variable de tipo entero introducido por teclado. Una posible codificación puede ser la siguiente: Pseudocódigo Algoritmo DiaSemana

Var: entero: opcion inicio: mostrar („ingresar un número entero entre 1 y 7‟) leer (opción)

según-sea opción hacer caso 1: mostrar („DOMINGO‟) caso 2: mostrar („LUNES‟) caso 3: mostrar („MARTES‟) caso 4: mostrar („MIERCOLES‟) caso 5: mostrar („JUEVES‟) caso 6: mostrar („VIERNES‟) caso 7: mostrar („SABADO‟) si-no: mostrar („ERROR‟) fin-según fin

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 15 -

EXPLICACION: Se declara una variable entera llamada opción. Los valores posibles para esta variable son: 1, 2, 3, 4, 5, 6 y 7. Si el usuario llegase a introducir un valor distintos de estos, se ejecutaría la acción correspondiente al si-no, es decir se mostraría por pantalla el mensaje ERROR. Por ejemplo si el usuario introduce por teclado el entero5 entonces se mostrará por pantalla el mensaje: JUEVES, y luego terminará el programa. En la figura 8 se muestra el diagrama de flujo. Ej2) Se desea implementar un algoritmo que permita ingresar por teclado un número comprendido entre 1 y 10 (inclusive) y que el algoritmo determine si el número entero ingresado es par o impar. Luego de la comprobación se mostrará por pantalla un mensaje indicando si el número fue par o impar. Si el número que se ingresa no está comprendido en el intervalo cerrado que se pide, terminar el programa indicando por pantalla tal situación. Una posible codificación puede ser la siguiente: Pseudocódigo Algoritmo ParImpar Var: entero: dato

si-no

op2 opN

op1

opcion

accionN1 accionN2 ………

accion1 accion2 ……

Figura 7

accion3 accion4 ………

accion6

accion7

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 16 -

7

6

5

4

si-no

2

3

1

opcion

Mostrar

(´MARTES´)

Mostrar (´DOMINGO´)

Figura 8

Mostrar

(´LUNES´)

Mostrar

(ÉRROR´)

inicio

Mostrar (‘ingresar un

número entero entre 1

y 7’)

Leer (opción)

Mostrar

(´MIERCOLES´)

Mostrar

(´JUEVES´)

Mostrar

(´SABADO´)

Mostrar

(´VIERNES´)

fin

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 17 -

inicio: mostrar ( „ingresar un número entero entre 1 y 10‟) leer (dato) si dato > = 1 y dato < = 10 entonces según-sea dato hacer caso 1, 3, 5, 7, 9: mostrar („impar‟) caso 2, 4, 6, 8, 10: mostrar („par‟) fin-según si-no mostrar(„error‟) fin-si fin EXPLICACION: Se declara una sola variable entera, dato. Se usa la función mostrar ( ) para desplegar por pantalla un mensaje que solicita el ingreso de un número entero en el intervalo cerrado de 1 a 10. La función leer ( ) permite capturar el ingreso del usuario y guardar ese calor en la variable dato. A continuación hay una estructura selectiva doble, esta estructura lo que permite es procesar el programa si el número introducido está dentro del intervalo pedido, para ello se construye la siguiente expresión: dato > = 1 y dato < = 10 la expresión completa da verdadera cuando dato es mayor o igual 1 y a su vez ( simultáneamente) dato es menor o igual a 10.Obeservar que dato se compara dos veces ( una vez por cada extremo del intervalo), entre ambas comparaciones se encuentra el operador ´y´ ( conjunción). Este operador binario, da como resultado verdadero cuando ambas partes son verdaderas, caso contrario, es decir una de las partes de la comparación o ambas partes de la comparación son falsas, el resultado final del operador “y” da falso. Entonces, habiendo introducido un número válido, se pasa a la estructura de selección múltiple según-sea caso fin-según. El caso de aplicación de esta estructura, es poco común. Se utilizan dos casos, en uno de ellos se colocan todos los valores impares separados por coma, y en el otro caso se colocan los números pares del intervalo separados por coma. Es importante destacar el anidamiento de estructuras, que tiene este ejercicio, lo cual lo hace muy interesante para el análisis. El siguiente código: Si ……….. entonces Según-sea ……. hacer //……… Fin-según Fin-si Representa un anidamiento, hay una estructura dentro de otra. No es un anidamiento doble. Cantidad de estructuras en cascada (cualquiera sea su tipo) -1 = numero de anidamientos.

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 18 -

Ej3) Se desea implementar un algoritmo que permita ingresar por teclado un número comprendido entre 1 y 7 (inclusive) correspondiente al día de la semana (1 representa Domingo). El algoritmo determinará si el número entero ingresado está o no en el intervalo válido. Luego de la comprobación se mostrará por pantalla un mensaje indicando mediante una cadena de caracteres el día que representa el número ingresado. Si el número que se ingresa no está comprendido en el intervalo cerrado que se pide, terminar el programa indicando por pantalla tal situación. Una posible codificación puede ser la siguiente: Pseudocódigo Algoritmo Dia_Semana Var: entero: dia inicio: mostrar ( „ingresar un número que represente día de la semana‟) leer (dia) según-sea dia hacer caso 1: mostrar („domingo‟) caso 2: mostrar („lunes‟) caso 3: mostrar („martes‟) caso 4: mostrar („miércoles‟) caso 5: mostrar („jueves‟) caso 6: mostrar („viernes‟) caso 7: mostrar („sábado‟) si-no: mostrar („error‟) fin-según fin EXPLICACION: Se declara una sola variable entera, dia. Se usa la función mostrar ( ) para desplegar por pantalla un mensaje que solicita el ingreso de un número entero en el intervalo cerrado de 1 a 7. La función leer ( ) permite capturar el ingreso del usuario y guardar ese valor en la variable día. Entonces, habiendo introducido un número, se pasa a la estructura de selección múltiple según-sea caso fin-según. Se utilizan 7 casos, uno por cada día de la semana y un si-no para que entre por este punto de bifurcación, cuando el número ingresado no esté comprendido entre 1 y 7.

2.8. Ejercicios de aplicación. Ej1) Se desea implementar un algoritmo que permita ingresar por teclado un número comprendido entre 1 y 10 (inclusive) y que el algoritmo determine si el número entero ingresado es múltiplo de dos. Luego de la comprobación se mostrará por pantalla un mensaje indicando el resultado. Si el número que se ingresa no está comprendido en el intervalo cerrado que se pide, terminar el programa indicando por pantalla tal situación. Una posible codificación puede ser la siguiente:

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 19 -

Pseudocódigo Algoritmo Procesa_numero Var: entero: dato inicio: mostrar ( ´ingresar un número entero entre 1 y 10‟) leer (dato) si dato > = 1 y dato < = 10 entonces si dato mod 2 = 0 entonces mostrar („el número ingresado es par y está en el intervalo de 1 a 10‟) si-no mostrar („el número es impar y está comprendido en el intervalo de 1 a 10‟) fin-si si-no mostrar(„error‟) fin-si fin Ej2) Se desea implementar un algoritmo que permita ingresar por teclado tres números A, B, C enteros y que muestre por pantalla el número más grande. Una posible codificación puede ser la siguiente: Pseudocódigo Algoritmo Muestra _mayor Var: entero: A, B, C, Mayor inicio: mostrar ( „ingresar tres números enteros‟) leer (A, B, C) si A > B entonces si A > C entonces mayor A si-no mayor C fin-si si-no si B > C entonces mayor B si-no mayor C fin-si fin-si mostrar („el mayor número es: „, mayor) fin

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 20 -

Ej3) Implementar un programa que permita mostrar por pantalla un menú con las opciones: 1 sumar, 2 multiplicar. Se tomará desde el teclado dos números enteros. El usuario ingresará un entero correspondiente a la operación que quiere realizar. Una posible codificación puede ser la siguiente: Pseudocódigo Algoritmo Menu_suma_mul Var: entero: dato1, dato2, opción, resul inicio: mostrar ( ´que operación desea realizar: 1 suma- 2 multiplicar´) leer (opcion) según-sea opcion hacer caso 1: mostrar (´ingresar dos números enteros para sumar´) leer ( dato1, dato2) resul dato1 +dato2 mostrar (´la suma es : ´, result) caso 2: mostrar (´ingresar dos números enteros para multiplicar´) leer ( dato1, dato2) result dato1 * dato2 mostrar (´la multipliocacion es:´, result) si-no: mostrar (´error´) fin-según fin Ej4) Implementar un programa que permita determinar si dos números ingresados por teclado están ordenados en forma creciente. Mostrar un mensaje por pantalla de esta situación se da. Una posible codificación puede ser la siguiente: Pseudocódigo Algoritmo Determina_orden Var: entero: dato1, dato2 inicio: mostrar ( ´ingresar dos números enteros´) leer (dato1, dato2) si dato1 < > dato2 entonces si dato1 < dato2 entonces mostrar (´los números fueron ingresados en forma ordenada de menor a mayor´) si-no mostrar (´los números fueron ingresados en forma ordenada de mayor a menor´) fin-si si-no mostrar (´los números ingresados son iguales´)

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 21 -

fin-si fin Ej5) Implementar un programa que permita leer 4 números enteros por teclado, y muestre su promedio por pantalla. Una posible codificación puede ser la siguiente: Pseudocódigo Algoritmo DeterminaPromedio Var: entero: dato1, dato2, dato3, dato4 real: prom inicio: mostrar ( ´ingresar cuatro números enteros´) leer (dato1, dato2, dato3, dato4) prom dato1 +dato2+dato3 +dato4 mostrar (´el promedio es:´, prom) fin Ej6) Realizar un algoritmo que determine si dos números introducidos por teclado uno de ellos es divisor del otro. Una posible codificación puede ser la siguiente: Pseudocódigo Algoritmo Determina_Divisibilidad Var: entero: dato1, dato2 inicio: mostrar ( ´ingresar dos números enteros´) leer (dato1, dato2) si dato1 > dato2 entonces si (dato1 mod dato2) = 0 entonces mostrar (´los números son divisibles´) si-no mostrar (´los números no son divisibles´) fin-si si-no si (dato2 mod dato1) = 0 entonces mostrar (´los números son divisibles´) si-no mostrar (´los números no son divisibles´) fin-si fin-si fin

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 22 -

Bibliografía obligatoria para la unidad 2: “Fundamentos de programación. Algoritmos, Estructuras de datos y Objetos”, Luis Joyanes Aguilar. Mc Graw Hill. Tercera edición. Capítulo 4 (páginas 131 a 162).

Unidad 3: Programación Estructurada: Estructura repetitiva

3.1. Concepto de estructura de repetición Hasta ahora hemos trabajado, instrucciones de entrada, salida, expresiones y operadores, asignaciones, instrucciones secuenciales y de selección. Hay una gran variedad de situaciones que requieren que una o varias instrucciones se repitan varias veces, ya sean cálculos u otro tipo de instrucciones. Las instrucciones iterativas o de repetición, abren la posibilidad de realizar una secuencia de instrucciones más de una vez. En este capítulo estudiaremos las distintas formas que existen en pseudocódigo, para lograr la repetición de al menos una instrucción. 3.2. Concepto de bucle e iteración Un bucle, es una sección de código que se repite. Es decir cuando se termina de ejecutar la última instrucción del conjunto, el flujo de control retorna a la primera sentencia y comienza una nueva repetición de las sentencias que forman esa sección de código. Se denomina iteración al hecho de repetir la ejecución de una secuencia de acciones, la iteración se asocia a un número entero que indica el número de veces que se repite un trozo de código. Por ejemplo si se desea sumar notas de alumnos, se necesitan dos sentencias, una para leer desde el teclado la nota, y otra que realice sumas parciales, es decir: ……. Suma 0 // se inicializa una sola vez // sentencias que se repiten Leer ( nota) Suma suma + nota Es necesario conocer alguna manera de detener la repetición, ya sea que se conozca el número de notas a procesar, para este ejemplo, o por medio de una expresión o condición que se va modificando dentro del bloque de sentencias que forman el bucle. De lo contrario la iteración no acabaría nunca.

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 23 -

3.3. Concepto de acumulador Un acumulador es un campo de memoria dinámica cuyo valor se incrementa sucesivas veces en cantidades variables. Se utiliza en aquellos casos en que se desee obtener un total de un conjunto de cantidades, siendo preciso inicializarlo a cero. También puede utilizarse en aquellas situaciones en las que hay que obtener un total como producto de distintas cantidades, en este caso hay que inicializar la variable a 1. En el ejemplo de las notas de los alumnos de un curso, si se desease calcular el promedio de notas en ese curso, la variable suma, representa un acumulador: Suma 0 // se inicializa una sola vez //sentencias que se repiten Leer (nota) Suma suma + nota Tener presente que la variable acumulador suma, se inicializa a 0.

3.4. Concepto de contador Un contador es un campo de memoria dinámica cuyo valor se incrementa en una cantidad fija, positiva o negativa, y generalmente asociado a un bucle. En general un contador se utiliza:

Para contar el número de veces que es necesario repetir una acción ( variable de control de un bucle)

Para contar un suceso en particular solicitado por los requerimientos del problema (asociado a un bucle o independientemente).

Un contador toma un valor inicial (0, en la mayoría de los casos) antes de comenzar su función, y cada vez que se presenta el suceso a contar, se incrementa su valor ( 1 en la mayoría de los casos). Tanto el acumulador como el contador, son variables que realizan funciones específicas dentro de un programa.

3.5. Estructura repetir hasta Esta estructura repetitiva se utiliza cuando se desea que al menos un bloque se ejecute una vez, antes de comprobar la expresión de repetición. Es decir el bucle se ejecuta primero y luego se comprueba le expresión para producir una nueva repetición o no del bucle. El bucle repetir /hasta-que, se repite mientras el valor lógico de la expresión booleana sea falsa. El pseudocódigo de esta estructura se muestra a continuación:

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 24 -

…………….. repetir // sentencia1 // sentenciaN hasta que <expresión> ……… El diagrama de flujo de esta estructura se muestra en la figura 9.

Un uso muy frecuente de este tipo de estructura, es la validación de datos. Por ejemplo un programa necesita procesar edades, entonces se solicita el ingreso de la edad, y mediante una estructura repetir/hasta-que se solicita ingresos de números que representen una edad válida, es decir si el usuario introduce 999, el programa desplegará un mensaje de error por pantalla y solicitará un nuevo ingreso de dato, y seguirá en esta situación hasta que se introduzca un valor de edad válido, por ejemplo un número entero comprendido entre 1 y 120.

3.6. Resolución de problemas usando repetir/hasta-que Ejemplo 1) Se desea implementar un programa que permita ingresar solo números enteros positivos, el programa mostrará por pantalla el promedio de los 10 número enteros positivos ingresados desde el teclado.

verdadera

falsa

expresión

Figura 9

sentncia1 …………… sentenciaN

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 25 -

Una posible codificación podría ser: Algoritmo CalculaPromedio Var: entero: cont, num, suma real: prom inicio: cont 0 suma 0 repetir cont cont + 1 repetir mostrar ( ´ingresar número entero mayor a cero´) leer (num) hasta-que num > = 0 suma suma + num hasta-que cont > = 10 prom suma / 10 mostrar ( “ el promedio es: “, prom) fin EXPLICACION: Este ejercicio tiene algunas cuestiones interesantes. Tiene dos estructuras repetir/hasta-que anidadas. La estructura repetir (hasta-que más externa, es la que controla que se sumen los primeros 10 números enteros positivos. La estructura repetir/hasta-que interna controla que el número ingresado sea mayor a 0, es decir que sea positivo. Si el número que se introduce no es mayor a 0, entonces la condición de la estructura repetitiva es falsa y el bucle se repite, es decir se pide un nuevo ingreso de dato desde el teclado; si por el contrario el dato introducido es mayor a 0, la condición es verdadera y por lo tanto el bucle no se repite, se prosigue con el aumento del contador, la acumulación en la variable suma. Otro aspecto interesante es que utiliza dos variables con funciones específicas, cont como contador, y suma como acumulador. Ejemplo 2) Se desea implementar un programa que permita ingresar solo letras mayúsculas. El programa mostrará por pantalla las 20 primeras letras mayúsculas introducidas por teclado. Una posible codificación podría ser: Algoritmo MuestraMayúsculas Var: entero: cont caracter: letra inicio: cont 0 repetir cont cont + 1 repetir mostrar ( ´ingresar letra mayúscula´)

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 26 -

leer (letra)

hasta-que (letra > = „A‟ y letra <= „Z‟) mostrar („letra‟) hasta-que cont > = 20 fin EXPLICACION: Para realizar este programa necesitamos dos variables de distinto tipo, una de tipo entero: cont, para contar la cantidad de letras mostradas por pantalla (deben ser 20); otra, de tipo carácter para guardar el ingreso que realice el usuario desde el teclado. Hay dos estructuras repetir/hasta-que anidadas, esto significa que una se ejecuta dentro de la otra. La estructura repetir/hasta-que externa, es la que permite que se muestren las 20 letras por pantalla. La estructura repetir/hasta-que interna, es la que valida que el carácter ingresado por teclado sea una letra mayúscula, en esta estructura la expresión que controla la iteración es una expresión de tipo y ó and. Recordemos que esta expresión solo da un resultado booleano verdadero, cuando ambas partes de la comparación son verdaderas. La expresión: letra > = „A‟ y letra <= „Z‟, establece un intervalo cerrado. Si el usuario introduce una letra mayúscula, entonces esta expresión da como resultado verdadera y el bucle interno no se repite, si por el contrario, el usuario introduce una letra minúscula, está estará fuera del intervalo y la expresión dará un resultado booleano falso, con lo cual el bucle se repite. Además si el usuario ingresa un carácter que no sea letra (ni mayúscula ni minúscula) el bucle interno se repite, y como puede apreciarse el contador (variable cont) no se incrementa. Ejemplo 3) Desarrolla un algoritmo que permita calcular el factorial de un número N que responde a la fórmula: N! = N * (N-1) * (N-2) … 2* 1 3! = 3 * 2 * 1 = 6 5! = 5 * 4 * 3 * 2 * 1= 120 Solo existe el factorial de números enteros igual o mayor que 0 El factorial de un número es otro número. Por convención matemática el factorial de 0! Es 1, y el factorial de 1! También es 1. Una posible codificación podría ser: Algoritmo CalculaFactorial Var: entero: num, cont real: fact inicio: mostrar ( „ingresar un número a calcular su factorial‟) // no se realiza la validación ingresar ( num) si num = 0 o num =1 entonces

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 27 -

fact 1 si-no fact num cont num-1 repetir fact fact * cont cont cont -1 hasta-que cont < =1 fin-si mostrar („El factorial de: „,num, „es:‟ fact) fin EXPLICACION: En este ejercicio se ha omitido la validación del dato de entrada, es decir no se verifica que el usuario ingrese un número mayor o igual a cero. El usuario no puede ingresar un número negativo, en primer lugar porque no existe el factorial de un número negativo y en segundo lugar el algoritmo calcularía cualquier cosa. El factorial del número que ingrese el usuario se calcula y guarda en la variable real fact, no se utiliza un entero, porque el tipo de dato real puede almacenar valores o cifras más grandes que los enteros (recordar que el tipo de dato real, no solo es para valores decimales, también es específico de los enteros grandes). La estructura de selección doble se la utiliza para diferenciar el caso en el cual el usuario introduzca el 1 ó el número 0, en ambos casos por convención matemática su factorial es igual a 1, por lo tanto no hay que realizar cálculo alguno. Para cualquier otro número, debe emplearse la fórmula matemática ya mencionada. Dentro del si-no, está la iteración para realizar el cálculo que implica la expresión matemática del factorial de un número. El mismo algoritmo puede ser realizado con un contador que se incrementa en lugar de usar decrementos. La expresión matemática es: 5!= 1 * 2 * 3 * 4 *5= 120 La versión con contador que se incrementa es: Algoritmo CalculaFactorial Var: entero: num, cont real: fact inicio: mostrar ( „ingresar un número a calcular su factorial‟) // no se realiza la validación ingresar ( num) si num = 0 o num =1 entonces fact 1 si-no

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 28 -

fact 1 cont 1 repetir fact fact * cont cont cont +1 hasta-que cont > num fin-si mostrar („El factorial de: „,num, „es:‟ fact) fin

3.7. Estructura mientras El bucle se repite mientras la expresión P sea cierta (verdadera), si al llegar por primera vez al bucle mientras la condición es falsa, el cuerpo del bucle no se ejecuta ninguna vez. El diagrama de flujo de esta estructura se muestra en la figura 10. En pseudocódigo la estructura mientras tiene la siguiente forma: ……… mientras <expresión P> hacer //sentencia1 ……. //sentenciaN fin-mientras …….. Tener presente que primero se evalúa la expresión P, si esta es verdadera, entonces se ejecutan el conjunto de sentencias asociadas al mientras, la ejecución del bucle se repite siempre que la expresión de cómo resultado booleano: verdadero. Con cada nueva iteración, la expresión vuelve a evaluarse. Es importante tener claro que si se desea que la iteración acabe en la expresión asociada al mientras debe haber alguna variable que cambie dentro del bucle, de lo contrario se corre el riesgo de generar estructuras repetitivas que no acaban nunca. A esto se le llama bucle infinito. A veces se desea generar bucles infinitos, por algún requerimiento del problema.

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 29 -

Existen dos cuestiones particulares: ejecución de un bucle cero veces y ejecución de bucles infinitos. EJECUCION DE UN BUCLE CERO VECES: Como lo primero que ocurre en una estructura mientras/fin-mientras es la evaluación de la expresión, si esta llegará a ser falsa la primera vez que se ingrese a esta estructura, entonces las sentencias asociadas al bucle, nunca se ejecutarían. Por ejemplo: …….. inicio dato1 5 dato2 1 mientras dato2 > dato1 hacer leer ( t) mostrar (t) dato2 dato2 + 1 fin-mientras ….. Las sentencias: leer ( t) mostrar (t) dato2 dato2 + 1 no se ejecutan nunca, pues dato1 contiene el entero 5 y dato2 contiene el entero 1, claramente dato2 NO ES MAYOR que dato1. No hay iteración. BUCLES INFINITOS Algunos bucles no tienen fin, porque así se los elabora. Esto dependerá de los requerimientos del problema a resolver.

verdadera

falsa P

Figura 10

sentencia1 …………… sentenciaN

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 30 -

Un bucle que nunca se termina se denomina bucle infinito o sin fin. Los bucles sin fin no intencionados son perjudiciales para la programación y se deben evitar siempre. Un ejemplo de bucle infinito es el siguiente: ……………. inicio dato1 5 dato2 1 mientras 1 hacer leer ( t) mostrar (t) dato2 dato2 + 1 mostrar (dato2) fin-mientras ….. La expresión asociada al mientras en este ejemplo es 1. El número 1 (uno) es siempre verdadero, por lo tanto este bucle no acaba nunca. NOTA IMPORTANTE: Las pruebas o test en la expresiones booleanas es conveniente que sean mayor o menor que ( > ó >) en lugar de pruebas de igualdad o desigualdad. Son más seguras, y en especial en un lenguaje en particular, en especial si las variables involucradas son de tipo real.

3.8. Resolución de problemas usando Mientras Ejemplo 1) Se desea implementar un programa que permita ingresar dos número enteros positivos: X y N. El programa deberá calcular y mostrar por pantalla, la N-ésima potencia de X. Una posible codificación podría ser: Algoritmo CalculaProtencia Var: entero: X, N real: pot inicio: pot 1 repetir mostrar („ ingresar la base y el exponente de la potencia a calcular) leer ( X, N) hasta-que (X>=1 y N > -1) mientras N > 0 hacer pot pot * X N N -1 fin-mientras mostrar ( ´La potencia de base:‟, X, „ y exponente: „, N, „es:‟, pot) fin

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 31 -

Ejemplo 2) Se desea implementar un programa que permita obtener el producto de dos números enteros positivos, ingresados por teclado, mediante el algoritmo de sumas sucesivas. El programa mostrará por pantalla el producto. 2x3= 2 + 2+ 2+ 2 =6 2 x 3 = 3 + 3 = 6 Una posible codificación podría ser: Algoritmo CalculaProducto Var: entero: A,B, acum inicio: mostrar ( „ingresar dos números enteros positivos‟) leer (A,B) acum 0 mientras A < > 0 hacer acum acum + B A A -1 fin-mientras mostrar ( acum) fin Ejemplo 3) Se desea implementar un programa que permita obtener el cociente de dos números enteros positivos, ingresados por teclado, mediante el algoritmo de restas sucesivas. El programa mostrará por pantalla el producto. Se muestra el algoritmo con ejemplos numéricos: a) 10 / 5 Primera resta 10-5 =5 N =1 Segunda resta 5-5 = 0 N = N +1 = 2 Por lo tanto cociente es 2 ( el valor de N) y el resto es 0 b) 10/4 10 > 4 Primera resta 10 - 4 = 6 acum = 1

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 32 -

6 > 4 Segunda resta 6 - 4 = 2 acum = acum + 1 = 2 2 > 4 FALSO el proceso termina Por lo tanto el cociente es 2 (valor de acum) y el resto es 2 (resultado de la última resta) Una posible codificación podría ser: Algoritmo CalculaCociente Var: entero: A,B, acum inicio: mostrar ( „ingresar dos números enteros positivos‟) leer (A,B) acum 0 mientras A > B hacer acum acum + 1 A A - B fin-mientras mostrar ( „ el cociente es.‟, acum, y el resto de la división es:‟, A) fin

3.9. Estructura Para En muchas ocasiones se conoce de antemano el número de veces que se desea que un bucle se repita. Una estructura de control muy común es el ciclo para o desde, esta estructura por lo tanto, se usa especialmente cuando se desea iterar un número conocido de veces, empleando como índice una variable que se incrementa o decrementa en forma automática, según el paso elegido.

En pseudocódigo esta estructura tiene la forma de: desde v vi hasta vf inc/dec paso hacer // acciones …………….. fin-desde o también puede escribirse con el para para v vi hasta vf inc/dec paso hacer // acciones …………….. fin-para

En cualquiera de las dos formas, v es una variable entera, que debe ser declarada en el programa en la sección var. Los valores vi y vf son los valores inicial y final que tomará automáticamente la variable v. En el formato de esta estructura hay que elegir entre incrementar o decrementar la variable de control v. No puede ocurrir al mismo tiempo ambas situaciones.

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 33 -

Se puede obviar la palabra inc cuando el incremento sea de1. Cuando se desee decrementar la variable de control de la estructura siempre deberá aparecer la palabra dec (aunque el decremento sea en 1). En la estructura para/desde, paso, representa el valor a sumar o restar del valor inicial de la variable de control de la estructura, en nuestro caso de la variable v. La presentación de algunas situaciones aclarará lo expresado anteriormente.

desde v 1 hasta 5 hacer // acciones …………….. fin-desde

En este caso la variable v se inicializa en 1, y luego de ejecutar todas las sentencias que estén comprendidas dentro de la estructura (bucle), automáticamente la variable v se incrementa en 1. Cuando iteración tras iteración, la variable de control v alcance el valor v = 6 no se realizan más iteraciones, y se prosigue con la próxima instrucción que esté a continuación del fin-desde.

desde v 5 hasta 9 hacer // acciones …………….. fin-desde Tiene el mismo efecto, que el caso anterior. El bucle se repite 5 veces, la variable de control se inicializa en 5, y bucle tras bucle se va indexando de 1, cuando v = 10 se saltea el bucle de la estructura desde y se prosigue con la próxima instrucción después del fin-desde.

desde v 1 hasta 5 inc 2 hacer // acciones …………….. fin-desde

En este caso, la variable se inicializa en 1 y con la ejecución de cada bucle se incrementa en 2, con el primer valor de v que supere el valor 5, se finaliza la iteración. En este caso v toma los valores 1, 3, 5, por lo tanto el bucle se repite 3 veces.

desde v 10 hasta 2 dec 2 hacer // acciones …………….. fin-desde

En este caso, la variable se inicializa en 10 y con la ejecución de cada bucle se decrementa en 2, con el primer valor de v que sea inferior a el valor 2, se finaliza la

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 34 -

iteración. En este caso la variable v toma los valores 10,8, 6, 4 y 2 por lo tanto el bucle se repite 5 veces.

Es importante recalcar que el pseudocódigo no es un lenguaje estandarizado. Eso significa que diferentes autores podrían dar otras estructuras de control o bien usar estas mismas estructuras, pero con una notación diferente. Sin embargo, las funciones matemáticas y lógicas toman el significado usual que tienen en matemática y lógica, con las mismas expresiones. EQUIVALENCIA ENTRE LAS ESTRUCTURAS REPETITIVAS Las estructuras repetitivas hasta aquí vistas son equivalentes unas con otras. Dependiendo del problema a solucionar, es posible que alguna de las estructuras de repetición se adapte más fácilmente que otra al mismo problema. Pero siempre es posible reemplazar una de ellas por otras, con algunas variantes sencillas, por ejemplo si se deseara acular en una variable la suma de los 10 primeros números enteros positivos que ingresa un usuario desde el teclado, podríamos tener los siguientes códigos:

a) Usando estructura mientras/fin-mientras …… inicio suma 0 cant 1 mientras cant <= 10 hacer leer ( dato) suma suma + dato cant cant + 1 fin-mientras mostrar ( suma) ……..

b) Usando estructura repetir/hasta-que …… inicio suma 0 cant 1 repetir leer ( dato) suma suma + dato cant cant + 1 hasta-que cant >10 mostrar ( suma) ……..

c) Usando la estructura desde/fin-desde

…… inicio suma 0 desde cant 1 hasta 10 hacer leer ( dato) suma suma + dato

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 35 -

fin-desde mostrar ( suma) ……..

ESTRUCTURAS REPETITIVAS ANIDADAS De igual forma que se puede anidar o encajar estructuras de selección, es posible insertar un bloque dentro de otro. Las reglas para construir estructuras repetitivas anidadas son iguales en ambos casos: la estructura interna debe estar totalmente incluida dentro de la externa y no puede bajo ningún aspecto existir solapamiento. En la figura 11 se muestran bucles correctamente anidados, mientras que en la figura 12 se muestran anidamientos incorrectos.

3.10. Resolución de problemas usando Para A continuación se presentarán algunos programas a modo de ejemplo del uso de esta estructura repetitiva. Ejercicio 1) Se dispone de una lista de N números ingresados por teclado, se desea determinar y mostrar por pantalla el valor del número mayor que se haya ingresado. Una posible codificación podría ser:

Algoritmo DeterminaMayor Var entero: N, cant real: dato, mayor

b) a)

Figura 11

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 36 -

inicio leer (N) leer ( dato) mayor dato desde cant 2 hasta N hacer leer ( dato) si mayor < dato entonces mayor dato fin-si fin-desde mostrar ( mayor)

fin Ejercicio 2) Se dispone de una lista de N números ingresados por teclado, se desea determinar y mostrar por pantalla el valor del número mayor y del menor que se hayan ingresado al mismo tiempo. Una posible codificación podría ser:

Algoritmo DeterminaMayor_Menor Var entero: N, cant real: dato, mayor, menor

a) b)

Figura 12

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 37 -

inicio leer (N) leer ( dato) mayor dato menor dato desde cant 2 hasta N hacer leer ( dato) si mayor < dato entonces mayor dato fin-si si menor > dato entonces menor dato fin-si fin-desde mostrar ( mayor, menor)

fin Ejercicio 3) Se leen desde el teclado 100 números, se desea determinar y mostrar por pantalla la media de los números positivos y la media de los números negativos que se hubiesen ingresado, al mismo tiempo. Una posible codificación podría ser:

Algoritmo DeterminaMedia_Positivos_Negativos Var entero: cantP, cantN, total real: dato, sumaPos, sumaNeg inicio cantP 0 cantN 0 sumaPos 0 sumaNeg 0 desde total 1 hasta 100 hacer leer ( dato) si dato > 0 entonces cantP cantP+1 sumaPos sumaPos + dato fin-si si dato < 0 entonces sumaNeg sumaNeg + dato cantN cantN + 1 fin-si fin-desde mostrar ( „la media de los valores negativos es: „,sumaNeg/cantN) mostrar ( „la media de los valores positivos es:‟, sumaPos/cantN)

fin

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 38 -

3.11. Ejercicios de aplicación. Ahora se realizarán ejercicios variados con las estructuras repetitivas vistas: Ejemplo1) Se desea leer las calificaciones de N alumnos de una clase de Informática. Y se desea contar la cantidad de alumnos aprobados (nota 5 o mayor a 5). Una posible codificación puede ser:

Algoritmo DeterminaNumero_Aprobados Var entero: N, cant, nota, cantApro inicio leer (N) // cantidad de alumnos cantApro 0 desde cant 1 hasta N hacer leer ( nota) si nota > = 5 entonces cantAmayor cantApro + 1 fin-si fin-desde mostrar ( cantApro)

fin Ejemplo 2) Mostrar por pantalla solamente las letras mayúsculas ingresadas por teclado. Realizar 20 ingresos. Una codificación puede ser:

Algoritmo MuestraMayúsculas Var caracter: dato entero: cant inicio cant 0 repetir leer ( dato) si (dato > = „A‟ y dato < = „Z‟) o (dato > = „a‟ y dato < = „z‟) entonces mostrar ( dato) fin-si cant cant +1 hasta-que cant > = 20 fin

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 39 -

Ejemplo 3) Realizar 50 ingresos de caracteres por teclado. Si el carácter ingresado, es una minúscula mostrarla por pantalla, si la letra es mayúscula convertirla a minúscula para luego mostrarla por pantalla. Una codificación puede ser:

Algoritmo MuestraMinúsculas Var caracter: dato entero: cont inicio cont 0 repetir leer ( dato) si (dato > = „a‟ y dato < = „z‟) entonces mostrar ( dato) fin-si si (dato > = „A‟ y dato < = „Z‟) entonces dato dato + 32 mostrar (dato) fin-si cont cont +1 hasta-que cant > = 50 fin

EXPLICACION: Los caracteres se almacenan en memoria mediante una codificación en 0 y 1. A cada carácter le corresponde un número entero que se representa en código ASCII. La tabla ASCII, contiene números enteros con los que se corresponden las letras minúsculas, las mayúsculas, los números (de 0 a 9), los signos de puntuación, etc. Las letras mayúsculas les corresponden números enteros consecutivos, la letra A mayúscula le corresponde el número 65, la letra B el 66, la letra C el 67 y así hasta llegar a la letra Z mayúscula. A las letras minúsculas, también les corresponden números enteros consecutivos. La letra a minúscula le corresponde el número 97, la letra b el 98, la letra c el 99 y así hasta llegar a la letra z minúscula. Para la misma letra, mayúscula y minúscula, existe una constante igual a 32. Es decir entre la A y la letra a minúscula existen 32 posiciones de la tabla. Lo mismo ocurre para la letra B y b. Cuando la letra se coloca entre comillas simple, se está haciendo referencia al número entero que representa su codificación en ASCII. Por lo tanto no es necesario recordar la constante 32, basta con saber la siguiente relación …… Var

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 40 -

entero: cont . ……… cont „a‟ – „A‟ // cont contiene 32 cont „t‟ – „T‟ // cont contiene 32 y así para cualquier letra mayúscula y minúscula. Entonces, cuando la estructura selectiva si/si-no detecta en la expresión que el carácter ingresado es una letra mayúscula, entonces a su valor entero ASCII le suma 32 para convertirla en la misma letra pero en su forma minúscula. Todos los caracteres que no sean minúsculas o mayúsculas ( se convierten) se cuentan como ingreso válido para alcanzar la cifra 50. Ejemplo 4) Realizar ingresos de caracteres por teclado y mostrarlos por pantalla. El programa termina, con la primer vocal ( sea mayúscula sea minúscula) que se ingrese. Una codificación puede ser:

Algoritmo MuestraCaracter Var caracter: dato lógico: flag // bandera inicio flag verdadero mientras flag = verdadero hacer leer ( dato) según-sea dato hacer caso „a‟ : flag falso caso „A‟ : flag falso caso „e‟ : flag falso caso „E‟ : flag falso caso „i‟ : flag falso caso „I‟ : flag falso caso „o‟ : flag falso caso „O‟ : flag falso caso „u‟ : flag falso caso „U‟ : flag falso fin-segun si flag = verdadero entonces mostrar ( dato) fin-si fin-mientras fin

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 41 -

Ejemplo 5) Ingresar 3 números desde el teclado, los números representan dimensiones de los lados de un triángulo. El programa mostrará por pantalla un mensaje indicando si el triángulo es equilátero ( 3 lados iguales), isósceles ( dos lados iguales) o escaleno (3 lados distintos). El programa termina cuando se introduzca la palabra salir. Una codificación puede ser:

Algoritmo Clasifica_triangulos Var Real: lado1, lado2, lado3 Cadena: clave inicio clave XXX mientras no (clave = „salir‟) hacer leer ( lado1, lado2, lado3) si (lado1 =lado2) y (lado2 = lado3) entonces mostrar ( „equilátero‟) si-no si ( lado1 < > lado2) y ( lado2 < > lado3) entonces mostrar („ escaleno‟) si-no mostrar ( „isósceles‟) fin-si fin-si mostrar ( „para terminar introduzca la palabra salir en minúscula‟) leer( clave) fin-mientras fin

Bibliografía obligatoria: “Fundamentos de programación. Algoritmos, Estructuras de datos y Objetos”, Luis Joyanes Aguilar. Mc Graw Hill. Tercera edición. Capítulo 5 (páginas 163 a 203).

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 1 -

Lectura 3: Arreglos

Unidad 4: Estructura de Datos: Arreglos

4.1 Concepto de arreglo unidimensional

Una estructura de datos es una colección de datos organizados de una cierta manera, y que se caracterizan por las operaciones que se definen sobre ellas.

Las estructuras de datos son muy importantes en los sistemas de computadora.

Las estructuras de datos se clasifican en estáticas y dinámicas. Esta clasificación se basa en la forma de gestionar la memoria de sistema para almacenar un conjunto de elementos del mismo tipo.

Las estructuras estáticas, la memoria se gestiona en tiempo de compilación, mientras que para las estructuras dinámicas la memoria se gestiona en tiempo de ejecución. La forma de generar los almacenamientos implican ventajas y desventajas, ambos tipos de estructuras existen en los lenguajes reales, el uso más conveniente de una forma u otra dependerá de los requerimientos del problema a resolver.

Dentro de las estructuras estáticas, se encuentran los arreglos (cualquiera sea el número de dimensiones que tenga) y los registros (estas son colecciones de elementos que pueden ser de distinto tipo, los cuales se verán más adelante).

Dentro de las estructuras dinámicas se encuentran: pila, cola, lista simplemente enlazada, lista

doblemente enlazada, listas circulares, árboles, grafos. En todas ellas, se almacena el dato

genuino 8 por ejemplo alturas de personas) más otro tipo de información que ayuda a formar la

estructura de datos de una forma particular.

En programación, un arreglo, es un conjunto finito de elementos del mismo tipo (homogéneos)

que ocupa un espacio o zona de almacenamiento en memoria dinámica físicamente contiguo.

Los arreglos pueden ser unidimensionales también llamados vectores (o arreglos lineales), o

bidireccionales (matrices) o multidimensionales.

Todo arreglo unidimensional o vector tiene asociado un único nombre o identificador. Cada

elemento es referenciado por la posición que ocupa dentro del vector. Dichas posiciones son

llamadas índice y siempre son correlativos.

Los vectores se pueden representar gráficamente como muestra la figura1, es decir como un

rectángulo dividido en tantas partes iguales como elementos tiene el vector o arreglo

unidimensional. La figura 1 representa un arreglo unidimensional llamado Dato de 4 elementos.

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 2 -

El nombre o identificador sirve para todos los elementos del conjunto, el valor del subíndice

asociado identifica en forma precisa a alguno de esos elementos.

El número de elementos de un vector se llama rango del vector. En el caso de la figura 1, el rango del vector llamado Dato, es 4.

Los arreglos en general pueden contener datos numéricos y no numéricos, por ejemplo se puede pensar en un arreglo de carácter. La figura 2, muestra un arreglo de tipo carácter de 5 elementos, llamado Info.

Otro ejemplo de un arreglo unidimensional no numérico, puede ser un vector que contiene los nombres de los 8 alumnos de un curso, entonces el vector se llama Alumno y su rango es de 8. En la figura 3 se muestra el vector Alumno.

Cada elemento de un vector se puede procesar como si fuese una variable simple al ocupar una posición de memoria. Por ejemplo:

Dato [4] 3

Almacena el valor entero o real 3 en el vector Dato en la posición número 4 (dato debe ser de tipo entero o real).

La instrucción:

escribir (Dato [4])

muestra por pantalla el contenido de la posición 4 del vector llamado Dato.

Info [ 1] Info [ 2] Info [3] Info [4]

Figura 2

Info [5]

Dato [ 1] Dato [ 2] Dato [3] Dato [4]

Figura 1

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 3 -

Los arreglos cualquiera sea su dimensión necesitan ser dimensionados previamente a su uso dentro de un programa.

En pseudocódigo un arreglo unidimensional se declara de la siguiente forma:

Algoritmo declaración_arreglo

tipo

array [1..10] de entero : dato

var

dato : info

entero: índice

inicio

………..

Se debe nota que en este trozo de código se agrega una sección llamada tipo, en esta parte se declaran los arreglos y otros tipos de datos definidos por el usuario como se verá más adelante. Se usa la palabra reservada array, seguido entre corchetes el rango como un intervalo cerrado

Luis

Jose

Sonia

Pedro

Celeste

Tomás

Sonia

Pedro

Alumno

Figura 3

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 4 -

entre 1 y el límite superior o cantidad máxima de elementos. En el ejemplo el arreglo tiene 10 elementos. A continuación se indica el tipo de dato que contiene el arreglo y finalmente el identificador. En la sección correspondiente a las variables (var) se indica el nombre de la variable con la que se va a manipular el conjunto de elementos. En el ejemplo el arreglo es de enteros y la variable por media de la cual se va a acceder a los elementos del vector, es info.

Si se desea guardar el valor entero 5, en la segunda posición del vector, la instrucción es:

info [2] 5

En el siguiente trozo de código, se crean dos vectores distintos:

Algoritmo declaración_arreglo2

tipo

array [1..10] de entero : dato

var

dato : origen, destino

entero: índice

inicio

………..

En este trozo de código, se crean dos arreglos distintos, uno de ellos se trabaja mediante la variable origen (arreglo unidimensional de 10 elementos de tipo entero) y otro se trabaja mediante la variable destino (arreglo de 10 elementos de tipo entero).

En este ejemplo, dato es un tipo de dato definido por el usuario, así como entero, real, lógico son tipos de datos primitivos o simples, dato es un tipo de dato compuesto, que reciben el nombre de: tipo de dato definido por el usuario.

En un mismo algoritmo pueden declararse varios tipos de arreglos, según las necesidades que surjan de los requerimientos del problema a resolver, en el siguiente código se declaran tres arreglos distintos.

Algoritmo declaración_arreglo3

tipo

array [1..10] de entero : dato

array [1..20] de real: vector1

array [1..3] de cadena: vector2

var

dato : origen

vector1: vec1

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 5 -

vector2: vec2

entero: índice

inicio

………..

4.2 Utilización de arreglos unidimensionales en algoritmos

Los arreglos se utilizan cuando es necesario almacenar varios valores. También se podrían guardar valores en un conjunto de variables simples, pero esto es más engorroso, y más complejo de manejar. En lugar de tener 10 variables de tipo real para guardar las alturas de personas, es más sencillo crear un arreglo de 10 elementos de tipo real, ya que toda la información la manejo con el mismo nombre de variable; y los elementos se diferencian entre sí según el valor que asuma un subíndice asociado al vector.

En la práctica suele ser necesario procesar conjuntos de datos, como por ejemplo listas de alumnos, docentes, cuentas bancarias, etc. Por ejemplo si necesitase procesar datos de 5000 alumnos respecto al promedio de inasistencia de ellos, deberíamos tener 5000 variables simple, cada una de ellas contendría un entero que represente este dato (inasistencias). Si por ejemplo se quisiese ordenar los alumnos por número creciente de inasistencias, para por ejemplo otorgarles un premio, sería imperioso tener todos los datos activos en memoria, y necesitaría otra variable para indicar el orden de los datos (5000 variables enteras más). Mientras que con un arreglo unidimensional de 5000 elementos de tipo entero sería suficiente para contener los datos y una variable más de tipo entero para indicar el orden dentro del arreglo (subíndice). Ordenado los datos de menor a mayor, en la primer posición del arreglo (índice = 1) tendría la menor inasistencia y en la última posición tendría el número más grande correspondiente al mayor número de falta (índice = 5000).

Como queda explicado con esta breve reflexión, es necesario que los lenguajes de programación brinden soporte para mantener juntos (referenciados mediante un mismo identificador) colecciones de de datos del mismo tipo.

4.3 Manejo de índices.

Un vector como ya se mencionó es una secuencia ordenada de elementos como

x[1], x[2],…,x[n]

El límite inferior no tiene que empezar en 1, puede ser cualquier valor para el subíndice, aunque es más fácil si el subíndice también sirve para indicar posición, como en el ejemplo anterior. Un subíndice igual a 1, también indica posición 1, y así.

Entonces también sería válido

P[0], P[1], P[2], P[3], P[4], P[5]

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 6 -

En este caso el rango del arreglo P es 6, y la posición 1 le corresponde el subíndice 0.

Lo mismo sucede con el siguiente caso:

P[-10], P[-11], P[-12], P[-13], P[-14], P[-15]

En este caso el rango del arreglo P es 6, y la posición 1 le corresponde el subíndice -10 y así sucesivamente.

Las operaciones que pueden realizarse con vectores son:

Asignación

Lectura/escritura

Recorrido

Ordenación búsqueda

En general, las operaciones con vectores implican el procesamiento o tratamiento de los elementos individuales del arreglo lineal.

ASIGNACION

La asignación de valores a un elemento del arreglo lineal se realiza con la siguiente instrucción:

A [4] 20

Si se desea asignara valores a todas las posiciones de un arreglo, desde el teclado, se deberá utilizar una estructura repetitiva, cualquiera. La que mejor se adapta es la estructura desde/fin-desde; ya que esta estructura tienen asociada a ella necesariamente una variable que permite contar las iteraciones, esa variable es la que nos sirve de subíndice.

Algoritmo almacena-valores_arreglo

tipo

array [1..10] de entero : dato

var

dato : origen

entero: índice

inicio

escribir („ ingresar los 10 elementos del arreglo‟)

desde índice 1 hasta 10 hacer

leer ( origen [índice])

fin-desde

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 7 -

………..

………..

En el trozo de código anterior se declara un arreglo lineal de 10 elementos de tipo entero, la variable para manejar la colección de datos se llama origen. La estructura repetitiva desde/fin-desde, itera 10 veces para asignar desde el teclado 10 valores enteros al arreglo, uno por cada posición del mismo.

LECTURA /ESCRITURA DE DATOS

Las operaciones de lectura y escritura de los elementos de un arreglo lineal generalmente se realizan con estructuras repetitivas, aunque también pueden hacerse con estructuras selectivas (dependerá de los requerimientos).

Si se desea mostrar por pantalla el contenido de una posición de un arreglo se utilizará la siguiente instrucción:

Mostrar ( a[2])

Esta instrucción muestra por pantalla el contenido de la posición 2 (si el límite inferior del arreglo es 1) del arreglo lineal a.

Si se desea mostrar por pantalla el contenido de todo un arreglo se usará una estructura repetitiva como se muestra en el siguiente trozo de código:

Algoritmo declaración_arreglo4

tipo

array [1..10] de entero : dato

var

dato : origen

entero: índice

inicio

escribir („ ingresar los 10 elementos del arreglo‟)

desde índice 1 hasta 10 hacer //se toman los valores del teclado

leer ( origen [índice])

fin-desde

escribir („ Se muestran los elementos del arreglo lineal‟)

desde índice 1 hasta 10 hacer // se muestran por pantalla los datos del arreglo lineal

escribir (origen [índice])

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 8 -

fin-desde

fin

4.4 Resolución de problemas usando arreglos unidimensionales.

Ejemplo 1) Se desea crear un algoritmo en pseudocódigo que permita ingresar 10 valores enteros por teclado, y los guarde en un arreglo unidimensional. Luego recorrerlo y mostrar los valores que ocupan las posiciones pares por pantalla.

Algoritmo Muestra_posi_par

tipo

array [1..10] de entero : dato

var

dato : origen

entero: índice

inicio

escribir („ ingresar los 10 elementos del arreglo‟)

desde índice 1 hasta 10 hacer //se toman los valores del teclado

leer ( origen [índice])

fin-desde

escribir („ Se muestran los elementos de las posiciones pares del arreglo lineal‟)

desde índice 2 hasta 10 inc 2 hacer // se muestran por pantalla los datos del arreglo lineal

escribir (origen [índice])

fin-desde

fin

Ejemplo 2) Se desea crear un algoritmo en pseudocódigo que permita ingresar 20 valores enteros por teclado, y los guarde en un arreglo unidimensional. Luego recorrerlo y mostrar los valores positivos que sean pares por pantalla.

Algoritmo Muestra_positivos_par

tipo

array [1..20] de entero : dato

var

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 9 -

dato : vec

entero: índice

inicio

escribir („ ingresar los 20 elementos del arreglo‟)

desde índice 1 hasta 20 hacer //se toman los valores del teclado

leer ( ver [índice])

fin-desde

escribir („ Se muestran los elementos positivos pares‟)

desde índice 1 hasta 20 hacer // se recorre los datos del arreglo lineal

si (vec [índice] > 0) y (vec [índice] mod 2 = 0) entonces

mostrar (vec[índice])

fin-si

fin-desde

fin

Ejemplo 3) Se desea crear un algoritmo en pseudocódigo que permita ingresar 20 valores enteros por teclado, y los guarde en un arreglo unidimensional. Luego recorrerlo y mostrar los valores positivos que sean pares por pantalla.

Algoritmo Muestra_positivos_par

tipo

array [1..20] de entero : dato

var

dato : vec

entero: índice

inicio

escribir („ ingresar los 20 elementos del arreglo‟)

desde índice 1 hasta 20 hacer //se toman los valores del teclado

leer ( ver [índice])

fin-desde

escribir („ Se muestran los elementos positivos pares‟)

desde índice 1 hasta 20 hacer // se recorre los datos del arreglo lineal

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 10 -

si (vec [índice] > 0) y (vec [índice] mod 2 = 0) entonces

mostrar (vec[índice])

fin-si

fin-desde

fin

Ejemplo 4) Se desea crear un algoritmo en pseudocódigo que permita ingresar 20 valores enteros por teclado, y los guarde en un arreglo unidimensional. Luego recorrerlo y guardar los enteros positivos en otro arreglo del mismo tipo. Mostrar los valores de este segundo arreglo porr pantalla.

Algoritmo Detecta_positivos_arreglo

tipo

array [1..20] de entero : dato

var

dato : origen, destino

entero: índice, indice2

inicio

escribir („ ingresar los 20 elementos del arreglo‟)

desde índice 1 hasta 20 hacer //se toman los valores del teclado

leer ( ver [índice])

fin-desde

//„ Se detectan y guardan los enteros positivos en arreglo destino

Indice2 1

desde índice 1 hasta 20 hacer // se recorre los datos del arreglo origen

si (vec [índice] > 0) entonces

destino[índice2] vec [índice]

indice2 indice2 +1

fin-si

fin-desde

escribir („Se muestran los elementos del arreglo destino‟)

desde índice 1 hasta indice2 hacer

mostrar( destino [índice])

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 11 -

fin-desde

fin

Ejemplo 5) Se desea crear un programa que permita guardar 15 caracteres tomados desde el teclado, el algoritmo deberá contar cuantas letras son mayúsculas. Mostrar este resultado por pantalla.

Algoritmo Cuenta_Mayúsculas

tipo

array [1..15] de caracter : dato

var

dato : ar

entero: índice, cant_May

inicio

cant_May 0

escribir („ ingresar los 15 caracteres del teclado‟)

desde índice 1 hasta 15 hacer //se toman los valores del teclado

leer ( ar [índice])

fin-desde

//„ Se detectan y cuentan las letras mayúsculas

desde índice 1 hasta 15 hacer

si ((ar [índice] > „A‟) y ( ar[índice] < „Z‟0)) entonces

cant_May cant_May +1

fin-si

fin-desde

escribir („La cantidad de letras mayúsculas del arreglo es:‟, cant_May)

fin

4.5 Concepto de arreglo bidimensional.

Los vectores hasta aquí analizados, se denominan arreglos lineales o unidimensionales.

Existen situaciones en que la información es mejor organizarla en forma de tabla o matriz con dos subíndices, uno para las filas y otro para recorrer las columnas.

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 12 -

El arreglo bidimensional se puede considerar como un vector de vectores. Por lo tanto es un conjunto de elementos, todos del mismo tipo, en el cual el orden de los elementos es significativo y en el que se necesita especificar dos subíndices, para poder identificar cada elemento del arreglo.

En la figura 4, se representa una tabla de 4 filas por 3 columnas. Cada elemento del arreglo se referencia con el mismo nombre, pero los valores de los subíndices son únicos para cada elemento de la tabla.

En notación estándar el primer subíndice hace referencia a las filas, y el segundo a los elementos de las columnas del arreglo. Es decir Tabla [2,3] es el elemento Tabla que ocupa la posición segunda fila, tercer columna, como se indica en la figura 5.

El arreglo Tabla se dice que tiene 5 por 3 elementos.

En pseudocódigo los arreglos bidimensionales se declaran de la siguiente forma:

Algoritmo Declaracion_ArregloBidimensional

tipo

array [1..5,1..3] de enteros : T

var

Fila 1

Fila 2

Fila 3

Fila 4

Fila 5

Columna 1

Columna 2

Columna 3

Figura 4

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 13 -

T : Tabla

entero: j,k

inicio

……………..

4.6 Utilización de arreglos bidimensionales en algoritmos.

Los arreglos bidimensionales son muy frecuentes, por ejemplo si se desease almacenar las calificaciones de los alumnos de un determinado grado, en tres materia: matemática, lengua e historia, se debería construir una tabla, las filas serían los nombre de los alumnos y las columnas serían las notas de los alumnos en las tres materias distintas, por ejemplo en la columna 1, las notas de matemática, en la columna 2 las de lengua y en la columna 3 las de historia. El contenido de cada celda sería un número entero, la declaración de esta tabla para 10 alumnos, se muestra en la figura 6.

Según la tabla de la figura 6, las notas de los alumnos de matemática son: 8, 7, 4, 10, 2, 1, 7, 8, 10, 2.

Las notas de los alumnos en la materia de lengua son: 5, 2, 10, 2, 8, 8, 5, 5, 10, 5 y las notas en la materia de historia son: 7,10, 5, 4, 1, 3, 7, 4, 3, 10.

Si se hace una lectura horizontal, se puede decir que el alumno de la fila 1, tiene un 8 (ocho) en matemática, un 5 (cinco) en lengua y un 7 (siete) en historia.

Fila 1

Fila 2

Fila 3

Fila 4

Fila 5

Columna 1

Columna 2

Columna 3

Figura 5

Tabla

Tabla[2,3]

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 14 -

También son útiles para representar los elementos de un almacén, por ejemplo. Los saldos en cuentas bancarias, o en distintos tipos de cuentas bancarias de un mismo cliente, etc.

4.7 Manejo de índices.

Para recorrer arreglos bidimensionales es necesario tener dos estructuras repetitivas anidadas. Las estructuras que mejor se adaptan a estos casos son las estructuras desde/fin-desde.

Fila 1

Fila 2

Fila 3

Fila 4

Fila 5

Columna 1

matemática Columna 2

lengua

Columna 3

historia

Figura 6

nota-alu

8

7

4

5

8

7

2

5

1

2 10

3

4

8

7

1

2

5

3

10

10

5

8

7

4

10

2 5 10

10

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 15 -

En pseudocódigo se expresa de la siguiente manera:

Algoritmo Declaracion_ArregloBidimensional1

tipo

array [1..5,1..3] de enteros : T

var

T : Tabla

Entero: i,j

Inicio

desde i 1 hasta 5 hacer

desde j 1 hasta 3 hacer

// sentencias

fin-desde

fin-desde

fin

Para leer datos desde el teclado, guardarlos en un arreglo bidimensional, y luego recorrerlo para mostarlo, se realiza lo siguiente:

Algoritmo Declaracion_ArregloBidimensional1

tipo

array [1..5,1..3] de enteros : T

var

T : Tabla

entero: i,j

Inicio

desde i 1 hasta 5 hacer

desde j 1 hasta 3 hacer

leer ( Tabla [i,j]

fin-desde

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 16 -

fin-desde

// se recorre el arreglo para mostrar los elementos almacenados por pantalla

desde i 1 hasta 5 hacer

desde j 1 hasta 3 hacer

escribir ( Tabla [i,j]

fin-desde

fin-desde

fin

Por cada valor que toma la variable i, el bucle interno ocurre completamente, es decir por cada valor que asume la variable i, j toma los valores de 1 a 3.

4.8 Resolución de problemas usando arreglos bidimensionales.

Ejemplo 1) Se desea crear un algoritmo en pseudocódigo que permita ingresar las notas de 10 alumnos en las materias de física (primera columna) y matemática (segunda columna) correspondientes a un curso. Se desea determinar el promedio general del curso y por materia. Mostrar estos valores por pantalla.

Algoritmo Muestra_promedios

tipo

array [1..10, 1..2] de entero : matriz

var

matriz: mat

entero: i, j, total, total2

inicio

total 0

escribir („ ingresar las notas de los 10 alumnos en las dos materias‟)

// se carga por fila desde el teclado

desde i 1 hasta 10 hacer

desde j 1 hasta 2 hacer

leer ( mat [i,j)

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 17 -

fin-desde

fin-desde

//se calcula el promedio general

desde i 1 hasta 10 hacer

desde j 1 hasta 2 hacer

total total + mat [i, j]

fin-desde

fin-desde

escribir ( „ el promedio general es: „, total / 20‟)

total 0

total2 0

escribir („ Se calculan los promedios por materia‟)

desde i 1 hasta 10 hacer

total total + mat [i,1]

total2 total2 + mat [i, 2]

fin-desde

escribir („ el promedio en física es: „, total/10, „ el promedio en matemática es:‟, total2/ 10)

fin

Ejemplo 2) Se desea crear un algoritmo en pseudocódigo que permita leer una tabla con temperaturas. La tabla tiene 5 filas correspondientes a 5 momentos distintos del día, y tiene 3 columnas correspondientes a 3 días distintos. Se desea detectar la temperatura mínima y la máxima de la tabla completa. Mostrar los valores hallados por pantalla.

Algoritmo Muestra_mín_máx

tipo

array [1..5, 1..3] de real : matriz

var

matriz : mat

entero: i, j

real: mi, ma

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 18 -

inicio

escribir („ ingresar los 15 elementos de la tabla‟)

desde i 1 hasta 5 hacer //se toman los valores del teclado

desde j 1 hasta 3 hacer

leer ( mat [i, j])

fin-desde

fin-desde

escribir („ Se detecta el mínimo y el máximo‟)

ma mat [1, 1]

mi mat [1, 1]

desde i 1 hasta 5 hacer

desde j 1 hasta 3 hacer

si mat [i, j] > max entonces

ma mat [i, j]

fin-si

si mat [i, j]< mi entonces

mi mat [i, j]

fin-si

fin-desde

fin-desde

mostrar („la temperatura mínima es: „, mi, „la temperatura máxima es:‟, ma)

fin

Ejemplo 3) Se desea crear un algoritmo en pseudocódigo que permita obtener el número de elementos positivos de una tabla de m x n. Mostrar el valor hallado por pantalla.

Algoritmo Muestra_positivos

tipo

array [1..50, 1..50] de entero : matriz

var

matriz : ma

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 19 -

entero: i, j, cont, cat_f, cant_c

inicio

escribir („ ingresar el número de filas menor a 50‟)

leer (cant_f)

escribir („ ingresar el número de columnas menor a 50‟)

leer (cant_c)

escribir („se ingresan los elementos de una tabla de :‟,cant_f, „y de „, cant_c,‟de columnas‟)

desde i 1 hasta cant_f hacer //se toman los valores del teclado

desde j 1 hasta cant_c hacer

leer ( ma [i, j])

fin-desde

fin-desde

cont 0

escribir („ Se cuentan los positivos‟)

desde i 1 hasta cant_f hacer // se recorre los datos del arreglo lineal

desde j 1 hasta cant_c hacer

si (ma [i, j] > 0) entonces

cont cont + 1

fin-si

fin-desde

fin-desde

mostrar ( „la cantidad de positivos es: „, cont)

fin

Ejemplo 4) Se desea crear un algoritmo en pseudocódigo que permita sumar los contenidos de dos tablas de 5x 5 cada una. El resultado se almacenara en otra tabla de la misma dimensión. Luego recorrer la tabla suma para mostrar los valores por pantalla.

Algoritmo suma_tablas

tipo

array [1..5, 1..5] de entero : mat

var

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 20 -

mat :ma1, ma2,maSuma

entero: i, j

inicio

escribir („ ingresar los elementos de la primera tabla de 5 x5 por fila‟)

desde i 1 hasta 5 hacer //se toman los valores del teclado

desde j 1 hasta 5 hacer

leer ( ma1 [i, j])

fin-desde

fin-desde

escribir („ ingresar los elementos de la segunda tabla de 5 x5 por fila‟)

desde i 1 hasta 5 hacer //se toman los valores del teclado

desde j 1 hasta 5 hacer

leer ( ma2 [i, j])

fin-desde

fin-desde

// se suman elementos homólogos y se guardan en la matriz

desde i 1 hasta 5 hacer //

desde j 1 hata 5 hacer

maSuma [ i, j] ma1 [i, j] + ma2 [i, j]

fin-desde

fin-desde

escribir („Se muestran los elementos de la matriz suma‟)

desde i 1 hasta 5 hacer

desde j1 hasta 5 hacer

mostrar( maSuma [i, j])

fin-desde

fin-desde

fin

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 21 -

Ejemplo 5) Se desea crear un programa que permita guardar 16 caracteres tomados desde el teclado, en un arreglo bidimensional de 4 x 4. Se solicitará el ingreso del número de fila desde el teclado, el programa mostrará por pantalla todos los elementos de esa fila.

Algoritmo Muestra_fila

tipo

array [1..4, 1..4] de caracter : dato

var

dato : ar

entero: i, j, fila

inicio

escribir („ ingresar los 16 caracteres del teclado‟)

desde i 1 hasta 4 hacer //se toman los valores del teclado

desde j 1 hasta 4 hacer

leer ( ar [i, j])

fin-desde

fin-desde

mostrar („ Introducir una fila entre 1 y 4‟)

repetir

leer ( fila)

hasta-que fila >=1 y fila < =4

escribir („Los elementos de la fila: „, fila, „son:‟)

desde i 1 hasta 4 hacer

mostrar ( ar [fila, j])

fin-desde

fin-desde

fin

4.9 Ejercicios de aplicación.

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 22 -

Ejemplo 1) Leer una tabla de 3 x3. Declarar dos arreglos unidimensionales uno llamado fila y otro columna, en estos arreglos se guardarán los totales de las filas y los totales de las columnas de la tabla de 3 x 3. Luego mostrar por pantalla los arreglos lineales.

Algoritmo Suma_fila_columna

tipo

array [1..3, 1..3] de entero : Mat

array [1..3] de entero :vector

var

Mat : ma

vector: vec1, vec2

entero: i, j, suma

inicio

escribir („ ingresar los 9 elementos del teclado‟)

desde i 1 hasta 3 hacer //se toman los valores del teclado

desde j 1 hasta 3 hacer

leer ( ma [i, j])

fin-desde

fin-desde

// se completa el arreglo fila

Suma 0

desde i 1 hasta 3 hacer

desde j 1 hasta 3 hacer

suma suma + ma [i, j])

fin-desde

vect1[i] suma

suma 0

fin-desde

// se completa el arreglo columna

Suma 0

desde j 1 hasta 3 hacer

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 23 -

desde i 1 hasta 3 hacer

suma suma + ma [i, j])

fin-desde

vect1[j] suma

suma 0

fin-desde

//se muestran por pantalla los elementos del vector de filas

desde i 1 hasta 3 hacer

mostrar ( vect1 [ i ])

fin-desde

//se muestran por pantalla el vector de columnas

desde i 1 hasta 3 hacer

mostrar ( vect2 [ i ])

fin-desde

fin

Ejemplo 2) Crear una tabla de 4 x4. Declarar un arreglo unidimensional, en el se guardarán los elementos de la diagonal principal. Luego mostrar por pantalla los elementos del arreglo lineal.

Algoritmo vector-diagonal

tipo

array [1..4, 1..4] de real : Mat

array [1..4] de real :vector

var

Mat : ma

vector: vec1

entero: i, j

inicio

escribir („ ingresar los 16 elementos del teclado‟)

desde i 1 hasta 4 hacer //se toman los valores del teclado

desde j 1 hasta 4 hacer

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 24 -

leer ( ma [i, j])

fin-desde

fin-desde

// se completa el arreglo lineal

desde i 1 hasta 4 hacer

vec [ i ] ma [i, i])

fin-desde

//se muestran por pantalla los elementos del vector diagonal principal

desde i 1 hasta 4 hacer

mostrar ( vec [ i ])

fin-desde

fin

Ejemplo 3) Crear una lista con N temperaturas almacenadas. Se desea calcular la media y crear otro arreglo con los valores mayores a la media. Luego mostrar por pantalla los elementos de los arreglos lineales.

Algoritmo vector-media

tipo

array [1..50] de real : vector

var

vector: origen, destino

entero: i, N

real: suma, media

inicio

escribir („ ingresar el número de elementos que tendrá el arreglo‟)

leer (N )

escribir („Ingresar los elementos del arreglo lineal‟)

desde i 1 hasta N hacer //se toman los valores del teclado

leer ( origen [i ])

fin-desde

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 25 -

// se calcula la media

Suma 0

desde i 1 hasta N hacer

suma suma + origen [ i ]

fin-desde

media suma / N

j 0

//se comparan los elementos del arreglo origen con la madia

desde i 1 hasta N hacer

si origen [ i ] > media entonces

j j+1

destino [j ] origen [ i]

fin-si

fin-desde

mostrar („ se muestra el arreglo origen‟ )

desde i 1 hasta N hacer //se toman los valores del teclado

escribir ( origen [i ])

fin-desde

mostrar („ se muestra el arreglo destino‟ )

desde i 1 hasta j hacer //se toman los valores del teclado

mostrar ( destino [i ])

fin-desde

fin

Ejemplo 4) Crear una lista con N nombres de alumnos. Se desea introducir un nombre de alumno por teclado 10 veces, y mostrar un mensaje adecuado si el nombre está en la lista.

Algoritmo Lista-nombre

tipo

array [1..50] de cadena : vector

var

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 26 -

vector: vec

entero: i, cant

cadena: nom

inicio

repetir

escribir („ ingresar el número de elementos que tendrá el arreglo‟)

leer (N )

hasta-que N>=1 y N <= 50

escribir („Ingresar los elementos del arreglo lineal‟)

desde i 1 hasta N hacer //se toman los valores del teclado

leer ( vec [i ])

fin-desde

cant 0

mientras cant < 10 hacer

escribir („Ingresar un nombre de alumno a buscar en la lista

leer ( nom)

desde i 1 hasta N hacer

si vec [ i ] = nom entonces

mostrar („ el nombre:‟, nom, „está en la lista‟)

si-no

mostrar („el nombre:‟, nom, „no está en la lista‟)

fin-si

fin-desde

cant cant + 1

fin-miesntras

fin

Bibliografía Obligatoria:

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 27 -

“Fundamentos de programación. Algoritmos, Estructuras de datos y Objetos”, Luis Joyanes Aguilar. Mc Graw Hill. Tercera edición. Capítulo 7 (páginas 247 a 284)

Unidad 5: Ordenación y búsqueda

5.1 Ordenación. Métodos

El ordenamiento es una labor común que realizamos continuamente. ¿Pero, qué es ordenar? El ordenamiento es algo tan corriente en nuestras vidas que no nos detenemos a pensar en ello. Ordenar es simplemente colocar información de una manera especial basándonos en un criterio de ordenamiento. La finalidad de un ordenamiento, es el de facilitar el acceso a la información.

En la computación el ordenamiento de datos también cumple un rol muy importante, ya sea como un fin en sí o como parte de otros procedimientos más complejos. Se han desarrollado muchas técnicas en este ámbito, cada una con características específicas, y con ventajas y desventajas sobre las demás. En esta unidad vamos a mostrar algunas de las más comunes, tratando de hacerlo de una manera sencilla y comprensible.

CONCEPTOS PRELIMINARES

Antes de comenzar a ver cada algoritmo vamos a ponernos de acuerdo en algunos conceptos, para que no haya confusiones:

Clave: La parte de un conjunto de datos (registro), por la cual se ordena la lista. Por ejemplo, una lista de registros, en la que cada registro de esa lista tiene tres campos diferentes: nombre, dirección y teléfono se puede ordenar alfabéticamente de acuerdo a la clave nombre. En este caso los campos dirección y teléfono no se toman en cuenta en el ordenamiento.

Criterio de ordenamiento (o de comparación): EL criterio que utilizamos para asignar valores a los registros con base en una o más claves. De esta manera decidimos si un registro es mayor o menor que otro.

Registro: Un grupo de datos que forman la lista. Pueden ser datos atómicos (enteros, caracteres, reales, etc.) o grupos de ellos.

Cuando se estudian algoritmos de todo tipo, no sólo de ordenamiento, es bueno tener una forma de evaluarlos antes de pasarlos a código, que se base en aspectos independientes de la plataforma o el lenguaje. De esta manera podremos decidir cuál se adapta mejor a los requerimientos de nuestro programa. Algunos de estos aspectos son:

Estabilidad: Este parámetro establece o mide cómo se comporta, el algoritmo con registros que tienen claves iguales. Algunos algoritmos mantienen el orden relativo entre

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 28 -

éstos y otros no. Veamos un ejemplo. Si tenemos la siguiente lista de datos (nombre, edad): "Pedro 19, Juan 23, Felipe 15, Marcela 20, Juan 18, Marcela 17", y la ordenamos alfabéticamente por el nombre con un algoritmo estable quedaría así: "Felipe 15, Marcela 20, Marcela 17, Juan 23, Juan 18, Pedro 19". Un algoritmo no estable podría dejar a Juan 18 antes de Juan 23, o a Marcela 20 después de Marcela 17.

Tiempo de ejecución: Este parámetro mide la complejidad del algoritmo, que no tiene que ver con dificultad, sino con rendimiento. Es una función independiente de la implementación.

Una medida de eficiencia es:

Contar el número de comparaciones

Contar el número de movimientos de ítems

Estos están en función del número de elementos a ser ordenados.

En el ordenamiento una operación fundamental es la de comparar. Ahora contamos cuántas veces el algoritmo necesita comparar. Si en una lista de n términos realiza n comparaciones la complejidad es O(n). (En realidad es un poco más complicado que eso). Algunos ejemplos de complejidades comunes son:

O(1): Complejidad constante.

O(n2): Complejidad cuadrática.

O(n log(n)): Complejidad logarítmica.

Ahora podemos decir que un algoritmo de complejidad O(n) es más rápido que uno de complejidad O(n2). Otro aspecto a considerar es la diferencia entre el peor y el mejor caso. Cada algoritmo se comporta de modo diferente de acuerdo a cómo se le entregue la información; por eso es conveniente estudiar su comportamiento en casos extremos, como cuando los datos están prácticamente ordenados o muy desordenados.

Requerimientos de memoria: El algoritmo puede necesitar memoria adicional para realizar su labor. En general es preferible que no sea así, pero es común en la programación tener que sacrificar memoria por rendimiento.

Hay más aspectos que se pueden tener en cuenta para realizar un análisis de calidad sobre un algoritmo de ordenamiento en particular, pero sólo vamos a mencionar en esta materia los hasta aquí descriptos.

Por último estableceremos algunas convenciones sobre el pseudocódigo:

Vamos a ordenar la lista en forma ascendiente, es decir, de menor a mayor. Obviamente es esencialmente lo mismo que hacerlo en forma inversa.

La forma de intercambiar los elementos depende de la estructura de datos: si es un arreglo (dinámico o estático) es necesario guardar una copia del primer elemento, asignarle el segundo al primero y el temporal al segundo. La variable temporal es necesaria, porque de lo contrario se perdería uno de los elementos. Si la estructura es una lista dinámica el procedimiento es parecido,

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 29 -

pero se utilizan las direcciones de los elementos. En el pseudocódigo se utilizará el primer método.

La siguiente es una tabla comparativa de algunos algoritmos de ordenamiento, según los parámetros ya vistos.

Tabla comparativa de algoritmos

Nombre Complejidad Estabilidad Memoria adicional

Ordenamiento Burbuja O(n2) Estable No

Ordenamiento por Selección O(n2) No Estable No

Ordenamiento por inserción O(n2) Estable No

Ordenamiento Rápido (Quicksort) O(n * log2(n)) No Estable No

Cada algoritmo se comporta de modo diferente de acuerdo a la cantidad y la forma en que se le presenten los datos, entre otras cosas. No existe EL algoritmo de ordenamiento. Sólo existe el mejor para cada caso particular. Se debe conocer el problema que se desea resolver, y aplicar el algoritmo más adecuado. Hay algunos interrogantes que pueden ayudar a escoger un algoritmo en especial:

¿Qué grado de orden tendrá la información que vas a manejar? Si la información va a estar casi ordenada y no quieres complicarte, un algoritmo sencillo como el ordenamiento burbuja será suficiente. Si por el contrario los datos van a estar muy desordenados, un algoritmo poderoso como Quicksort puede ser el más indicado. Si por forma en que se presenta la información no es posible hacer una presunción sobre el grado de orden de la información, lo mejor será elegir un algoritmo que se comporte de manera similar en cualquiera de estos dos casos extremos.

¿Qué cantidad de datos vas a manipular? Si la cantidad es pequeña, no es necesario utilizar un algoritmo complejo, y es preferible uno de fácil implementación. Una cantidad muy grande puede hacer prohibitivo utilizar un algoritmo que requiera de mucha memoria adicional.

¿Qué tipo de datos quieres ordenar? Algunos algoritmos sólo funcionan con un tipo específico de datos (enteros, enteros positivos, etc.) y otros son generales, es decir, aplicables a cualquier tipo de dato.

¿Qué tamaño tienen los registros de tu lista? Algunos algoritmos realizan múltiples intercambios (burbuja, inserción). Si los registros son de gran tamaño estos intercambios son más lentos.

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 30 -

El ordenamiento es una labor común que realizamos cotidianamente, es un proceso tan común en nuestras vidas que no nos detenemos a meditar mucho en ello. Ordenar es meramente colocar información de una manera especial basándonos en un criterio de ordenamiento.

El ordenar un grupo de datos significa mover los datos o sus referencias para que queden en una secuencia tal que represente un orden, el cual puede ser numérico, alfabético o incluso alfanumérico, ascendente o descendente.

Tipos de ordenamientos

a- internos

Los datos a ordenar están en memoria la principal Ram, por lo que se asume que el tiempo que se requiere para acceder cualquier elemento sea el mismo. En el siguiente cuadro aparecen métodos que explícitamente pide desarrollar el programa y otros que no se trabajan en la materia, como para presentar un panorama amplio del ordenamiento

Inserción Directa

Inserción Directa

Inserción Binaria

Selección Directa Selección Directa

Intercambio Directo

Burbuja

Shake

Inserción Disminución Incremental Shell

Ordenamiento De Árbol

Heap

Tournament

Sort Particionado Quick Sort

Merge Sort

Radix Sort

Cálculo De Dirección

b- externos

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 31 -

Los datos a ordenar están en la memoria secundaria, es decir, por ejemplo disco duro, disco extraíble, por lo que se asume que el tiempo que se requiere para acceder a cualquier elemento depende de la última posición consultada.

Straight Merging

Natural Merging

Balanced Multiway Merging

Polyphase Sort

Distribution Of Initial Runs

Clasificación de los algoritmos de ordenamiento:

Algoritmos de inserción:

Inserción Directa

Shell

Inserción Binaria

Hashing

Algoritmos de intercambio:

Burbuja

Shake

QuickSort

Algoritmos de selección: Selección Directa

Algoritmos de enumeración:

Merge

Radix

Heap

Los métodos simples son: Inserción Directa, Selección, Burbuja y Shell, en dónde el último es una

extensión al método de Inserción, siendo más rápido. Los métodos más complejos son Quick Sort

y Heap.

La ordenación (clasificación) es la operación de organizar un conjunto de datos en algún orden dado, tal como creciente o decreciente para los datos numéricos, o en orden alfabético para caracteres o cadenas (directo o inverso).

Los métodos de ordenamiento directos, son aquellos que para realizar el ordenamiento utilizan el espacio del arreglo.

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 32 -

La ordenación de información es una de las aplicaciones más importantes de la computación. Por ejemplo un banco ordena los cheques por número de cuenta para poder preparar los estados de cuenta al cierre del mes. Otro caso lo constituyen las compañías de teléfonos, estos ordenan sus listas de cuenta por apellido y nombre para hacer más fácil la localización de números telefónicos.

Prácticamente todas las organizaciones tienen información a ordenar y en muchos casos son grandes volúmenes de datos. El ordenamiento de datos es un problema interesante que ha provocado áreas de investigaciones en la ciencia de la computación.

Los métodos de ordenamiento más populares son:

Intercambio

Selección

Inserción

En algunas circunstancias es clara la ventaja de usar un método en lugar de otros.

5.2 Ordenación por selección.

Este método se basa en buscar el elemento menor del vector y colocarlo en primera posición. Luego se busca el segundo elemento más pequeño y se coloca en la segunda posición, y así sucesivamente.

Los pasos sucesivos son:

1. Seleccionar el elemento menor del vector de n elementos

2. Intercambiar dicho elemento con el primero

3. Repetir estas operaciones con los n-2 elementos restantes hasta que sólo quede el mayor

Un ejemplo aclarará el método:

120 45 2 36 89 90 23

El método busca el más pequeño, y lo intercambia con el elemento que ocupa la primera posición

2 45 120 36 89 90 23

Luego busca el número más pequeño entre los que quedan menos el primer elemento que ya está ubicado.

2 23 120 36 89 90 45

Ahora busca el elemento que ocupa la tercera posición en el ordenamiento:

2 23 36 120 89 90 45

Busca el elemento que ocupa la 4 posición en el vector ordenado:

2 23 36 45 89 90 120

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 33 -

Busca el elemento que ocupa la 5 posición:

2 23 36 45 89 90 120

La posición 6 y 7 ya están ordenadas, pero el método seguirá iterando y confirmará sus posiciones en el ordenamiento.

2 23 36 45 89 90 120

La última pasada ratificará el último valor

2 23 36 45 89 90 120

Un algoritmo para este método de ordenación es:

Algoritmo ordenación_selección

tipo

array [1..7] de entero : vector

var

vector: vec

entero: i, j, aux

inicio

escribir („ ingresar los valores 2, 23, 36, 45, 89, 90, 120‟)

desde i 1 hasta 7 hacer

leer (vec [i ] )

fin-desde

escribir („Comienza el ordenamiento‟)

desde i 1 hasta 6 hacer

desde j i+1 hasta 7 hacer

si vec [i ] > vec [ j ] entonces

aux vec [ i ]

vec [i ] vec [ j ]

vec [j ] aux

fin-si

fin-desde

fin-desde

escribir („el vector ordenado es:‟ )

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 34 -

desde i 1 hasta 7 hacer

mostrar ( vec [ i ])

fin-desde

fin

Si se quisiese ordenar en forma decreciente los elementos, sólo habría que dar vuelta el signo de la desigualdad:

si vec [i ] < vec [ j ] entonces

La parte del intercambio corresponde al siguiente trozo de código:

aux vec [ i ]

vec [i ] vec [ j ]

vec [j ] aux

cómo puede verse se requiere una variable auxiliar para el intercambio.

5.3 Ordenación por inserción.

Este método consiste en insertar un elemento en una parte ya ordenada del vector y comenzar de nuevo con los elementos restantes. Este también es un algoritmo lento, pero puede ser de utilidad para listas que están a medio ordenar, pues en ese caso realiza pocos desplazamientos.

También se lo conoce como el método de la baraja.

Tiempo de Ejecución: Para una lista de n elementos el ciclo externo se ejecuta n-1 veces. Complejidad O(n2).

Estabilidad: No intercambia registros con claves iguales. Por lo tanto es estable.

Ventajas:

Fácil implementación.

Requerimientos mínimos de memoria.

Desventajas:

Lento.

Numerosas comparaciones.

EJEMPLO PRACTICO

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 35 -

Explicaremos el método sobre una lista de números enteros desordenados, por ejemplo:

67 90 30 21 4 51

Paso1: toma las dos primeras posiciones y las ordena

67 90 30 21 4 51

Paso 2: toma el 3 elemento y lo inserta ordenado en la parte que ya está ordenada, previo desplazar los elementos ordenados en forma lineal, para lo cual el elemento a insertar se guarda en una variable auxiliar, lo cual permite hacer el desplazamiento de los elementos ordenados de la lista:

67 90 30 21 4 51

67 90 90 21 4 51 aux= 30

67 67 90 21 4 51

Paso 3: toma el 4 elemento y busca insertarlo en la parte ordenada del vector. Para ello guarda el valor a insertar en una variable auxiliar, y luego entra a desplazar los elementos ordenados buscando el lugar adecuado para la inserción.

30 67 90 21 4 51

Aux = 21

30 67 90 90 4 51 (notar que el 4 y el 51 de la lista ocupan el mismo lugar)

21 67 67 90 4 51

30 30 67 90 4 51

21 30 67 90 4 51

Paso 4: toma el 5 elemento y busca insertarlo en la parte ordenada del vector. Para ello guarda el valor a insertar en una variable auxiliar, y luego entra a desplazar los elementos ordenados buscando el lugar adecuado para la inserción.

21 30 67 90 4 51

Aux = 4

21 30 67 90 90 51 (notar que el 51 de la lista ocupa el mismo lugar)

21 30 67 67 90 51

21 30 30 67 90 51

21 21 30 67 90 51

4 21 30 67 90 51

Paso 5: toma el 5 elemento y busca insertarlo en la parte ordenada del vector. Para ello guarda el valor a insertar en una variable auxiliar, y luego entra a desplazar los elementos ordenados buscando el lugar adecuado para la inserción.

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 36 -

4 21 30 67 90 51

Aux = 51

4 21 30 67 90 90

4 21 30 67 67 90

4 21 30 51 67 90

El arreglo lineal queda ordenado.

Por lo tanto el método se basa en comparaciones y desplazamientos sucesivos. El algoritmo de clasificación de un vector X para N elementos se realiza con un recorrido de todo el vector y la inserción del elemento correspondiente en el lugar adecuado. El recorrido se puede realizar desde el segundo al n-ésimo.

desde i 2 hasta N hacer

// insertar X [i ] en el lugar adecuado entre X[1 ].. X [i-1 ]

fin-desde

En el siguiente código se utiliza un centinela o bandera (sw)

algoritmo orden_inserción-directa

//declaraciones

inicio

……

desde i 2 hasta N hacer

aux X [ i]

k i-1

sw falso

mientras no (sw) y ( k > = 1) hacer

si aux < X [k ] entonces

X [k +1] X [k ]

K k-1

si-no

sw verdadero

fin-si

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 37 -

fin-mientras

X [k +1] aux

fin-desde

fin

Existe una forma de mejorar el algoritmo de inserción lineal o directa. Para ello se utiliza el método de buscada binaria para ubicar la posición correcta y no realizar un desplazamiento lineal.

En pseudocódigo el algoritmo de inserción mejorada es:

algoritmo orden_inserción_binaria

//declaraciones

inicio

……

desde i 2 hasta N hacer

aux X [ i]

P 1 //primero

U i -1 // ultimo

mientras P < = U hacer

C ( P+ U) div 2

si aux < X [C ] entonces

U C - 1

si-no

P C +1

fin-si

fin-mientras

desde K i -1 hasta P decrementar 1 hacer

X [k +1] X [ K ]

fin-desde

X [ P ] aux

fin-desde

fin

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 38 -

5.4 Ordenación por burbuja.

Algoritmo Burbuja

BubbleSort recorre el arreglo intercambiando los elementos adyacentes que estén desordenados. Recorre el arreglo tantas veces hasta que ya no haya cambios. Prácticamente lo que hace es tomar el elemento mayor y lo coloca en las últimas posiciones o tomar el menor y colocarlo en las primeras posiciones.

Tiempo de ejecución: El ciclo interno se ejecuta n veces. El ciclo externo también se ejecuta n veces, la complejidad es n * n = O(n2). El comportamiento del caso promedio depende del orden de entrada de los datos, pero es sólo un poco mejor que el del peor caso, y sigue siendo O(n2).

Estabilidad: No intercambia registros con claves iguales.

Ventajas:

Fácil implementación.

No requiere memoria adicional.

Desventajas:

Muy lento.

Muchas comparaciones.

Muchos intercambios.

En pseudocódigo el algoritmo es:

algoritmo Método_Burbuja

//declaraciones

inicio

// lectura del vector

desde i 1 hasta N hacer

leer ( vec[ i ] )

fin-desde

//ordenamiento del vector

desde i 1 hasta n-1 hacer

desde j 1 hasta n-1 hacer

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 39 -

si vec [ j ] > vec [ j +1 ] entonces

//intercambiar

aux vec [ j ]

vec [ j ] vec [ j +1 ]

vec [ j+1 ] aux

fin-si

fin-desde

fin-desde

// mostrar por pantalla el arreglo ordenado

desde i 1 hasta N hacer

mostrar ( vec[ i ] )

fin-desde

fin

5.5 Ordenación por burbuja mejorada.

Después de cada pasada (el bucle desde más externo), el elemento de más valor se ubica en el extremo del arreglo. Lo que significa que toma su posición correcta, por este motivo sería conveniente que en vez de realizar todas las comparaciones en la segunda pasada, se haga una comparación menos.

algoritmo Método_Burbuja_mejorada

//declaraciones

inicio

// lectura del vector

desde i 1 hasta N hacer

leer ( vec[ i ] )

fin-desde

//ordenamiento del vector

desde i 1 hasta n-1 hacer

desde j 1 hasta n- i hacer

si vec [ j ] > vec [ j +1 ] entonces

//intercambiar

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 40 -

aux vec [ j ]

vec [ j] vec [ j +1 ]

vec [ i+1 ] aux

fin-si

fin-desde

fin-desde

// mostrar por pantalla el arreglo ordenado

desde i 1 hasta N hacer

mostrar ( vec[ i ] )

fin-desde

fin

5.6 Ejercicios de aplicación.

Ejemplo 1) Generar un arreglo de 10 elementos enteros ordenados de menor mayor.

Algoritmo ordenación_selección

tipo

array [1..10] de entero : vector

var

vector: vec

entero: i, j, aux

inicio

escribir („ ingresar los valores‟)

desde i 1 hasta 10 hacer

leer (vec [i ] )

fin-desde

escribir („Comienza el ordenamiento‟)

desde i 1 hasta 9 hacer

desde j i+1 hasta 10 hacer

si vec [i ] > vec [ j ] entonces

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 41 -

aux vec [ i ]

vec [i ] vec [ j ]

vec [j ] aux

fin-si

fin-desde

fin-desde

escribir („el vector ordenado es:‟ )

desde i 1 hasta 10 hacer

mostrar ( vec [ i ])

fin-desde

fin

Ejemplo 2) Generar un arreglo de 10 elementos enteros ordenados de mayor a menor.

Algoritmo ordenación_selección

tipo

array [1..10] de entero : vector

var

vector: vec

entero: i, j, aux

inicio

escribir („ ingresar los valores ‟)

desde i 1 hasta 10 hacer

leer (vec [i ] )

fin-desde

escribir („Comienza el ordenamiento‟)

desde i 1 hasta 9 hacer

desde j i+1 hasta 10 hacer

si vec [i ] < vec [ j ] entonces

aux vec [ i ]

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 42 -

vec [i ] vec [ j ]

vec [j ] aux

fin-si

fin-desde

fin-desde

escribir („el vector ordenado es:‟ )

desde i 1 hasta 10 hacer

mostrar ( vec [ i ])

fin-desde

fin

5.7 Búsqueda. Métodos.

Un algoritmo de búsqueda es aquel que está diseñado para localizar un elemento concreto dentro de una estructura de datos. Consiste en solucionar un problema de existencia o no de un elemento determinado en un conjunto finito de elementos, es decir, si el elemento en cuestión pertenece o no a dicho conjunto, además de su localización dentro de éste.

5.8 Búsqueda secuencial.

Se utiliza cuando el contenido del vector no se encuentra o no puede ser ordenado. Consiste en buscar el elemento comparándolo secuencialmente (de ahí su nombre) con cada elemento del arreglo hasta que éste se encuentre, o hasta que se llegue al final del arreglo. La existencia se puede asegurar desde el momento que el elemento es localizado, pero no podemos asegurar la no existencia hasta no haber analizado todos los elementos del arreglo. A continuación se muestra el pseudocódigo del algoritmo:

algoritmo Método_Busqueda_secuencial

//declaraciones

inicio

// lectura del vector

desde i 1 hasta N hacer

leer ( vec[ i ] )

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 43 -

fin-desde

//se toma la clave de búsqueda

leer ( clave)

//búsqueda

ban falso

desde i 1 hasta n hacer

si vec [i ] = clave entonces

ban verdadero

fin-si

fin-desde

si ban = verdadero entonces

mostrar ( „la clave de búsqueda está en el arreglo‟ )

si-no

mostrar ( „la clave de búsqueda NO está en el arreglo‟ )

fin-si

fin

5.9 Búsqueda binaria.

Se utiliza cuando el vector en el que queremos determinar la existencia o no de un elemento está ordenado, o puede estarlo, este algoritmo reduce el tiempo de búsqueda considerablemente, ya que disminuye exponencialmente con el número de iteraciones.

Para implementar este algoritmo se compara el elemento a buscar con un elemento cualquiera del arreglo (normalmente el elemento central), si el valor de éste es mayor que el del elemento buscado se repite el procedimiento en la parte del arreglo que va desde el inicio de éste hasta el elemento tomado, en caso contrario se toma la parte del arreglo que va desde el elemento tomado hasta el final. De esta manera obtenemos intervalos cada vez más pequeños, hasta que se obtenga un intervalo indivisible, con el elemento buscado como elemento central. Si el elemento no se encuentra dentro de este último entonces se deduce que el elemento buscado no se encuentra en el arreglo.

La búsqueda binaria utiliza un método de „divide y vencerás‟ para localizar el elemento deseado.

A continuación se presenta el pseudocódigo del algoritmo, tomando como elemento inicial el elemento central del arreglo.

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 44 -

Algoritmo búsqueda_binaria

// declaraciones

inicio

// llenar el arreglo x con N valores

// ordenar el arreglo

leer ( K) // clave de búsqueda

// se inicializan las variables para la búsqueda

bajo 1

alto N // N es el número de elementos del arreglo

central ent ( ( bajo + alto ) / 2)

mientras ( bajo < = alto ) y ( x [ central ] <> K) hacer

si K < x [ central] entonces

alto central -1

si-no

bajo central + 1

fin-si

central ent (( bajo +alto ) / 2)

fin-mientras

si K = x [central] entonces

escribir ( „valor encontrado‟)

si-no

escribir ( „valor no encontrar‟)

fin-si

fin

Bibliografía Obligatoria:

Materia: Programación Lógica

Profesor: Ing. Silvia Carrera - 45 -

“Fundamentos de programación. Algoritmos, Estructuras de datos y Objetos”, Luis Joyanes Aguilar. Mc Graw Hill. Tercera edición. Capítulo 10 (páginas 360 a 412)

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 1 -

Unidad 6: Subalgoritmo. 6.1. Introducción a los subalgoritmos. La resolución de problemas complejos se facilita considerablemente si se procede dividiendo en problemas más pequeños (subproblemas). La solución de estos subproblemas se realiza con subalgoritmos. El uso de subalgoritmos permite al programador desarrollar programas de problemas complejos utilizando el método descendente introducido en los módulos anteriores. Los subalgoritmos (subprogramas) pueden ser de dos tipos: funciones y procedimientos o subrutinas. Los subalgoritmos son unidades de programa o módulos que están diseñados para ejecutar alguna tarea específica. Estas funciones y procedimientos se escriben solamente una vez, pero pueden ser referenciados en diferentes puntos de un programa de modo que se puede evitar la duplicación innecesaria del código. El uso de unidades de programas en el estilo de programación modular son independientes; el programador puede escribir cada módulo y verificarlo sin preocuparse de los detalles de otros módulos. Esto facilita considerablemente la localización de un error cuando se produce. Los programas desarrollados de este modo son normalmente también más fáciles de comprender, ya que la estructura de cada unidad de programa puede ser estudiada independientemente de las otras unidades de programa. En este módulo se describen las funciones y procedimientos junto con los conceptos de variables locales y globales, así como los conceptos relacionados a los parámetros. Entonces, para solucionar un problema complejo hay que dividirlo en subproblemas -problemas más sencillos- y a continuación dividir estos subproblemas en otros más simples hasta que los problemas más pequeños sean fáciles de resolver. Esta técnica de dividir el problema principal en subproblemas se suele denominar "divide y vencerás" (Divide and Conquer). Este método de diseñar la solución de un problema principal obteniendo las soluciones de sus subproblemas se conoce como diseño descendente (top-dow design). Se denomina descendente ya que se inicia en la parte superior con un problema general y el diseño específico de las soluciones de los subproblemas. Normalmente las partes en que se divide un programa deben poder desarrollarse independientemente entre sí. Las soluciones de un diseño descendente pueden implementarse fácilmente en lenguajes de programas de alto nivel. Estas partes independientes se denominan subprogramas o subalgoritmos si se emplean desde el concepto algorítmico. Consideremos el problema del cálculo de la superficie (área) de un rectángulo. Este problema se puede dividir en tres subproblemas.

Subproblema 1: entrada de datos de altura y base. Subproblema 2: cálculo de la superficie. Subproblema 3: salida de resultados.

El algoritmo correspondiente que resuelve los tres subproblemas es: ………………..

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 2 -

leer datos (altura, base) //entrada de datos}

área base * altura //cálculo de la superficie escribir (base, altura, área) //salida de resultados

…………………… El problema principal se soluciona por el correspondiente programa o algoritmo principal -también denominado controlador o conductor (driver)- y la solución de los subproblemas mediante subprogramas, conocidos como procedimientos (subrutinas) o funciones. Los subprogramas cuando se trata en lenguaje algorítmico se denominan también subalgoritmos. Un subprograma puede realizar las mismas acciones que un programa: 1) aceptar datos, 2) realizar algunos cálculos y 3) devolver resultados. Un subprograma, sin embargo, se utiliza por el programa para un propósito específico. El subprograma recibe datos desde el programa y le devuelve resultados. Haciendo un símil con una oficina, el problema es como el jefe que da instrucciones a sus subordinados -subprogramas-; cuando la tarea se termina, el subordinado devuelve sus resultados al jefe. Se dice que el programa principal llama o invoca al subprograma. El subprograma ejecuta una tarea, a continuación devuelve el control al programa. Esto puede suceder en diferentes lugares del programa. Cada vez que el subprograma es llamado, el control retorna al lugar de donde fue hecha la llamada. Un subprograma puede llamar a su vez sus propios subprogramas. Existen -como ya se ha comentado- dos tipos importantes de subprogramas: funciones y procedimientos o subrutinas.

6.2. Ejemplos de utilidad. Implementar subalgoritmos, tiene más ventajas que desventajas. Entre las ventajas se encuentran:

Una vez implementado un subalgoritmo, si este tuviese que modificarse en algún aspecto (cambiar el tipo de variable de entero pasar a real, mostrar por pantalla un valor de cálculo intermedio que antes no se hacía, cambiar el tamaño de un arreglo, etc.) es más fácil y rápido efectuar el cambio en el subalgoritmo, que andar buscando en el algoritmo general las partes de código que implementan la tarea y que necesitan cambiarse para adaptar el algoritmo original a los nuevos requerimientos.

Se pueden construir librerías propias, con los subalgoritmos que se desarrollen. Desarrollado un algoritmo, cualquier ajuste que deba hacerse, es más fácil hacerlo sobre

un subalgoritmo que sobre el algoritmo. Es menos laborioso, el testeo y búsqueda de error de un algoritmo que utilizó

subalgoritmos para codificar tareas específicas, que uno que no utilizó subalgoritmos. Los algoritmos modularizados (subalgoritmos), se pueden ir desarrollando paulatinamente

por tarea, se pueden probar, y finalmente hacer el ensamble de todos los módulos en un solo programa.

Es más sencillo trabajar en ambientes colaborativos, donde distintos programadores desarrollan los subalgoritmos y luego se unen los módulos en un programa.

Etc. Entre las desventajas, se encuentran:

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 3 -

En general los subalgoritmos utilizan más memoria de sistema, porque los parámetros (información que se pasa desde el algoritmo a los subalgoritmos) deben guardarse en alguna parte de memoria.

Las variables locales al subalgoritmo, y los parámetros por valor se guardan en una zona de memoria de sistema llamada Pila, esta pila esta acotada en capacidad, por lo tanto hay que tener cuidado de que no se rebalse. Muchos compiladores de lenguajes reales no avisan cuando se está dando esta situación con lo cual se pierde información y nadie se da cuenta.

Es más complejo realizar un programa modular que uno que no lo sea.

Por ejemplo, se podrían pensar en situaciones como las siguientes:

Desarrollar subalgoritmos que reciban como parámetro un mensaje a desplegar por pantalla. Cada vez que se necesite mostrar algo por pantalla se invoca el subalgoritmo pasándole los parámetros adecuados.

Desarrollar un subalgoritmo que permita buscar algún dato entre una colección de elementos del mismo tipo. Los parámetros de este subalgoritmos, serían el arreglo, su dimensión, la clave de búsqueda.

Desarrollar un subalgoritmo de ordenamiento, los parámetros de este código serían el arreglo, su tamaño, la forma de ordenamiento ( de mayor a menor o viceversa)

Subalgoritmos que permitan cargar arreglos, sus parámetros serían: el arreglo, el tamaño, y eventualmente alguna otra variable para determinar si se aceptan valores positivos o negativos o alguna condición en especial, de manera tal de hacer el algoritmo lo más general que se pueda.

Etc.

6.3. Definición de subalgoritmo. Los subalgoritmos son unidades de programa o módulos que están diseñados para ejecutar alguna tarea específica. Estos subalgoritmos, en forma de funciones y procedimientos, se escriben una sola vez, pero pueden ser referenciados en diferentes puntos de un programa, de modo que se evita la duplicación innecesaria de código.

Se llama subalgoritmo a cada una de las partes de un algoritmo más general que resuelve cada una de las tareas particulares necesarias para que dicho algoritmo general alcance el objetivo para el que fue diseñado, es decir resolver un problema concreto. Este concepto está vinculado al diseño estructurado de algoritmos, en el cual un problema se divide en partes que posteriormente son resueltas por un módulo. Cada módulo coincidirá con un subalgoritmo.

6.4. Paso de parámetros Los parámetros son vías de comunicación entre el algoritmo y los subalgoritmos de un programa más complejo.

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 4 -

Estas vías de comunicación pueden ser unidireccionales o bidireccionales. Es decir información de entrada, o información de salida del subalgoritmo o información bidireccional es decir de entrada y de salida del subalgoritmo. Es necesario aclarar los conceptos referidos a variables locales y globales. Una variable local es aquella que está declarada y definida dentro de un subprograma, en el sentido de que está declarada dentro de la parte var del subalgoritmo y es distinta de las variables con igual nombre y tipo que está declarada en la sección var del algoritmo principal. Es más si otro subalgoritmo, declara y usa una variable del mismo tipo y nombre que otro subalgoritmo, no hay conflicto entre estas variables, pues pertenecen a ámbitos distintos. El significado de una variable se confina al procedimiento en el que está declarada. Una variable global es aquella que está declarada para el programa o algoritmo principal, del que dependen todos los subprogramas. La parte del programa en la que una variable se define, se llama ámbito. El uso de variables locales tiene sus ventajas. Usar variables locales en lugar de globales, hace a los subprogramas independientes, pues la comunicación entre programa y subprograma se realiza a través de los parámetros. Para usar un subalgoritmos solo tenemos que saber que hace y no como lo hace. Una variable local a un procedimiento no tiene ningún significado en otros subprogramas, por el contrario las variables globales tienen la característica de compartir información de diferentes subprogramas, sin estar presente entre los parámetros. Los lenguajes que admiten variables locales y globales suelen tener la posibilidad explícita de definir dichas variables como tales en el cuerpo del programa, o definir su ámbito de actuación. Los parámetros actuales son los que aparecen entre paréntesis en la invocación del subalgoritmo dentro del algoritmo principal. Mientras que los parámetros formales son los que se encuentran entre paréntesis en la definición del subalgoritmo COMUNICACIÓN CON SUBPROGRAMAS: PASO DE PARÁMETROS Cuando un programa llama (invoca) a un subprograma, la información se comunica a través de la lista de parámetros y se establece una correspondencia automática entre los parámetros formales y actuales. Los parámetros actuales son “sustituidos” o “utilizados” en lugar de los parámetros formales. La correspondencia se establece aparejando los parámetros reales y formales según su posición en las listas: así, Fi se corresponde con Ai donde i = 1, 2, ..., n. Este método tiene algunas desventajas de legibilidad cuando el número de parámetros es grande. Paso de parámetros Existen diferentes métodos para la transmisión o el paso de los parámetros a subprogramas. Es preciso conocer el método adoptado por cada lenguaje, ya que la elección puede afectar a la

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 5 -

semántica del lenguaje. Dicho de otro modo, un mismo programa puede producir diferentes resultados bajo diferentes sistemas de paso de parámetros. Los métodos más empleados para realizar el paso de parámetros son: paso por valor (también conocido por parámetro valor) paso por referencia o dirección (también conocido por parámetro variable) Paso por valor El paso por valor se utiliza en muchos lenguajes de programación; por ejemplo, Modula-2, Pascal, C\ C++, Algol, Snobol. La razón de su popularidad es la analogía con los argumentos de una función, donde los valores se proporcionan en el orden de cálculo de resultados. Los parámetros se tratan como variables locales y los valores iniciales se proporcionan copiando los valores de los correspondientes argumentos. Los parámetros formales -locales a la función- reciben como valores iniciales los valores de los parámetros actuales y con ello se ejecutan las acciones descritas en el subprograma. No se hace diferencia entre un argumento que es variable, constante o expresión, ya que sólo importa el valor del argumento. Aunque el paso por valor es sencillo, tiene una limitación acusada: no existe ninguna otra conexión con los parámetros actuales, y entonces los cambios que se produzcan por efecto del subprograma no producen cambios en los argumentos originales y, por consiguiente, no se pueden pasar valores de retorno al punto de llamada: es decir, todos los parámetros son sólo de entrada. El parámetro actual no puede modificarse por el subprograma. Cualquier cambio realizado en los valores de los parámetros formales durante la ejecución del subprograma se destruye cuando se termina el subprograma. La llamada por valor no devuelve información al programa que llama. Paso por referencia En numerosas ocasiones se requiere que ciertos parámetros sirvan como parámetros de salida, es decir, se devuelvan los resultados a la unidad o programas que llama. Este método se denomina paso por referencia o también de llamada por dirección o referencia. La unidad que llama pasa a la unidad llamada la dirección del parámetro actual (que está en el ámbito de la unidad llamante). Una referencia al correspondiente parámetro formal se trata como una referencia a la posición de memoria, cuya dirección se ha pasado. Entonces una variable pasada como parámetro real es compartida, es decir, se puede modificar directamente por el subprograma. Si el parámetro actual es una expresión, el subprograma recibe la dirección de la posición temporal que contiene el valor de la expresión. Este método existe en VB, C++, Delphi, FORTRAN, COBOL, Modula-2, Pascal, PL/1 y Algol 68. La característica de este método se debe a su simplicidad y su analogía directa con la idea de que las variables tienen una posición de memoria asignada desde la cual se pueden obtener o actualizar sus valores. El área de almacenamiento (direcciones de memoria) se utiliza para pasar información de entrada y / o salida; en ambas direcciones. En este método los parámetros son de entrada / salida y los parámetros se denominan parámetros variables.

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 6 -

Los parámetros por valor y los parámetros por variable se suelen definir en la cabecera del subprograma. En el caso de lenguajes como Pascal, los parámetros variable deben ir precedidos por la palabra clave var; en nuestros ejemplos se indicará expresamente el método de paso con líneas comentario. La llamada por referencia es muy útil para parámetros donde se necesita la comunicación del valor en ambas direcciones. NOTAS: Ambos métodos de paso de parámetros se aplican tanto a la llamada de funciones como a las de procedimientos. Una función tiene la posibilidad de devolver los valores al programa principal de dos formas:

valor de la función argumentos gobernados por la llamada de referencia en la correspondencia parámetro

actual-parámetro formal. Un procedimiento sólo puede devolver valores por referencia. Síntesis de la transmisión de parámetros Los métodos de transmisión de parámetros más utilizados son: por valor y por referencia. El paso de un parámetro por valor significa que el valor del argumento —parámetro actual o real— se asigna al parámetro formal. En otras palabras, antes de que el subprograma comience a ejecutarse, el argumento se evalúa a un valor específico (por ejemplo, 8 ó 12). Este valor se copia entonces en el correspondiente parámetro formal dentro del subprograma. Una vez que el procedimiento arranca, cualquier cambio del valor de tal parámetro formal no se refleja en un cambio en el correspondiente argumento. Esto es, cuando el subprograma se termine, el argumento tendrá exactamente el mismo valor que cuando el subprograma comenzó, con independencia de lo que haya sucedido al parámetro formal. Estos parámetros de entrada se denominan parámetros valor. El paso de un parámetro por referencia o dirección, llamado parámetro variable, en oposición al parámetro por valor. En este caso, la posición o dirección (no el valor) del argumento o parámetro actual se envía al subprograma. Si a un parámetro formal se le da el atributo de parámetro variable y si el parámetro actual es una variable, entonces un cambio en el parámetro formal se refleja en un cambio en el correspondiente parámetro actual, ya que ambos tienen la misma posición de memoria. Es importante volver a recordar que: Las variables locales se declaran dentro de un módulo o subalgoritmo y sólo tienen utilidad dentro de ese módulo, no se podrá acceder a ellas desde otros módulos. Pueden existir variables locales con el mismo nombre siempre que estén en módulos diferentes. Los parámetros por valor son variables locales. Las variables globales son declaradas de forma que puedan ser utilizadas (consultada y/o modificada) desde cualquiera de los módulos que forman el programa. En este caso, no puede haber dos variables globales con el mismo nombre, ya que esto produciría una ambigüedad que el

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 7 -

compilador no podría resolver. En el diseño estructurado de algoritmos se desaconseja el uso de variables globales. Las variables globales no pueden ser parámetros de subalgoritmos. DEFINICIÓN DE UN SUBALGORITMO

Los subalgoritmos se definen de forma distinta según cumplan el rol de procedimiento o de función:

a) Procedimiento procedimiento nombre_del_procedimiento (modo tipo: nombre-variable;…..) var: // se declaran las variables y sus tipos inicio // se codifica la tarea

fin-procedimiento

La definición de un procedimiento comienza con la palabra reservada procedimiento a continuación se coloca el nombre del procedimiento, tratando de darle un identificador que represente la tarea que codifica el subalgoritmo, a continuación entre paréntesis se coloca la lista de parámetros indicando: modo, tipo y nombre o identificador de la variable. Los parámetros se separan con punto y como. No hay limitación a la cantidad de parámetros que pueden indicarse entre paréntesis. En los lenguajes de programación suelen usarse hasta 4 o 5 parámetros, si se necesitasen más que esa cantidad, entonces, es posible que dicho subalgoritmo pueda descomponerse en dos o más subalgoritmos. Modo: hay tres posibilidades: E (entrada), S (salida) y E/S (entrada y salida) El modo entrada (E), implica que el contenido de la variable solo puede ser leído o usado dentro del subalgoritmo, pero ese valor no puede ser modificado desde dentro del subalgoritmo. El modo salida (S), implica que el contenido de la variable no puede ser leído o usado dentro del subalgoritmo, pero si se puede generar un resultado o valor dentro del subalgoritmo y asignárselo a este parámetro de salida, y desde el algoritmo principal se puede hacer uso de ese valor. El modo entrada/salida (E/S), implica que el contenido de la variable puede ser leído o usado dentro del subalgoritmo, pero ese valor no puede ser modificado desde dentro del subalgoritmo. Tipo: es cualquier tipo válido en pseudocódigo, por ejemplo real, entero, lógico, cadena, carácter o registro (se verá más adelante).

b) Función Tipo función nombre_de_la_función (modo tipo: nombre-variable;…..) var: // se declaran las variables y sus tipos inicio // se codifica la tarea

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 8 -

fin-función

La definición de una función comienza con la palabra reservada función a continuación se coloca el tipo de dato que va a devolver la función (entero, real, etc.), a continuación se coloca el nombre o identificador de la función, tratando de darle un identificador que represente la tarea que codifica el subalgoritmo, posteriormente, entre paréntesis se coloca la lista de parámetros indicando: modo, tipo y nombre o identificador de la variable. Los parámetros se separan con punto y como. No hay limitación a la cantidad de parámetros que pueden indicarse entre paréntesis. En los lenguajes de programación suelen usarse hasta 4 o 5 parámetros, si se necesitasen más que esa cantidad, entonces, es posible que dicho subalgoritmo pueda descomponerse en dos o más subalgoritmos. Modo: hay tres posibilidades: E (entrada), S (salida) y E/S (entrada y salida) El modo entrada (E), implica que el contenido de la variable solo puede ser leído o usado dentro del subalgoritmo, pero ese valor no puede ser modificado desde dentro del subalgoritmo. El modo salida (S), implica que el contenido de la variable no puede ser leído o usado dentro del subalgoritmo, pero si se puede generar un resultado o valor dentro del subalgoritmo y asignárselo a este parámetro de salida, y desde el algoritmo principal se puede hacer uso de ese valor. El modo entrada/salida (E/S), implica que el contenido de la variable puede ser leído o usado dentro del subalgoritmo, pero ese valor no puede ser modificado desde dentro del subalgoritmo. Tipo: es cualquier tipo válido en pseudocódigo, por ejemplo real, entero, lógico, cadena, carácter o registro (se verá más adelante).

6.5. Invocación de subalgoritmos. Según se trate de un procedimiento o una función, se realiza lo siguiente:

a) Procedimiento

La invocación se hace en el programa principal o algoritmo para lo cual se escribe: la palabra llamar-a (que es opcional, puede ir o suprimirse) y a continuación el nombre del procedimiento y entre paréntesis la lista de parámetros sin tipo ni modo, separados por coma., y la definición del subalgoritmo se coloca después de la línea de fin para el algoritmo principal. Por ejemplo, implementar un programa que permita mediante un procedimiento sumar dos enteros pasados por parámetros desde el programa principal. Los sumandos serán tomados desde el teclado. El resultado de la suma se mostrará desde el subalgoritmo. Algoritmo CalcularSuma

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 9 -

Var: entero: a, b //declaración de variables Inicio: escribir („ingresar dos números enteros‟) // ingreso de datos desde el teclado leer (a,b ) // se introducen por teclado y se guardan en las posiciones de memoria //llamadas a y b Llamar-a suma (a, b) // se invoca el procedimiento fin // fin del algoritmo procedimiento suma ( E entero: a,b) // definición del procedimiento var: entero: sum inicio sum a + b mostrar ( „ la suma es: „ , sum) fin-procedimiento EXPLICACIÓN: El procedimiento recibe dos parámetros de modo entrada, esto quiere decir que dentro del procedimiento solo se podrá leer su contenido, pero no se podrá modificar el contenido de las variables a y b. Dentro del procedimiento se declara una variable entera sum, local, sobre la que se guarda la suma de a y b. El procedimiento muestra por pantalla la suma de a y b.

b) Función

La invocación se hace en el programa principal o algoritmo para lo cual se escribe: el nombre de la función (sin la palabra reservada función ni el tipo de retorno de la función, a continuación y entre paréntesis la lista de parámetros (actuales) sin tipo ni modo, separados por coma., y la definición del subalgoritmo se coloca después de la línea de fin para el algoritmo principal. Por ejemplo, implementar un programa que permita mediante una función sumar dos enteros pasados por parámetros desde el programa principal. Los sumandos serán tomados desde el teclado. El resultado de la suma se mostrará desde el algoritmo principal. Algoritmo CalcularSuma Var: entero: a, b, resul //declaración de variables Inicio: escribir („ingresar dos números enteros‟) // ingreso de datos desde el teclado leer (a,b ) // se introducen por teclado y se guardan en las posiciones de memoria //llamadas a y b

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 10 -

Resul suma (a, b) // se invoca la función Mostrar („la suma es: „, resul) fin // fin del algoritmo entero función suma ( E entero: a,b) // definición del procedimiento var: entero: sum inicio sum a + b devolver sum fin-función EXPLICACIÓN: La función recibe dos parámetros de modo entrada, esto quiere decir que dentro de la función solo se podrá leer su contenido, pero no se podrá modificar el contenido de las variables a y b. Dentro de la función se declara una variable entera sum, local, sobre la que se guarda la suma de a y b. La función devuelve a través de la línea devolver, un valor, y solo un valor (objeto) al programa principal. El resultado de la tarea solicitada se muestra por pantalla en el algoritmo principal.

6.6. Ejercicios de aplicación. Ejemplo 1: Implementar un programa que mediante un procedimiento se permita mostrar por pantalla solamente las letras ingresadas por teclado. Realizar 20 ingresos. Una codificación puede ser:

Algoritmo MuestraMayúsculas Var caracter: dato entero: cant inicio cant 0 repetir leer ( dato) llamar_a determina_mayus ( dato) cant cant +1 hasta-que cant > = 20 fin

procedimiento determina_mayus ( E carácter: dato)

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 11 -

inicio: si (dato > = „A‟ y dato < = „Z‟) o (dato > = „a‟ y dato < = „z‟) entonces mostrar ( dato) fin-si fin-procedimiento

EXPLICACIÓN: El procedimiento recibe un parámetro de entrada de tipo carácter. Dentro del procedimiento se determina si el carácter ingresado por teclado corresponde a una letra, en tal caso lo muestra por pantalla. Ejemplo 2: Realizar 50 ingresos de caracteres por teclado. Una función determinará si el carácter ingresado, es una minúscula, la minúscula se muestra desde el programa principal, si no lo es otra función transformará el carácter la letra es mayúscula convertirla a minúscula para luego mostrarla por pantalla. Una codificación puede ser:

Algoritmo MuestraMinúsculas Var caracter: dato entero: cont inicio cont 0 repetir leer ( dato) si determina_minus ( dato) entonces mostrar ( dato) fin-si si determina_mayus (dato) entonces mostrar (dato) fin-si cont cont +1 hasta-que cant > = 50 fin lógico función determina_minus ( E carácter: dato) var: lógico: prueba inicio prueba verdadero si (dato > = „a‟ y dato < = „z‟) entonces devolver prueba si_no prueba falso devolver prueba

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 12 -

fin-si fin_funcion lógico función determina_mayus ( E/S carácter: dato) var lógico: prueba inicio prueba verdadero si (dato > = „A‟ y dato < = „Z‟) entonces dato dato + 32 si_no prueba falso fin-si

devolver prueba fin_funcion Ejemplo 3: Ingresar 3 números desde el teclado, los números representan dimensiones de los lados de un triángulo. Un procedimiento mostrará por pantalla un mensaje indicando si el triángulo es equilátero (3 lados iguales), isósceles (dos lados iguales) o escaleno (3 lados distintos). El programa termina cuando se introduzca la palabra salir. Una codificación puede ser:

Algoritmo Clasifica_triangulos Var Real: lado1, lado2, lado3 Cadena: clave inicio clave XXX mientras no (clave = „salir‟) hacer leer ( lado1, lado2, lado3) llamar_a clasifica_triangulo ( lado1, lado2, lado3) mostrar ( „para terminar introduzca la palabra salir en minúscula‟) leer( clave) fin-mientras fin

procedimiento clasifica_triangulo ( E real: lado1, lado2, lado3) inicio si (lado1 =lado2) y (lado2 = lado3) entonces mostrar ( „equilátero‟) si-no si ( lado1 < > lado2) y ( lado2 < > lado3) entonces

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 13 -

mostrar („ escaleno‟) si-no mostrar ( „isósceles‟) fin-si fin-si fin_procedimiento

Ejercicio 4: Se dispone de una lista de N números ingresados por teclado, mediante un procedimiento se desea determinar y mostrar por pantalla el valor del número mayor y del menor que se hayan ingresado al mismo tiempo. Una posible codificación podría ser:

Algoritmo DeterminaMayor_Menor Var entero: N inicio leer ( N) llamar_a det_May_men ( N) fin procedimiento det_May_men ( E entero: N) var real: dato, mayor, menor entero: cant inicio leer ( dato) mayor dato menor dato desde cant 2 hasta N hacer leer ( dato) si mayor < dato entonces mayor dato fin-si si menor > dato entonces menor dato fin-si fin-desde mostrar ( mayor, menor)

fin_procedimiento

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 14 -

Ejercicio 5: Se leen desde el teclado 100 números, mediante un procedimiento se desea determinar y mostrar por pantalla la media de los números positivos y la media de los números negativos que se hubiesen ingresado, al mismo tiempo. Una posible codificación podría ser:

Algoritmo DeterminaMedia_Positivos_Negativos Inicio Llamar_a det_media ( ) fin procedimiento det_media ( ) var entero: cantP, cantN, total real: dato, sumaPos, sumaNeg inicio cantP 0 cantN 0 sumaPos 0 sumaNeg 0 desde total 1 hasta 100 hacer leer ( dato) si dato > 0 entonces cantP cantP+1 sumaPos sumaPos + dato fin-si si dato < 0 entonces sumaNeg sumaNeg + dato cantN cantN + 1 fin-si fin-desde mostrar ( „la media de los valores negativos es: „,sumaNeg/cantN) mostrar ( „la media de los valores positivos es:‟, sumaPos/cantN)

fin_procedimiento

EXPLICACION: Lo interesante de este ejercicio es presentar una lista de parámetros vacía. Este procedimiento, no recibe parámetros entonces los paréntesis se colocan vacios en su interior. El procedimiento declara todas las variables que necesita para cumplir su tarea como locales al método. Observar también que el algoritmo principal no requiere declarar variables.

Ejercicio 6: Se desea implementar un programa que permita ingresar dos número enteros positivos: X y N. Una función deberá calcular la N-ésima potencia de X. El resultado se muestra desde el programa principal.

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 15 -

Una posible codificación podría ser: Algoritmo CalculaProtencia Var: entero: X, N real: pot inicio: pot 1 repetir mostrar („ ingresar la base y el exponente de la potencia a calcular) leer ( X, N) hasta-que (X>=1 y N > -1) pot calcula_Po ( X, N) mostrar ( ´La potencia es :‟ , pot) fin real función calcula_Po ( E entero: X ; E /S entero: N) var real: pot inicio pot 1 mientras N > 0 hacer pot pot * X N N -1 fin-mientras devolver pot fin_función Ejercicio 7: Mediante una función se desea calcular el factorial de un número entero ingresado por teclado. Una posible codificación podría ser: Algoritmo CalculaFactorial Var: entero: num, cont real: fact inicio: mostrar ( „ingresar un número a calcular su factorial‟) // no se realiza la validación ingresar ( num) fact cal_fac ( num) mostrar („El factorial de: „,num, „es:‟ fact) fin real función cal_fac ( E entero: num) var real: fa

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 16 -

entero: cont inicio si num = 0 o num =1 entonces fa 1 si-no fa num cont num-1 repetir fa fa * cont cont cont -1 hasta-que cont < =1 fin-si devolver fa fin_función Ejemplo 8: Se desea implementar un programa que permita ingresar solo números enteros positivos, el programa mostrará por pantalla por medio de una función, el promedio de los 10 números enteros positivos ingresados desde el teclado. Una posible codificación podría ser: Algoritmo CalculaPromedio var real: prom inicio prom cal_pro ( ) mostrar ( „el promedio es: „, prom) fin real función cal_pro ( ) var: entero: cont, num, suma real: prom inicio: cont 0 suma 0 repetir cont cont + 1 repetir mostrar ( ´ingresar número entero mayor a cero´) leer (num) hasta-que num > = 0 suma suma + num hasta-que cont > = 10 prom suma / 10

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 17 -

devolver prom fin_función

Ejemplo 9: Se desea crear un algoritmo en pseudocódigo que permita ingresar 10 valores enteros por teclado, y los guarde en un arreglo unidimensional, mediante un procedimiento. Luego mediante otro procedimiento, recorrerlo y mostrar los valores que ocupan las posiciones pares por pantalla. Algoritmo Muestra_posi_par tipo array [1..10] de entero : dato var dato : origen inicio carga_arreglo (origen) muestra_pos_pares (origen) fin procedimiento carga_arreglo ( S dato: origen) var entero: i inicio escribir („ ingresar los 10 elementos del arreglo‟) desde i 1 hasta 10 hacer //se toman los valores del teclado leer ( origen [ i ]) fin-desde fin_procedimiento procedimiento muestra_pos_pares ( E dato: origen) var entero: i inicio escribir („ Se muestran los elementos de las posiciones pares del arreglo lineal‟) desde i 2 hasta 10 inc 2 hacer // se muestran por pantalla datos del arreglo lineal escribir (origen [i ]) fin-desde fin_procedimiento Ejemplo 10: Se desea crear un algoritmo en pseudocódigo que permita ingresar 20 valores enteros por teclado, y los guarde en un arreglo unidimensional, mediante un procedimiento. Luego recorrerlo y mostrar los valores positivos que sean pares por pantalla, mediante otro procedimiento. Algoritmo Muestra_positivos_par tipo

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 18 -

array [1..20] de entero : dato var dato : vec inicio carga_datos ( vec) busca_posit_pares ( vec) fin procedimiento carga_datos ( S dato: vec) var entero: índice inicio escribir („ ingresar los 20 elementos del arreglo‟) desde índice 1 hasta 20 hacer //se toman los valores del teclado leer ( vec [índice]) fin-desde fin_procedimento procedimiento busca_posit_pares ( E dato: vec) var entero: índice inicio escribir („ Se muestran los elementos positivos pares‟) desde índice 1 hasta 20 hacer // se recorre los datos del arreglo lineal si (vec [índice] > 0) y (vec [índice] mod 2 = 0) entonces mostrar (vec[índice]) fin-si fin-desde fin_procedimiento Ejemplo 11: Se desea crear un algoritmo en pseudocódigo que permita leer una tabla con temperaturas. La tabla tiene 5 filas correspondientes a 5 momentos distintos del día, y tiene 3 columnas correspondientes a 3 días distintos, esta tabla se carga mediente un procedimiento. Se desea detectar la temperatura mínima y la máxima de la tabla completa, mediante otro procedimiento. Mostrar los valores hallados por pantalla, desde el programa principal. Algoritmo Muestra_mín_máx tipo array [1..5, 1..3] de real : matriz var matriz : mat real: men, may inicio men 0 may 0 carga_tabla ( mat) busca_Men_May ( mat, men, may) mostrar („la temperatura mínima es: „, men, „ y la temperatura máxima es:‟, may)

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 19 -

fin procedimiento carga_tabla ( S matriz: mat) var entero: i, j inicio escribir („ ingresar los 15 elementos de la tabla‟) desde i 1 hasta 5 hacer //se toman los valores del teclado desde j 1 hasta 3 hacer leer ( mat [i, j]) fin-desde fin-desde fin_procedimiento procedimiento busca_Men_May ( e matriz:mat, S real: men, may) var entero: i,j inicio escribir („ Se detecta el mínimo y el máximo‟) may mat [1, 1] men mat [1, 1] desde i 1 hasta 5 hacer desde j 1 hasta 3 hacer si mat [i, j] > may entonces may mat [i, j] fin-si si mat [i, j]< men entonces men mat [i, j] fin-si fin-desde fin-desde fin-procedimiento

Bibliografía Obligatoria: “Fundamentos de programación. Algoritmos, Estructuras de datos y Objetos”, Luis Joyanes Aguilar. Mc Graw Hill. Tercera edición. Capítulo 6 (páginas 205 a 246).

Unidad 7: Estructuras de datos: registros. 7.1. Concepto de registro.

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 20 -

Las estructuras de datos se clasifican en estructuras simples y compuestas, según cuantos elementos agrupen. Las estructuras de datos, también se clasifican en estructuras de datos estáticas y dinámicas, según cuando se realice la reserva de memoria ram. Dentro de las estructuras de datos simples están los tipos entero, real, cadena, caráter y lógico. Dentro de las estructuras de datos compuestas están los arreglos y los registros. Las estructuras de datos estáticas, son aquellas en las que la reserva de memoria se realiza en tiempo de compilación, mientras que las estructuras de datos dinámicas, son aquellas en las que la reserva de memoria se realiza en tiempo de ejecución. El registro, es un tipo de dato compuesto, es una colección de elementos que pueden ser de distinto tipo. Todos los elementos del conjunto se referencian con una misma variable de ese tipo. Este tipo de dato es apropiado cuando se quiere por ejemplo dispone de un programa que permita calcular cuánto hay que pagarle a una serie de empleados de una institución. Para poder confeccionar el cheque, debe conocerse el nombre y apellido junto con el monto a pagar. El monto a pagar se determina según su categoría, número de horas trabajadas, monto por hora, descuentos especiales (adelanto de dinero), premios por asistencia, cargas sociales (esposa, hijos, escolaridad, etc) Toda esta información junta (registro) caracteriza a una persona. Entonces como esta colección de datos son de distinto tipo, no puedo utilizar un arreglo para alcenarlos. Para estos y otros casos existe el tipo de dato registro. Otras situaciones son por ejemplo, representar los datos de un alumno, los datos de un docente, los datos de un cliente del banco, los datos de un rectángulo, los datos de una mesa (forma, material, color). Entonces cuando debo representa una colección de datos que pueden ser de distintos tipos, puede utilizar un registro para representarla. Ahora bien si necesito representar los datos de un alumno, también lo puedo hacer con tipos simples o primitivos, en este caso tendría tantas variables simples como datos quiera representar del alumno. La ventaja que tiene usar un registro en lugar de muchas variables simples, es que mediante un único identificador puedo acceder a la colección completa de datos del alumno. En lugar de tener varias variables, tendría una sola y mediante esa única variable accedería a la información del alumno. Es más sencillo trabajar y usar los registros cuando la situación lo hace necesario. Cuando se copia el contenido de un registro a otro, se copia miembro a miembro En memoria ram, todos los miembros del registro ocupan posiciones consecutivas.

7.2. Creación de variables de tipo registro. En pseudocódigo el registro se declara de la siguiente forma: Algoritmo MMMM tipo registro: reg inicio …… : …..

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 21 -

…… : ….. …… : ….. fin_registro var reg: re ……………….. ………………. Los registros se declaran en la misma zona que los arreglos en decir en la sección tipo. En el ejemplo anterior se declara un tipo de dato llamado reg, dentro de inicio y fin se declaran los miembros del registro, pueden declararse miembros primitivos (real, entero, lógico, cadena, carácter) o compuestos (array o incluso otro registro). En la sección var se declara el tipo con el identificador de la variable con la cual se va a hacer referencia al registro, en este caso ese identificador es re. A continuación se van a presentar algunos casos para que puede apreciarse la forma de utilizar estos tipos de datos definidos por el usuario.

a) Declaración de un registro, con tres datos de tipo entero y un miembro de tipo real: Algoritmo TTT tipo registro: reg inicio entero: dato1, dato2, dato3 real: resul fin_registro var reg: re ………… ………..

b) Declaración de un registro, con datos de tipo entero, real y cadena: Algoritmo TTT tipo registro: regist inicio entero: dato1 real: resul cadena: inf1 fin_registro var regist: re1 ………… ………..

c) Declaración de un registro, con 3 miembros de tipo entero: Algoritmo TTT tipo

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 22 -

registro: regis inicio entero: sumando1 entero: sumando2 entero: result fin_registro var regis: re ………… ………..

d) Declaración de un registro, con dato de tipo entero, 2 de tipo real, carácter: Algoritmo OOO tipo registro: reg inicio entero: dato1 real: resul, prom carácter: dato2 fin_registro var reg: re ………… ………..

7.3. Acceso a los campos. Operaciones de asignación, entrada/salida. Para acceder a cada uno de los miembros de un registro se utiliza el nombre o identificador de la variable de tipo registro el operador punto (.) seguido del nombre de la variable del miembro al que queremos acceder ya sea para guardar información en el o para leer su contenido. Los miembros de un registro no pueden accederse por medio de la variable de ese miembro, siempre se accede a los miembros a tras del identificador de la variable de tipo registro. Por ejemplo en el siguiente trozo de código se quiere introducir un valor por teclado para guardarlo en el miembro real, variable resul:

Algoritmo YYY const: tam= 5 tipo array [ 1..5, 1..5] de carácter: vector registro: reg inicio entero: dato1,dato2 real: resul carácter: dato2

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 23 -

vector: ve fin_registro var reg: re entero: i, j, resultado inicio escribir ( „ ingresar un número real‟) leer ( re.resul) ………… fin Notar la sintaxis para acceder a los miembros de un registro. leer ( re.resul)

A continuación se muestra como se realiza una asignación, para el trozo de código anterior, se desea acumular en la variable resultado, el contenido de los miembros entero del registro: …………… ………….. leer( re.dato1, re.dato2) resultado re.dato1 + re.dato2 Para mostrar por pantalla el contenido de un miembro de un registro, se utiliza la variable registro punto ( .) seguido del nombre de la variable del miembro que se desea mostrar por pantalla. Para el código anterior, se desea mostrar por pantalla el contenido del miembro dato1, la sintaxis es: ………. mostrar ( re.dato1) …………

7.4. Arreglo de registros. Es bastante común tener que utilizar arreglos de registros, es decir cada posición del arreglo es un registro. A continuación se presentarán algunos ejemplos:

a) Declaración de un arreglo unidimensional de 10 elementos de tipo registro. El registro contiene un miembro real y otro entero: algoritmo TTT tipo registro: regis inicio entero: inf1 real: inf2

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 24 -

fin_registro array [1..10] de regis: vector var vector: re ………… ………..

b) Declaración de un arreglo de registro, el registro contiene un miembro que es un dato lógico, y dos enteros: Algoritmo OOO tipo registro: reg inicio entero: dato1, dato2 lógico: inf1 fin_registro array [1..10] de reg: vector var vector: re ………… ………..

c) Declaración de un arreglo unidimensional de 20 elementos de tipo registro. Cada registro contine tres datos de tipo lógico: Algoritmo TTT tipo registro: regis inicio lógico: inf1, inf2, inf3 fin_registro array [1..20] de regis: vector var vector: vec ………… ………..

d) Declaración de un arreglo de registros de 10 elementos. El registro contiene un entero, real, carácter, y un miembro que es una matriz de 5 x5 de caracteres: Algoritmo OOO tipo array [1..5, 1..5] de caracter: vector

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 25 -

registro: reg inicio entero: dato1 real: resul carácter: dato2 vector: ve fin_registro array [1..10] de reg: arr var arr: vec ………… ………..

7.5. Ejercicios de aplicación. A continuación se mostrarán ejemplos tratando de abarcar la mayor diversidad de casos posibles. Ejemplo 1: Se desea representar información de 3 trabajadores. Cada trabajador se representa con un registro. La información que se guarda en el registro es: nombre, apellido, edad, número de horas trabajadas, monto por hora trabajada. Cargar desde el teclado los registros, y mostrar por pantalla la remuneración promedio que paga la empresa. algoritmo Calcula_remuneracion

tipo registro: persona inicio cadena: nombre, apellido entero: edad, num_hora real: monto_hora fin_registro var real: total persona: per1, per2, per3 inicio total 0 ingresar ( „nombre, apellido, edad, monto por hora y número de horas trabajadas de un trabajador‟) leer ( per1.nombre, per1.apellido, per1.edad, per1.monto_hora, per1.num_hora )

ingresar ( „nombre, apellido, edad, monto por hora y número de horas trabajadas de un trabajador‟) leer ( per2.nombre, per2.apellido, per2.edad, per2.monto_hora, per2.num_hora )

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 26 -

ingresar ( „nombre, apellido, edad, monto por hora y número de horas trabajadas de un trabajador‟) leer ( per3.nombre, per3.apellido, per3.edad, per3.monto_hora, per3.num_hora ) total total + per1.monto_hora * per1.num_hora total total + per2.monto_hora * per2.num_hora total total + per3.monto_hora * per3.num_hora mostrar ( „la empresa en promedio paga:‟, total/3)

fin Ejercicio 2: Se desea representar información de 3 trabajadores. Cada trabajador se representa con un registro. La información que se guarda en el registro es: nombre, apellido, edad, número de horas trabajadas, monto por hora trabajada. Cargar desde el teclado los registros, y mostrar por pantalla la remuneración más alta, junto con su identificación. algoritmo Calcula_Mayor_remuneracion

tipo registro: persona inicio cadena: nombre, apellido entero: edad, num_hora real: monto_hora fin_registro var real: total persona: per1, per2, per3 cadena: nom,ape inicio total 0 ingresar ( „nombre, apellido, edad, monto por hora y número de horas trabajadas de un trabajador‟) leer ( per1.nombre, per1.apellido, per1.edad, per1.monto_hora, per1.num_hora )

ingresar ( „nombre, apellido, edad, monto por hora y número de horas trabajadas de un trabajador‟) leer ( per2.nombre, per2.apellido, per2.edad, per2.monto_hora, per2.num_hora ) ingresar ( „nombre, apellido, edad, monto por hora y número de horas trabajadas de un trabajador‟) leer ( per3.nombre, per3.apellido, per3.edad, per3.monto_hora, per3.num_hora ) total total + per1.monto_hora * per1.num_hora nom per1.nombre

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 27 -

ape per1.apellido si total < (per2.monto_hora * per2.num_hora) entonces total per2.monto_hora * per2.num_hora nom per2.nombre ape per2.apellido fin-si si total < (per3.monto_hora * per3.num_hora) entonces total per3.monto_hora * per3.num_hora nom per3.nombre ape per3.apellido fin-si mostrar ( „la mayor remuneración es: „, total, „el nombre y apellido es:‟, nom,ape)

fin

Ejercicio 3: Se desea representar información de 3 trabajadores. Cada trabajador se representa con un registro. La información que se guarda en el registro es: nombre, apellido, edad, número de horas trabajadas, monto por hora trabajada, sexo codificado (mujer=1, varón=0). Cargar desde el teclado los registros, y mostrar por pantalla la remuneración de las mujeres, junto con su identificación. algoritmo Calcula_Mayor_remuneracion

tipo registro: persona inicio cadena: nombre, apellido entero: edad, num_hora lógico: sexo real: monto_hora fin_registro var persona: per1, per2, per3 inicio ingresar ( „nombre, apellido, edad, monto por hora y número de horas trabajadas, sexo ( mujer=1, varón=0), de un trabajador‟) leer ( per1.nombre, per1.apellido, per1.edad, per1.monto_hora, per1.num_hora, per1.sexo )

ingresar ( „nombre, apellido, edad, monto por hora y número de horas trabajadas, sexo codificado (mujer=1, varón=0), de un trabajador‟) leer ( per2.nombre, per2.apellido, per2.edad, per2.monto_hora, per2.num_hora, per2.sexo )

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 28 -

ingresar ( „nombre, apellido, edad, monto por hora y número de horas trabajadas, sexo codificado (mujer=1, varón=0), de un trabajador‟) leer ( per3.nombre, per3.apellido, per3.edad, per3.monto_hora, per3.num_hora, per3.sexo ) si per1.sexo = 1 entonces mostrar ( „la empleada:‟ per1.nombre, per1.apellido, „ gana:‟, per1.monto_hora * per1.num_hora) fin-si si per2.sexo = 1 entonces mostrar ( „la empleada:‟ per2.nombre, per2.apellido, „ gana:‟, per2.monto_hora * per2.num_hora) fin-si si per3.sexo = 1 entonces mostrar ( „la empleada:‟ per3.nombre, per3.apellido, „ gana:‟, per3.monto_hora * per3.num_hora) fin-si

fin

Ejemplo 4: Se desea representar información de 5 trabajadores, mediante un arreglo de registros. Cada trabajador se representa con un registro. La información que se guarda en el registro es: nombre, apellido, edad, número de horas trabajadas, monto por hora trabajada, sexo codificado (mujer=1, varón=0). Cargar desde el teclado los registros, y mostrar por pantalla la remuneración de las mujeres, junto con su identificación. algoritmo Calcula_Mayor_remuneracion tipo

registro: persona inicio cadena: nombre, apellido entero: edad, num_hora lógico: sexo real: monto_hora fin_registro array [1..5] de persona: vector var vector:vec entero: i inicio

desde i 1 hasta 5 hacer

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 29 -

ingresar („nombre, apellido, edad, monto por hora y número de horas trabajadas, sexo ( mujer=1, varón=0) del trabajador n:‟, i) leer ( vec[ i].nombre, vec[ i].apellido, vec[ i].edad, vec[ i].monto_hora, vect[ i].num_hora, vec[ i].sexo ) fin-desde desde i 1 hasta 5 hacer si vec[ i].sexo = 1 entonces mostrar(„la empleada:‟ vec[ i].nombre, vec[ i].apellido, „gana:‟, vec[ i].monto_hora * vec[ i].num_hora)

fin-si fin-desde fin

Ejemplo 5: Se desea representar información de 10 trabajadores. Cada trabajador se representa con un registro. La información que se guarda en el registro es: nombre, apellido, edad, número de horas trabajadas, monto por hora trabajada. Cargar desde el teclado los registros, y mostrar por pantalla la remuneración más alta, junto con su identificación. algoritmo Calcula_Mayor_remuneracion const tam = 10 tipo registro: persona inicio cadena: nombre, apellido entero: edad, num_horas real: monto_hora fin_registro array [1..10] de persona: vector

var entero: i vector: ve real: total cadena: nom, ape inicio total 0 desde i 1 hasta tam hacer ingresar ( „nombre, apellido, edad, monto por hora y número de horas trabajadas del trabajador n:‟, i) leer ( ve[ i].nombre, ve[ i].apellido, ve[ i].edad, ve[ i].monto_hora, ve[ i].num_hora) fin_desde

total ve[ 1].monto_hora * ve[1 ].num_hora nom ve[1 ].nombre

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 30 -

ape ve[1 ].apellido

desde i 2 hasta tam hacer si total < (ve[ i].monto_hora * ve[ i].num_hora) entonces

total ve[i ].monto_hora * ve[i ].num_hora nom ve[i ].nombre ape ve[i ].apellido

fin-si fin_desde mostrar ( „la mayor remuneración es: „, total, „el nombre y apellido es:‟, nom,ape) fin

Ejemplo 6: Se desea representar información de 10 trabajadores. Cada trabajador se representa con un registro. La información que se guarda en el registro es: nombre, apellido, remuneración mensual. Cargar desde el teclado los registros mediante un procedimiento. Mediante una función determinar el promedio de remuneración que paga la empresa, y mostrar por pantalla los nombres y apellidos de los trabajadores que perciben por arriba de la remuneración media. algoritmo Calcula_Mayor_remuneracion const tam = 10 tipo registro: persona inicio cadena: nombre, apellido real: remun fin_registro array [1..10] de persona: vector

var entero: i vector: ve real: rem_dedia inicio rem_media 0 carga_registro ( ve) rem_media calcula_remun_media ( ve) mostrar („los empleados que cobran remuneraciones mayores a la media son:‟) desde i 1 hasta tam hacer si rem_media < (ve[ i].remun) entonces

mostrar ( ve[ i].nombre, ve[ i].apellido, ve[ i].remun fin-si fin_desde

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 31 -

fin procedimiento carga_registro ( S persona: ve) var entero: i inicio desde i 1 hasta 10 hacer ingresar( „ nombre, apellido y remuneración de la persona n: „, i) leer (ve[ i].nombre, ve[ i].apellido, ve[ i]remun) fin_desde fin_procedimiento real función calcula_remun_media ( E persona: ve) var entero: i real: media inicio media 0 desde i 1 hasta 10 hacer media media + ve[ i].remun fin_desde media media / 10 devolver media fin_funcion Ejemplo 7: Se desea representar información de 50 trabajadores. Cada trabajador se representa con un registro. La información que se guarda en el registro es: nombre, apellido, remuneración mensual. Cargar desde el teclado los registros mediante un procedimiento. Mediante otro procedimiento determinar la menor y la mayor remuneración que paga la empresa, y mostrar por pantalla los nombres y apellidos de los trabajadores que las perciben. algoritmo Calcula_Mayor_remuneracion const tam = 50 tipo registro: persona inicio cadena: nombre, apellido real: remun fin_registro array [1..50] de persona: vector

var entero: i vector: ve real: extremo cadena: nom, ape

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 32 -

lógica: cual inicio carga_registro ( ve ) mostrar („ se detecta la menor remuneración‟) cual verdadero // bandera, con verdadero busca el menor calcula_remun_extrema (ve, extremo, nom, ape, cual) mostrar („el empleado que cobra la menor remuneración es:‟) mostrar ( nom, ape, extremo) mostrar („ se detecta la mayor remuneración‟) cual falso // bandera, con falso busca el mayor calcula_remun_extrema ( ve, extremo, nom, ape, cual) mostrar („el empleado que cobra la mayor remuneración es:‟) mostrar ( nom, ape, estremo) fin procedimiento carga_registro ( S persona: ve) var entero: i inicio desde i 1 hasta 50 hacer ingresar( „ nombre, apellido y remuneración de la persona n: „, i) leer (ve[ i].nombre, ve[ i].apellido, ve[ i]remun) fin_desde fin_procedimiento procedimiento calcula_remun_extrema ( E persona: ve; S real: extremo; S cadena: nom, ape; E lógico: cual ) var entero: i real: valor inicio si cual = verdadero entonces // se busca la menor remuneración extremo ve[ 1].remun nom ve[ 1].nombre ape ve[ 1].apellido desde i 2 hasta 50 hacer si extremo > ve[ i].remun entonces extremo ve[ i].remun nom ve[i ].nombre ape ve[ i].apellido fin_si fin_desde si_no // se busca el mayor extremo ve[ 1].remun

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 33 -

nom ve[ 1].nombre ape ve[ 1].apellido desde i 2 hasta 50 hacer si extremo < ve[ i].remun entonces extremo ve[ i].remun nom ve[i ].nombre ape ve[ i].apellido fin_si fin_desde fin_si fin_procedimiento Ejemplo 8: Se desea representar información de 10 alumnos. Cada alumno se representa con un registro. La información que se guarda en el registro es: nombre, apellido, promedio general. Cargar desde el teclado los registros mediante un procedimiento. Mediante una función determinar el promedio más alto. algoritmo Calcula_Mayor_promedio const tam = 10 tipo registro: alumno inicio cadena: nombre, apellido real: pro fin_registro array [1..10] de alumno: vector

var entero: i vector: ve real: prome inicio carga_registro ( ve) prome detecta_mayor_pro ( ve) mostrar („el promedio más alto es:‟, prome) fin procedimiento carga_registro ( S alumno: ve) var entero: i inicio desde i 1 hasta 10 hacer ingresar( „ nombre, apellido y promedio del alumno n: „, i) leer (ve[ i].nombre, ve[ i].apellido, ve[ i].pro) fin_desde fin_procedimiento

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 34 -

real función detecta_mayor_pro ( E persona: ve) var entero: i real: mayor inicio mayor ve[ 1].pro desde i 2 hasta 10 hacer si mayor < ve[ i].pro mayor ve[ i ].pro fin_si fin_desde devolver mayor fin_funcion Ejemplo 9: Se desea representar información de 10 alumnos. Cada alumno se representa con un registro. La información que se guarda en el registro es: nombre, apellido, promedio y número de inasistencias. Cargar desde el teclado los registros mediante un procedimiento. Mediante una función determinar cuántos alumnos tienen promedio mayor de 4.00, y mostrar por pantalla ese valor. algoritmo Calcula_numero_aprob const tam = 10 tipo registro: alumno inicio cadena: nombre, apellido real: pro entero: ina fin_registro array [1..10] de alumno: vector

var entero: i, can vector: ve inicio can 0 carga_registro ( ve) can calcula_número_aprob ( ve) mostrar („El número de alumnos con promedio superior a 4.00 es:‟, can) fin procedimiento carga_registro ( S persona: ve) var entero: i

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 35 -

inicio desde i 1 hasta 10 hacer ingresar( „ nombre, apellido, promedio, y numero de ina del alumno n: „, i) leer (ve[ i].nombre, ve[ i].apellido, ve[ i].pro, ve[ i].ina) fin_desde fin_procedimiento entero función calcula_numero_aprob ( E persona: ve) var entero: i, cont inicio cont 0 desde i 1 hasta 10 hacer si ve[ i].pro > 4 entonces cont cont +1 fin-si fin-desde devolver cont fin_funcion Ejemplo 10: Se desea representar información de 10 alumnos. Cada alumno se representa con un registro. La información que se guarda en el registro es: nombre, apellido, promedio general. Cargar desde el teclado los registros mediante un procedimiento. Mediante una función determinar el promedio más alto y el más bajo. algoritmo Calcula_Mayor_promedio const tam = 10 tipo registro: valor inicio real: ma, me fin_registro registro: alumno inicio cadena: nombre, apellido real: pro fin_registro array [1..10] de alumno: vector

var entero: i vector: ve valor: va inicio

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 36 -

carga_registro ( ve) va detecta_mayor_menor ( ve) mostrar („el promedio más alto es:‟, va.ma) mostrar ( „el promedio más bajo es: ‟,va.me) fin procedimiento carga_registro ( S alumno: ve) var entero: i inicio desde i 1 hasta 10 hacer ingresar( „ nombre, apellido y promedio del alumno n: „, i) leer (ve[ i].nombre, ve[ i].apellido, ve[ i].pro) fin_desde fin_procedimiento valor función detecta_mayor_menor ( E persona: ve) tipo registro: resultado inicio real: may,men fin_registro var entero: i resultado: res inicio res.may ve[ 1].pro desde i 2 hasta 10 hacer si res.may < ve[ i].pro res.may ve[ i ].pro fin_si fin_desde res.men ve[ 1].pro desde i 2 hasta 10 hacer si res.men > ve[ i].pro res.men ve[ i ].pro fin_si fin_desde devolver res fin_funcion Ejemplo 11: Se desea representar información de 20 alumnos. Cada alumno se representa con un registro. La información que se guarda en el registro es: nombre, apellido, promedio y número de inasistencias. Cargar desde el teclado los registros mediante un procedimiento. Mediante una función determinar cuántos alumnos tienen promedio menor que 4.00, y más de 10 ina. Mostrar por pantalla estos valores.

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 37 -

algoritmo Calcula_numero_reprob const tam = 20 tipo registro: alumno inicio cadena: nombre, apellido real: pro entero: ina fin_registro array [1..20] de alumno: vector

var entero: i, can vector: ve inicio can 0 carga_registro ( ve) can calcula_número_reprob ( ve) mostrar („El número de alumnos con promedio menor a 4.00 y más de 10 inasistencias es:‟, can) fin procedimiento carga_registro ( S persona: ve) var entero: i inicio desde i 1 hasta 20 hacer ingresar( „ nombre, apellido, promedio, y numero de ina del alumno n: „, i) leer (ve[ i].nombre, ve[ i].apellido, ve[ i].pro, ve[ i].ina) fin_desde fin_procedimiento entero función calcula_numero_reprob ( E persona: ve) var entero: i, cont inicio cont 0 desde i 1 hasta 10 hacer si (ve[ i].pro < 4) y ( ve[i ].ina > 10) entonces cont cont +1 fin-si fin-desde devolver cont

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 38 -

fin_funcion

Ejemplo 12: Generar un arreglo de 10 elementos enteros ordenados de menor mayor. Utilizar ordenamiento por método de selección, una función realiza este ordenamiento y devuelve al algoritmo principal en un dato de tipo registro el menor y el mayor valor del arreglo. El arreglo se carga desde el teclado por medio de un procedimiento Algoritmo ordenación_selección tipo registro: result inicio entero: men, may fin_registro array [1..10] de entero : vector var vector: vec result: re inicio llamar_a carga_arreglo ( vec) re ordenamiento_seleccion ( vec) mostrar ( „ el menor elemento es:‟, re.men, „ y el mayor elemento es: „, re.may) fin procedimiento carga_arreglo ( S entero: vec) var entero: i inicio escribir („ ingresar los valores‟) desde i 1 hasta 10 hacer leer (vec [i ] ) fin-desde fin_procedimiento resultado función ordenamiento_selecion ( E/ S entero: vec) tipo registro: resultado inicio entero: min, max fin-registro var entero: i, j, aux resultado: resul inicio escribir („Comienza el ordenamiento‟) desde i 1 hasta 9 hacer

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 39 -

desde j i+1 hasta 10 hacer si vec [i ] > vec [ j ] entonces

aux vec [ i ] vec [i ] vec [ j ] vec [j ] aux fin-si fin-desde fin-desde escribir („el vector ordenado es:‟ ) desde i 1 hasta 10 hacer mostrar ( vec [ i ]) fin-desde re.max vec[9 ] re.min vec[ 1] devolver re fin_función Ejemplo 13: Se desea cargar mediante un procedimiento un arreglo de 10 elementos de tipo entero. Una función realizará una búsqueda binaria, la clave de búsqueda será tomada desde el teclado y pasada por parámetro a la función, ésta devolverá al programa principal el mensaje de encontrado y en qué posición. El arreglo es sin repetición. Algoritmo busqueda_binaria tipo registro: result inicio entero: pos lógico: enc fin_registro array [1..10] de entero : vector var vector: vec result: re entero: clave inicio llamar_a carga_arreglo ( vec) mostrar ( „ingresar la clave de busqueda‟) leer (clave) llamar_ a ordenamiento_seleccion ( vec) re búsqueda_binaria ( vec, clave) mostrar ( „ la clave de búsqueda :‟, re.enc, „ y está en la posición: „, re.pos) fin procedimiento carga_arreglo ( S entero: vec) var

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 40 -

entero: i inicio escribir („ ingresar los valores‟) desde i 1 hasta 10 hacer leer (vec [i ] ) fin-desde fin_procedimiento procedimiento ordenamiento_selecion ( E/ S entero: vec) tipo registro: resultado inicio entero: min, max fin-registro var entero: i, j, aux resultado: resul inicio escribir („Comienza el ordenamiento‟) desde i 1 hasta 9 hacer desde j i+1 hasta 10 hacer si vec [i ] > vec [ j ] entonces

aux vec [ i ] vec [i ] vec [ j ] vec [j ] aux fin-si fin-desde fin-desde escribir („el vector ordenado es:‟ ) desde i 1 hasta 10 hacer mostrar ( vec [ i ]) fin-desde fin_procedimiento result función búsqueda_binaria ( E entero: x, E entero: clave) tipo registro: resultado inicio entero: pos lógico: enc fin-registro var entero: bajo, central, alto, K, N resultado: resul inicio N 10 K clave // clave de búsqueda

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 41 -

// se inicializan las variables para la búsqueda bajo 1 alto N // N es el número de elementos del arreglo central ent ( ( bajo + alto ) / 2) mientras ( bajo < = alto ) y ( x [ central ] <> K) hacer si K < x [ central] entonces alto central -1 si-no bajo central + 1 fin-si central ent (( bajo +alto ) / 2) fin-mientras // se testea si se hallo el valor si K = x [central] entonces //„valor encontrado res.pos central res.enc verdadero si-no //valor no encontrar res.pos -1 res.enc falso fin-si devolver res fin_funcion

Bibliografía Obligatoria: “Fundamentos de programación. Algoritmos, Estructuras de datos y Objetos”, Luis Joyanes Aguilar. Mc Graw Hill. Tercera edición. Capítulo 7 (páginas 267 a 269). Capítulo 12 páginas 440 a 465).

Materia: Programación Lógica

Profesor: Ing. Silvia A. Carrera - 42 -