Académique Documents
Professionnel Documents
Culture Documents
Jonatan Gom ez Perdomo, Ph.D. Arles Rodr guez, M.Sc. Camilo Cubides, Ph.D.(c)
Indice general
J
I V VII 1 1 1 1 2 2 5 5 5 7 8 8 9 10 10 11 12 13 13 14 14 15
Indice general Indice de tablas Indice de guras 1. Introducci on 1.1. Lenguaje . . . . . . . . . . . . . 1.1.1. L exico . . . . . . . . . . 1.1.2. Sintaxis . . . . . . . . . 1.1.3. Sem antica . . . . . . . 1.2. Lenguajes de Programaci on
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
2. L ogica Matem atica 2.1. L ogica Proposicional . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.1.1. El lenguaje de la l ogica proposicional . . . . . . . . . . . . 2.1.2. Precedencia de conectivos l ogicos . . . . . . . . . . . . . . . 2.1.3. Leyes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.1.3.1. Interpretaci on . . . . . . . . . . . . . . . . . . . . . . 2.1.3.2. Tautolog as, contradicciones y contingencias 2.1.3.3. Equivalencias L ogicas . . . . . . . . . . . . . . . . 2.1.3.4. Implicaciones L ogicas . . . . . . . . . . . . . . . . 2.2. L ogica de predicados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2.1. Cuanticadores . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2.2. Sem antica de los cuanticadores . . . . . . . . . . . . . . . 2.2.3. Leyes de Morgan para cuanticadores . . . . . . . . . . . . 2.2.4. Particularizaci on universal . . . . . . . . . . . . . . . . . . . . 2.2.5. L ogica de predicados en programaci on . . . . . . . . . . . 2.3. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .
II
INDICE GENERAL
3.1.2. Especicaci on de Conjuntos . . . . . . 3.1.2.1. Extensi on . . . . . . . . . . . . 3.1.2.2. Comprensi on . . . . . . . . . 3.1.3. Inclusi on e igualdad . . . . . . . . . . . 3.2. Construcci on de conjuntos . . . . . . . . . . . . 3.2.1. Uni on, intersecci on y complemento . 3.2.2. Conjunto de partes . . . . . . . . . . . . 3.2.3. Producto cartesiano . . . . . . . . . . . 3.2.4. Producto cartesiano generalizado . . 3.2.5. Cardinalidad . . . . . . . . . . . . . . . . 3.3. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . 4. Relaciones y funciones 4.1. Relaciones . . . . . . . . . . . . . . . . . . . . 4.1.1. Propiedades de las relaciones . . 4.1.2. Relaciones de orden . . . . . . . . 4.1.3. Relaciones de equivalencia . . . . 4.2. Funci on parcial . . . . . . . . . . . . . . . . . 4.2.1. Propiedades de las funciones . . 4.3. Funciones importantes en computaci on 4.4. Composici on de funciones . . . . . . . . . 4.5. Ejercicios . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
19 20 20 21 22 22 24 24 25 25 27 29 29 30 32 32 33 34 37 39 41
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . . y . . . . . . . . . . . . . .
5. Identicadores, variables, tipos, operadores, expresiones aritm eticas evaluaci on 5.1. Identicadores y variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.2. Tipos de datos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.2.1. Enteros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.2.2. Reales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.2.3. Booleanos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.2.4. Caracteres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.3. Operadores y expresiones aritm eticas . . . . . . . . . . . . . . . . . . . . . . . . . . 5.3.1. Operadores aritm eticos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.3.2. Operadores de asignaci on . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.3.3. Operadores l ogicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.3.4. Operadores de igualdad y relacionales . . . . . . . . . . . . . . . . . . . . . 5.3.5. Precedencia de operadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.4. Evaluaci on de secuencias de expresiones . . . . . . . . . . . . . . . . . . . . . . . . 5.5. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6. Funciones en programaci on y la estructura condicional 6.1. Compilaci on y ejecuci on de funciones . . . . . . . . . . . . . . . 6.2. Funciones con m as de un par ametro de entrada . . . . . . . . 6.3. La estructura de control de condicional s (if) . . . . . . . . . 6.3.1. El condicional if . . . . . . . . . . . . . . . . . . . . . . . . 6.3.2. El condicional if sin la sentencia else . . . . . . . . .
43 43 44 44 45 46 46 48 48 48 49 49 50 51 54 55 58 59 61 61 63
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
INDICE GENERAL
III 64 66 68
6.3.3. Estructuras if enlazadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.4. Validaci on de datos usando condicionales . . . . . . . . . . . . . . . . . . . . . . . . 6.5. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7. Funciones recursivas 69 7.1. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 8. Las 8.1. 8.2. 8.3. 8.4. 8.5. 8.6. 8.7. estructuras c clicas La estructura de control de ciclos mientras (while) La estructura de control de ciclos para (for) . . . . . La estructura de control de ciclos hacer (do) . . . . . Simulaci on de ciclos usando funciones recursivas . . Variables del ciclo while . . . . . . . . . . . . . . . . . . . . Validaci on de datos usando ciclos . . . . . . . . . . . . . Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 93 95 98 100 101 101 103
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
9. Flujos de Entrada y Salida 9.1. Trabajando con archivos de entrada . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.2. Trabajando con archivos de salida . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.3. Ejemplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.Vectores o arreglos unidimesionales 10.1. Utilizando arreglos con funciones . . . . . . . . . . . . . . . . . . . . . 10.2. Arreglos y ujos de datos . . . . . . . . . . . . . . . . . . . . . . . . . . 10.3. Subindices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.4. Ejercicios sobre arreglos . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.4.1. Suma de los elementos de un arreglo . . . . . . . . . . . . . 10.4.2. Promedio de los elementos de un arreglo . . . . . . . . . . . 10.4.3. Determinar si un arreglo de reales est a ordenado . . . . . 10.4.4. Obtener el m aximo elemento de un arreglo de tipo real 10.4.5. Ordenar un arreglo de reales de tama no n . . . . . . . . . .
105 . 106 . 107 . 107 109 110 112 112 113 113 114 114 114 114
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
11.Cadenas de Caracteres 117 11.1. Codigo Completo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 11.2. Ejercicios Interesantes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 12.Tipos Abstractos de Datos (TDA) 12.1. Estructura y Operaciones . . . . . . . . . . . . 12.2. Denici on de un TDA . . . . . . . . . . . . . . . 12.2.1. Funciones Constructoras . . . . . . . . 12.2.2. Funciones Analizadoras . . . . . . . . . 12.2.3. Funciones Modicadoras . . . . . . . . 12.3. Otras Funciones y Funciones Analizadoras . 12.4. Funciones de Persistencia o E/S . . . . . . . . 12.5. Funciones Liberadoras . . . . . . . . . . . . . . . 12.6. Programa Principal . . . . . . . . . . . . . . . . . 125 125 126 127 127 128 129 129 131 131
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
IV
INDICE GENERAL
13.Matrices o arreglos bidimensionales 13.1. Conceptos y notaci on . . . . . . . . . . . . . . . 13.2. Deniciones alternativas . . . . . . . . . . . . . 13.2.1. El conjunto de las matrices . . . . . . 13.3. Las matrices en computaci on . . . . . . . . . . 13.3.1. Funciones para utilizar matrices . . . 13.3.1.1. Creaci on de matrices . . . . 13.3.1.2. Liberaci on de matrices . . . 13.3.1.3. Matrices y ujos de datos 13.3.2. Ejemplos de funciones con matrices Bibliograf a
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
133 133 135 135 136 136 136 138 139 142 147
Indice de tablas
2.1. Prioridad de los conectivos l ogicos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2. Equivalencias l ogicas. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3. Implicaciones l ogicas. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.1. Precedencia de los operadores en C++. . . . . . . . . . . . . . . . . . . . . . . . . . .
8 11 12 50
VI
INDICE DE TABLAS
Indice de guras
A B mediante diagramas de Venn. A B mediante diagramas de Venn. B A mediante diagramas de Venn. . . A mediante diagramas de Venn. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
22 23 23 24 30 31 34 34 35 35 36 36 37 40
4.1. Representaci on de la relaci on R = (0, p), (0, m), (2, m), (2, o) mediante diagramas Sagitales. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2. Representaci on de la relaci on R = (p, o), (o, p), (n, m), (m, n) mediante diagramas Sagitales. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.3. Representaci on de la funci on f = (0, o), (1, o), (4, n) mediante diagramas Sagitales. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.4. Representaci on de la relaci on f = (0, p), (1, p), (2, n), (1, m) mediante diagramas Sagitales. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.5. Representaci on de la funci on inyectiva f = (0, m), (2, p) mediante diagramas Sagitales. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.6. Representaci on de la funci on sobreyectiva f = (0, p), (1, n), (2, m), (4, p) mediante diagramas Sagitales. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.7. Representaci on de la funci on total f = (0, m), (1, o), (2, p), (3, m), (4, p) mediante diagramas Sagitales. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.8. Representaci on de la funci on biyectiva f = (0, n), (1, o), (2, m), (3, p) mediante diagramas Sagitales. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.9. Representaci on de la funci on identidad idA . . . . . . . . . . . . . . . . . . . . . . . . 4.10. Representaci on mediante diagramas Sagitales de la composici on de las funciones f y g , f g = (1, a), (2, d), (3, c), (4, c), (6, c) . . . . . . . . . . . . . . . .
VII
VIII
INDICE DE FIGURAS
Cap tulo
Introducci on
1.1. Lenguaje
Un lenguaje es un conjunto de elementos que nos permite expresarnos y comunicarnos con otros entes, ya sean personas, animales, computadores, etc. Un lenguaje est a denido por tres elementos, el l exico, la sintaxis y la sem antica.
1.1.1. L exico
El l exico de un lenguaje lo conforman las unidades m nimas con signicado completo. A cada uno de estas unidades m nimas con signicado se le conoce como lexema 1 . Por ejemplo, en el espa nol, las palabras y los s mbolos de puntuaci on (que son usados para formar frases, oraciones y p arrafos) conforman el l exico. A tales lexemas se les asocia un signicado preciso en t erminos de las frases construidas con ellos.
1.1.2. Sintaxis
La sintaxis de un lenguaje explica la forma en que se pueden construir frases en el lenguaje a partir del l exico. Usualmente la sintaxis se presenta como una colecci on de reglas de reescritura que se denen con una gram atica. Estas son reglas que indican como unos s mbolos de la gram atica pueden ser reescritos por otros s mbolos de la gram atica o por lexemas. La idea es que al nal del proceso de reescritura s olo se tengan lexemas. Por ejemplo en espa nol una frase se puede reescribir como un sujeto y un predicado, a su vez un sujeto se puede reescribir como un art culo, un sustantivo y un adjetivo, nalmente un sustantivo puede ser reescrito como la palabra perro.
La palabra lexema usada en este libro tiene un signicado similar (pero no igual) a la que se usa en ling u stica. En ling u stica las palabras m ovil y m oviles se derivan del mismo lexema (m ovil), es decir, son el mismo lexema (por las relaciones sem anticas propias del espa nol), solamente que tienen diferente gramema (, -es ).
1
CODIGO ARGUMENTO(S) Lenguaje ensamblador: Surgi o la necesidad de desarrollar un lenguaje de nivel mayor al de la m aquina, y se desarroll o una forma de construir un lenguaje intermedio que empleara mnem onicos (palabras cortas escritas con caracteres alfanum ericos), para codicar las operaciones. Los datos y/o direcciones son codicados generalmente como n umeros en un sistema hexadecimal. Generalmente es espec co (aunque no u nico) para cada lenguaje de m aquina. La estructura de una instrucci on en este lenguaje es la siguiente: MNEMONICO ARGUMENTO(S) Un Ensamblador es un software, generalmente escrito en lenguaje de m aquina, que es capaz de traducir de lenguaje ensamblador a lenguaje de m aquina. Este lenguaje di o el salto fundamental. Dicho salto se da cuando se logra separar el programa de la m aquina empleando los conceptos de m aquina de Turing y la arquitectura de Von Neumann. Almacenando el programa en memoria y empleando el hardware como elemento de control. Esto di o origen a los sistemas operativos, logrando que la m aquina completa pudiera controlar otro programa. Lenguajes de alto nivel: Posteriormente se plante o la idea de generar un lenguaje mas parecido al lenguaje natural y que realizara la compilaci on del programa y generara un programa de c odigo de m aquina. Lenguajes como Basic empleaban interpretes tomando cada instrucci on y traduci endola a Ensamblador y de Ensamblador a c odigo de m aquina. Se plante o la idea de tomar un c odigo y traducirlo completamente a lenguaje de m aquina mediante un proceso de compilaci on. El lenguaje de programaci on C entra en esta categor a de lenguajes. Dichos lenguajes est an basados en una estructura gramatical para codicar estructuras de control y/o instrucciones. Cuenta con un conjunto de palabras reservadas (escritas en lenguaje natural). Estos lenguajes permiten el uso de s mbolos aritm eticos y relacionales para describir c alculos matem aticos, y generalmente representan las cantidades num ericas mediante sistema decimal. Gracias a su estructura gramatical, estos lenguajes permiten al programador olvidar el direccionamiento de memoria (donde cargar datos y/o instrucciones en la memoria), ya que este se realiza mediante el uso de conceptos como el de variable. Los compiladores e interpretes son software capaz de traducir de un lenguaje de alto nivel al lenguaje ensamblador espec co de una m aquina. Los primeros toman todo el programa en lenguaje de alto nivel, lo pasan a lenguaje ensamblador y luego lo ejecutan. Los u ltimos toman instrucci on por instrucci on, la traducen y la van ejecutando. Posteriormente se desarrollaron lenguajes intermedios que tomaran una parte compilada y otra interpretada. Es cuando surgen lenguajes como Java y Python. Java
compila su c odigo y genera c odigo bytecode que se ejecuta en una m aquina virtual espec ca que conoce las instrucciones de bytecode permitiendo su ejecuci on en diferentes sistemas operativos.
Cap tulo
Las letras proposicionales son usadas para representar proposiciones, por lo tanto el signicado de una letra proposicional es el signicado que tiene la proposici on que dicha letra representa. El s mbolo proposicional es usado para representar una proposici on con signicado siempre falso 1 , mientras que es usado para representar una proposici on con signicado siempre verdadero 2 . Los conectivos l ogicos son s mbolos que permiten, a partir de s mbolos y/o letras proposicionales, formar frases. En la denici on mas com un de la l ogica proposicional cl asica, una de las cuales es la l ogica cl asica estos s mbolos son la negaci on (), el o l ogico (), el y l ogico (), la implicaci on () y la equivalencia (). El signicado que cada uno de estos conectivos le da a las frases que se construyen con ellos se explicar a m as adelante3 . Los par entesis son usados para agrupar de manera apropiada las frases o f ormulas de la l ogica proposicional. En la l ogica proposicional la gram atica se describe en t erminos de f ormulas bien for4 madas (fbf) de manera recursiva , es decir, suponiendo que los s mbolos y letras proposicionales son fbfs y deniendo nuevas fbfs en t erminos de fbfs ya construidas. Denici on. La gram atica de la l ogica proposicional se dene recursivamente en t erminos de f ormulas bien formadas (fbf), as : i) Si p es un s mbolo o letra proposicional, entonces p es una fbf. ii) Si f es fbf entonces (f ) es una fbf. iii) Si f1 y f2 son fbfs entonces: (f1 f2 ), (f1 f2 ), (f1 f2 ) y (f1 f2 ) son fbfs. En el lenguaje de la l ogica proposicional, a diferencia del espa nol u otro lenguaje natural, la sem antica es f acil de denir ya que los posibles sentidos que tiene una frase son solamente dos (verdadero y falso ) y las frases que se pueden construir se denen de manera recursiva (f ormulas bien formadas). Ejemplo. Las siguientes secuencias de s mbolos son f ormulas bien formadas: f1 : (p (q )) (r s) f2 : (r q ) (q s)
Ejemplo. Las siguientes secuencias de s mbolos no son f ormulas bien formadas: f1 : ( p)(r s) f2 : ( p q ) ( q p)
Denici on. La sem antica de la l ogica proposicional se dene de manera recursiva sobre las f ormulas bien formadas as ( (f ) se usa para representar el signicado de la f ormula bien formada f ): i) Si f es un fbf denida solamente por un s mbolo o letra proposicional, el signicado de la f ormula f es el mismo signicado del s mbolo o letra proposicional.
Que se representar a abreviadamente por el s mbolo F . Que se representar a abreviadamente por el s mbolo V . 3 Existen diversas formas de denir la l ogica proposicional cl asica dependiendo de los conectivos l ogicos usados (s mbolo y denici on sem antica). La presentada aqu es la mas usual y se le dice cl asica por la denici on sem antica de los conectivos l ogicos. 4 En una denici on recursiva se denen casos particulares o base y los dem as se denen como construcciones sobre estos casos base y sobre estas construcciones.
2 1
() F
(f ) F V
(f1 ) (f2 ) (f1 f2 ) (f1 f2 ) (f1 f2 ) (f1 f2 ) V V V V V V V F V F F F V V F V F F F F F V V F Ejemplo. Suponga que (p) = F, (q ) = F, (r) = V , entonces el signicado (valor de verdad) de la f ormula bien formada f : (p) q (r q ) () para hallar el signicado de f , primero se debe hallar el valor de verdad de los par entesis m as internos y luego con esos resultados ir hallando el valor de verdad de las f ormulas m as internas que vayan apareciendo, de esta manera (p) (q ) (r) (p) F F V V (r q ) F () V (p) q F
(r q ) () V
(p) q (r q ) () F
(p) q (r q ) () V as , (f ) = V .
de completar los par entesis, los par entesis asociados al operador con m as prioridad son adicionados primero que los par entesis de un conectivo con menor prioridad. Las prioridades asignadas a los operadores se pueden observar el la tabla 2.1. Cuando en la f ormula aparece el mismo operador varias veces y no se puede determinar a cu al se le deben asignar los par entesis primero, se asignan los par entesis de izquierda a derecha. Conectivo Prioridad Signicado 1 alta , 2 medio , 3 baja
Tabla 2.1. Prioridad de los conectivos l ogicos.
Ejemplo. La f ormula p q r s representa la fbf (p q ) (r s) , ya que completando par entesis: i) p q r s ii) p q (r s) iii) (p q ) (r s) iv) (p q ) (r s) ( prioridad 3) ( m as a la izquierda prioridad 4) ( prioridad 4)
2.1.3. Leyes
En la l ogica proposicional cl asica, una ley l ogica es una equivalencia o implicaci on entre f ormulas l ogicas. Tal equivalencia o implicaci on l ogica debe ser verdadera para cualquier interpretaci on de las letras proposicionales que conforman las f ormulas relacionadas por la equivalencia (debe ser tautolog a). Las m as famosas leyes l ogicas son: Modus Ponen, Modus Tollen, Inconsistencia, Doble negaci on, Conmutatividad, Distributivas, Asociativas y Morgan. 2.1.3.1. Interpretaci on Dada una colecci on de s mbolos proposicionales, una interpretaci on de es una asignaci on de valores de verdad a cada una de las letras proposicionales de la colecci on. Ejemplo. Sea = {q, r, s}. 1. Una interpretaci on de es: (q ) = V, (r) = V, (s) = F . 2. Una interpretaci on de es: (q ) = F, (r) = F, (s) = F . 3. Una interpretaci on de es: (q ) = F, (r) = V, (s) = V . Propiedad. Si una colecci on tiene n letras proposicionales entonces tiene en total 2n interpretaciones diferentes.
Ejemplo. Las interpretaciones posibles de la colecci on de letras proposicionales = 3 {p, q, r}, entonces tiene ocho (2 = 8) interpretaciones: (p) V V V V F F F F (q ) V V F F V V F F (r ) V F V F V F V F
Nota. El valor de verdad de una f ormula f para una interpretaci on I de f se notar a como I (f ). 2.1.3.2. Tautolog as, contradicciones y contingencias Una f ormula f se dice tautolog a si para cualquier interpretaci on de su conjunto de letras proposicionales, su signicado (valor de verdad) es V , se dice contradicci on si para cualquier interpretaci on su signicado es F y se dice contingencia si no es tautolog a ni contradicci on. Ejemplo. Determinar el tipo (tautolog a, contingencia o contradicci on) de cada una de las siguientes f ormulas: 1. f = p q q p 2. f = p p 3. f = p (q r) Soluci on. 1. Si f = p q q p entonces f = {p, q } p V V F F entonces f es tautolog a. 2. Si f = p p entonces f = {p} p V F p F V p p F F q V F V F pq V V V F qp V V V F pq qp V V V V
10
entonces f es contradicci on. 3. Si f = p (q r) entonces = {p, q, r} p V V V V F F F F entonces f es contingencia. Al esquema de presentar todas las interpretaciones y el valor de verdad de la f ormula se le llama tabla de verdad de la f ormula f . Las tablas de verdad son muy u tiles para realizar demostraciones a nivel sem antico, ya que ellas no solamente se pueden usar con letras proposicionales sino con f ormulas bien formadas, es decir, considerando toda una f ormula bien formada como verdadera o falsa y construyendo la tabla de verdad para dichas f ormulas. 2.1.3.3. Equivalencias L ogicas Denici on. Sean f1 y f2 dos f ormulas, se dice que f1 es l ogicamente equivalente a f2 , (f1 f2 ) si y solamente si la f ormula f1 f2 es una tautolog a. Ejemplo. Las f ormulas f1 = ( ) y f2 = son l ogicamente equivalentes, es decir, ( ) , para cualesquiera f ormulas y . Para esto, se debe demostrar que ( ) es una tautolog a; como se aprecia en la siguiente tabla V V F F ( ) ( ) V V F F F F V F F V F V V V V F V V F V V F F V V V V V q V V F F V V F F r V F V F V F V F qr V V V F V V V F p (q r) V V V F F F F F
como se observa, f1 f2 es una tautolog a, por lo tanto, f1 y f2 son l ogicamente equivalentes. Las equivalencias l ogicas m as conocidas se presentan en la tabla 2.2. La demostraci on de las mismas se deja al lector. 2.1.3.4. Implicaciones L ogicas Denici on. Sea = {f1 , f2 , . . . , fn } una colecci on de f ormulas (premisas ) y g una f ormula (conclusi on ), se dice que implica l ogicamente a g ( g ), si y solamente si (f1 f2 fn ) g es una tautolog a.
11
Equivalencia ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( )
Nombre Tercio exclu do Contradicci on Identidad Dominaci on Idempotencia Doble negaci on Conmutativas Asociativas Distributivas Morgan
Ejemplo. Las premisas = {, } implican l ogicamente a g = , para esto es necesario que la f ormula ( ) sea una tautolog a, como se aprecia en la siguiente tabla V V F F ( ) V F V F F F V F F F V F V F V F V V V V ( ) V V V V
como se observa, ( ) es una tautolog a, por lo tanto, = {, } implica l ogicamente a g = . Las implicaciones l ogicas m as conocidas se presentan en la tabla 2.3. Se deja al lector la demostraci on de las mismas.
12
Implicaci on Nombre {, } ( ) Combinaci on {, } Ley de simplicaci on {, } Variante de la ley de simplicaci on {} ( ) Ley de adici on { } ( ) Variante de la adici on {, } Modus ponens {, } Modus tollens { , } ( ) Silogismo hipot etico {, } Silogismo disyuntivo {, } Variante de silog smo disyuntivo { , } Ley de casos { } ( ) Eliminaci on de equivalencia { } ( ) Variante de eliminaci on de equivalencia { , } ( ) Introducci on de la equivalencia {, } Ley de inconsistencia
Tabla 2.3. Implicaciones l ogicas.
x e y son objetos que est an relacionados con un predicado y dependiendo del objeto, se tiene una proposici on que es verdadera o es falsa. En t erminos de estos se dene un predicado como una frase que tiene un valor que verdad dependiendo de los objetos de los que se este hablando. En el ejemplo anterior el predicado es JuegaCon y se escribir a de la forma JuegaCon(x, y ), que se interpreta conceptualmente como x juega con y . Un predicado da una forma m as amplia de hablar. Se podr a tener una colecci on {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}, y sobre esta colecci on se dene un predicado. Se podr a hablar del predicado esP ar(x). Si se toma el predicado esP ar(3) este tiene un valor de verdad falso, si se toma el predicado esP ar(6) este tiene un valor de verdad verdadero. A una colecci on de objetos a los cuales se les desea aplicar el predicado se le llama el universo de discurso. Cuando en un predicado se reemplaza una variable x por un valor concreto del universo del discurso, se dice que se est a instanciando la variable x, la f ormula resultante se dice que es una instancia del predicado inicial. De esta manera cuando se instancian todas la variables de un predicado, lo que se obtiene es una proposici on, y por lo tanto cumple la condici on de que en ning un caso la instancia puede ser verdadera y falsa a la vez.
2.2.1. Cuanticadores
Pueden haber predicados como esDigito(x) que para todos los objetos del universo del discurso {1, 2, 3, 4, 5, 6, 7, 8, 9, 0} son verdaderos. Para este mismo universo, el predicado esM ayora10(x) es falso para todos los elementos de dicha colecci on, y el predicado esM oduloAditivo(x) es verdadero s olo para x = 0 y para el resto de los casos ser a falso. Cuando se desea expresar que un predicado P (x) describe una propiedad sobre todos los elementos del universo del discurso o para s olo algunos, se dice que se est a cuanticando la variable x.
13
Cuando se desea expresar que un predicado describe una propiedad para todos los elementos del universo del discurso, se dice que se est a cuanticando universalmente. Cuando el predicado describe una propiedad para algunos de los elementos del universo del discurso, se dice que se est a cuanticando existencialmente. Para expresar estas nuevas propiedades se necesitan nuevos s mbolos, y estos son los s mbolos y que permiten ampliar el l exico y se utilizan de la siguiente manera: Para notar que una variable x est a cuanticada universalmente en un predicado P (x) se utiliza la expresi on xP (x) que se lee para todo x P (x). Para notar que una variable x est a cuanticada existencialmente en un predicado P (x) se utiliza la expresi on xP (x) que se lee existe x P (x).
14
xP (x) xP (x): no todo x cumple el predicado P es decir que existe un x que no cumple el predicado.
2.3. EJERCICIOS
15
2.3. Ejercicios
1. De los siguientes enunciados cu ales son proposiciones y cu ales no?, justique su respuesta. Tom Hanks ha ganado dos premios Oscar como mejor actor por dos a nos consecutivos. Dame una cerveza. Colombia gan o ocho medallas ol mpicas en Londres 2012. Todo n umero primo es impar. 1 + 1 = 2. La diferencia de dos primos. Todo n umero par mayor que 2 puede escribirse como suma de dos n umeros primos. (Christian Goldbach, 1742). Que hora es?. xn + y n = z n . x + y = z + y si x = z . 2. De las siguientes secuencias de s mbolos cu ales son f ormulas bien formadas y cu ales no?. ((p) r) (p q ) ((p) (q )) (q r) ( p q ) ( q p) (p p) (p p) (p (p)) 3. Escriba la f ormula bien formada que representa cada una de la siguientes secuencias de s mbolos: pq rsq pqqp p q r (q r) q p (q r) p q (p q ) 4. Hallar el signicado de cada f ormula que se especica a continuaci on con respecto a la interpretaci on denida para esta. f = p q r s q , si (p) = V , (q ) = V , (r) = V , (s) = F . f = p q q p, si (p) = V , (q ) = F . f = p q r (q r) q , si (p) = F , (q ) = V , (r) = V . f = p (q r) p q (p q ), si (p) = V , (q ) = F , (r) = V . 5. Verique las equivalencias l ogicas de la tabla 2.2.
16
6. Verique las implicaciones l ogicas de la tabla 2.3. 7. Verique que las f ormulas f1 = p q r y f2 = p (q r) no son l ogicamente equivalentes. 8. Con los operadores l ogicos y es posible expresar los otros operadores l ogicos (, , ) de forma equivalente, de la siguiente manera p q (p q ) p q (p q ) p q (p q ) (q p) vericar que efectivamente los operadores l ogicos , , se pueden expresar en t erminos de los operadores l ogicos y . 9. Con los operadores l ogicos y es posible expresar los otros operadores l ogicos (, , ). Encontrar f ormulas l ogicas que contengan s olo los operadores l ogicos y que sean equivalentes a las f ormulas p q , p q , p q y verique que efectivamente son l ogicamente equivalentes. 10. Adicional a los conectivos l ogicos presentados, existen otros conectivos, tal como el conectivo o exclusivo (), el cual es muy utilizado en computaci on, y tiene como objetivo que dadas dos f ormulas f1 y f2 , la operaci on f1 f2 ser au nicamente verdadera cuando se cumpla que s olo una de la f ormulas f1 o f2 sea verdadera. De esta manera, la sem antica para este conectivo es la siguiente (f1 ) (f2 ) V V V F F V F F (f1 f2 ) F V V F
(a) Encuentre una f ormula que sea equivalente l ogicamente a la f ormula f1 f2 , que s olo utilice los operadores l ogicos y . (b) Encuentre una f ormula que sea equivalente l ogicamente a la f ormula f1 f2 , que s olo utilice los operadores l ogicos y . 11. Adicional a los conectivos l ogicos presentados, existe otro conectivo, tal como el conectivo barra de Sheer (|), para el cual su sem antica es la siguiente (f1 ) V V F F (f2 ) (f1 | f2 ) V F F V V V F V
2.3. EJERCICIOS
17
La principal caracter stica de este conectivo es que las f ormulas f , f1 f2 , f1 f2 , f1 f2 , f1 f2 , son l ogicamente equivalentes a f ormulas que s olo contienen el conectivo |, como se observa a continuaci on f f1 f2 f1 f2 f1 f2 f |f (f1 | f1 ) | (f2 | f2 ) (f1 | f2 ) | (f1 | f2 ) f1 | (f2 | f2 )
(a) Verique las anteriores equivalencias l ogicas. (b) Encuentre una f ormula que s olo utilice el conectivo | y que sea l ogicamente equivalente a la f ormula f1 f2 . 12. Adicional a los conectivos l ogicos presentados, existe otro conectivo, tal como el conectivo echa de Peirce (), para el cual su sem antica es la siguiente (f1 ) (f2 ) V V V F V F F F (f1 f2 ) F F F V
La principal caracter stica de este conectivo es que las f ormulas f , f1 f2 , f1 f2 , f1 f2 , f1 f2 , son l ogicamente equivalentes a f ormulas que s olo contienen el conectivo , como se observa a continuaci on f f f f1 f2 (f1 f2 ) (f1 f2 ) f1 f2 (f1 f1 ) (f2 f2 ) f1 f2 (f1 f1 ) f2 (f1 f1 ) f2 (a) Verique las anteriores equivalencias l ogicas. (b) Encuentre una f ormula que s olo utilice el conectivo y que sea l ogicamente equivalente a la f ormula f1 f2 . 13. Hallar el valor de verdad para los siguientes predicados con variables cuanticadas y cuyo universo del discurso son los n umeros reales. i. x(x es mayor que cada n umero natural). ii. x(x es menor que todos los n umeros naturales positivos). iii. x(x tiene inverso aditivo). iv. x(x2 > 0). v. x(x 0). vi. x(x tiene inverso multiplicativo).
18
vii. x(xy = x, para todo n umero real y ) viii. x(x es divisor de cada n umero real). ix. x(ax2 + bx + c = 0, para todos los n umeros reales a,b y c). x. x(ax3 + bx2 + cx + d = 0, para todos los n umeros reales a, b, c y d). 14. Usando las leyes de Morgan para cuanticadores, negar los predicados del numeral 13.
Cap tulo
Teor a de conjuntos
3.1. Conceptos b asicos
3.1.1. Conjunto y elemento
Un conjunto A es una colecci on bien denida de objetos. Se dice que una colecci on A est a bien denida si existe un predicado A (llamado constructor del conjunto A), que determina de manera exacta los objetos que pertenecen a la colecci on. Ejemplo. La colecci on A = {1, 2, 3, 4} es un conjunto, ya que el siguiente predicado determina de manera exacta los objetos que pertenecen a A: A (x) = V, si x = 1, x = 2, x = 3 o x = 4; F, en otro caso.
Un objeto x se dice que es un elemento del conjunto A si y s olo si A (x) = V . En el caso en que A (x) = F , se dice que el objeto x no es un elemento del conjunto A. Ejemplo. Para el conjunto A = {1, 2, 3, 4}, se tiene que 1 es elemento de A (A (1) = V ), y 5 no es elemento de A (A (5) = F ). Los predicados constructores de conjuntos, permiten denir el siguiente predicado que relaciona elementos con conjuntos: (x, A) A (x) Este predicado es conocido como el predicado pertenece. x A es usado para denotar que (x, A), y x / A es usado para denotar (x, A) .
20 3.1.2.1. Extensi on
Si se listan exhaustivamente los elementos que conforman el conjunto, se dice que se est a especicando el conjunto por extensi on. Esto se hace mediante la siguiente notaci on: A = {x1 , x2 , . . . , xn } Donde xi son los objetos en el conjunto A. De esta manera el predicado asociado al conjunto es, V, si x = xi para alg un i = 1, 2, . . . , n; A (x) = F, en otro caso. Ejemplos. 1. A = {1, 2, 3, 4} 2. B = {p, o, n, m} 3. C = {a, e, i, o, u} 4. B = {V, F } 5. N = {0, 1, 2, 3, 4, 5, . . .} 6. P = {1, 2, 3, 4, 5, . . .} 7. Z = {. . . , 3, 2, 1, 0, 1, 2, 3, . . .} 3.1.2.2. Comprensi on Si se presenta expl citamente el predicado que dene el conjunto, se dice que se est a especicando el conjunto por comprensi on. Esto se hace mediante la siguiente notaci on: A = x : A (x) . En esta notaci on, el s mbolo : se lee tal que . Ejemplos. 2N = x : (x = 2n) (n N) 2N + 1 = x : (x = 2n + 1) (n N) Q = x : (x = p/q ) (p, q Z) (q = 0) I = {x : x es un n umero irracional} R = {x : x es un n umero real} R+ = x : (x R) (x > 0) R = x : (x R) (x < 0)
21
R0,+ = x : (x R) (x 0)
C = x : (x = a + bi) (a, b R) (i = (i denota la unidad imaginaria) A = x : (x R) (x2 1) B = {x : x es una pinta del poker}
1)
C = {x : x es una vocal del idioma espa nol} El conjunto x : (x = x) es llamado conjunto vac o porque no tiene elemento alguno (no existe objeto alguno que sea diferente de si mismo). El s mbolo es usado para notar al conjunto vac o. (x ) = F para todo x objeto.
22
Ejemplo. Sean A = {2, 4, 8, p, n} y B = {1, 2, 3, 4, p, n, :}, entonces A B = {1, 2, 3, 4, 8, p, n, :}. Propiedades. Sean A, B y C conjuntos. 1. A B = B A. (conmutatividad) 2. (A B ) C = A (B C ). (asociatividad) Sean A y B dos conjuntos, el conjunto intersecci on de A y B es el formado con los elementos que est an en A y est an en B . El conjunto intersecci on es u nico, se nota A B y se dene formalmente mediante el siguiente predicado AB (x) x (A B ) := (x A) (x B ) Utilizando notaci on por comprensi on A B = x : (x A) (x B ) . En la gura 3.2 se muestra una representaci on gr aca de la operaci on A B entre conjuntos. Ejemplo. Sean A = {2, 4, 8, p, n} y B = {1, 2, 3, 4, p, n, :}, entonces A B = {2, 4, p, n}.
23 B
B AB
Propiedades. Sean A, B y C conjuntos. 1. A B = B A. (conmutatividad) 2. (A B ) C = A (B C ). (asociatividad) Sean A y B dos conjuntos, el conjunto complemento de A relativo a B es el conjunto de todos los elementos que est an en B y que no est an en A. El conjunto complemento B relativo es u nico, se nota A y se dene formalmente mediante el siguiente predicado AB (x) x A Utilizando notaci on por comprensi on A = x : (x / A ) (x B ) . En la gura 3.3 se muestra una representaci on gr aca de la operaci on A entre conjuntos. A B A
B B B B
:= (x / A ) (x B )
Ejemplo. Sean A = {2, 4, 8, p, n} y B = {1, 2, 3, 4, p, n, :}, entonces A = {1, 3, :}. Cuando B es un universo para A, el conjunto A es llamado complemento de A y es notado A. En la gura 3.4 se muestra una representaci on gr aca de la operaci on A sobre un conjunto. Ejemplo. Sean U = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0, p, o, n, m, :} un universo para A = {2, 4, 8, p, n}, entonces A = {1, 3, 5, 6, 7, 9, 0, o, m, :}. Propiedades. Sean A y B conjuntos, U un universo para A y B .
B
24
U A A A
1. A A = U. 2. A A = . 3. (A B ) = A B. 4. (A B ) = A B.
(A)
:= (X A)
(A) = {X : X A}.
Ejemplo. Para el conjunto A = {1, 2, 3} se tiene que
(A) =
, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1, 2, 3} .
2. 2 (x, y ) =
25
El conjunto producto cartesiano de dos conjuntos A y B , es el conjunto de todas las parejas ordenadas, cuya primer componente es un elemento del conjunto A y cuya segunda componente es un elemento del conjunto B . El conjunto producto cartesiano es u nico y se nota A B . El conjunto producto cartesiano puede ser denido mediante el siguiente predicado AB (x, y ) (x, y ) A B := (x A) (y B ) Utilizando notaci on por comprensi on A B = (x, y ) : (x A) (y B ) . Ejemplo. Para los conjuntos A = {1, 2, 3} y B = {p, o, n, m} se tiene que A B = (1, p), (1, o), (1, n), (1, m), (2, p), (2, o), (2, n), (2, m), (3, p), (3, o), (3, n), (3, m) . B A = (p, 1), (p, 2), (p, 3), (o, 1), (o, 2), (o, 3), (n, 1), (n, 2), (n, 3), (m, 1), (m, 2), (m, 3) .
3.2.5. Cardinalidad
Todos los conjuntos poseen una propiedad muy importante llamada cardinalidad, esta se reere a la cantidad de elementos que posee el conjunto. El cardinal de un conjunto A es u nico y se denota por |A|. Con base en el concepto de cardinal se puede decidir si un conjunto es nito o innito, as , un conjunto es nito si el conjunto es el vac o o su cardinal es un n umero natural, en caso contrario se dice que es innito. Ejemplo. Para los siguientes conjuntos nitos
|D| = 1 |E | = 2 |F | = 4
|G| = 7 |H | = 7 |I | = 15
Para el caso de los conjuntos innitos, estos pueden tener distinto cardinal, Ejemplo. |N| = 0 (que se lee alef cero ) |P| = 0 |2N| = 0 |2N + 1| = 0 |Z| = 0 |Q| = 0 |N N| = 0 |(N)| = 1 = 20 |I| = 1 = 20 |R| = 1 = 20 |R R| = 1 = 20 |C| = 1 = 20
Un conjunto es enumerable si tiene el mismo cardinal de los naturales. Si un conjunto es nito o enumerable entonces se dice que es contable. Cuando dos conjuntos tienen el mismo cardinal se dice que son equipotentes.
3.3. EJERCICIOS
27
3.3. Ejercicios
1. Sea A el siguiente predicado constructor del conjunto A A (x) = V, si x es un d gito y x es un multiplo de 3; F, en otro caso.
Cu al es el conjunto listado por extensi on que dene A (x)?. 2. Si A = {2, 4, 6, 8, 0}, denir un predicado constructor A para el conjunto A. 3. Encuentre todos los conjuntos A, tales que A B , para el conjunto B = {G, I, L, N}. 4. Sea U = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0, G, I, L, N} un universo para los conjuntos A = {2, 4, 6, 8, 0, G, L}, B = {3, 6, 9, 0, G, N} y C = {1, 3, 5, 7, 9, I, N}. Calcule: i. A B ii. A C iii. (A B ) C iv. (A C ) (B C ) v. B C vi. A C vii. B C viii. A ix. A x. A
B C C B
xi. A B xii. A
B
C
(A)
ii.
(B )
iii.
(C )
iv.
(D)
6. Sean A = {2, 4, 6, 8, 0}, B = {G, I, L, N} y C = {a, e, i, o, u}, calcular: i. A B ii. B A iii. A C iv. C A v. B C vi. C B vii. A B C viii. A C B ix. B A C x. B C A xi. C A B xii. C B A
7. Halle el cardinal de los conjuntos obtenidos en el numeral 5. Para un conjunto A, cu al ser a el cardinal de (A) en t erminos de |A|?. 8. Halle el cardinal de los conjuntos obtenidos en el numeral 6. Para los conjuntos A, B , C , A1 , A2 , . . . , An . (a) Cu al ser a el cardinal de A B en t erminos de |A| y |B |?. (b) Cu al ser a el cardinal de A B C en t erminos de |A|, |B | y |C |?.
28
(c) Cu al ser a el cardinal de A1 A2 An en t erminos de |A1 |, |A2 |, . . . , |An |?. 9. Dados dos conjuntos A y B , se tiene que |A B | = |A| + |B | |A B |, esto por que al sumar |A| y |B | se incluye dos veces |A B |, y por lo tanto hay que restarlo. Para el caso de tres conjuntos A, B y C , Cu al es el cardinal del conjunto A B C ?. Ayuda : Utilice diagramas de Venn para tres conjuntos. 10. Sea A
B
(a) Haga un diagrama de Venn que represente la operaci on A (b) Para los conjuntos A, B y C del numeral 4 calcule: i. A ii. A B C iii. B iv. B A C B ?. A?. v. C vi. C
A B
B es igual a B
(a) Haga un diagrama de Venn que represente la operaci on A (b) Para los conjuntos A, B y C del numeral 4 calcule: i. A ii. A B C iii. B iv. B A C B ?. A?. v. C vi. C
A B
Cap tulo
Relaciones y funciones
4.1. Relaciones
Una relaci on R de A en B es un subconjunto del producto cartesiano A B , es decir, R se dice relaci on si R A B . Al conjunto A se le denomina conjunto de salida y al conjunto B se le denomina conjunto de llegada. Ejemplo. Sean A = {0, 1, 2} y B = {p, o, n, m}, una de la posibles relaciones que se pueden denir es R = (0, p), (0, m), (2, m), (2, o) , el cual es un subconjunto de parejas ordenadas pertenecientes al producto cartesiano entre A y B . El conjunto vac o puede considerarse una relaci on al ser subconjunto de cualquier conjunto. De forma similar, el producto cartesiano A B tambi en es una relaci on pues todo conjunto es subconjunto de si mismo (A B A B ). Dada una relaci on R A B , el conjunto DomR = a : (a A) (b B ) (a, b) R se denomina el dominio de la relaci on R, a los elementos de DomR se les denomina preim agenes de la relaci on R. Ejemplo. Sean A = {0, 1, 2} y B = {p, o, n, m}, dos conjuntos y sea R = (0, p), (0, m), (2, m), (2, o) , una relaci on denida de A en B , el conjunto DomR = {0, 2} es el dominio de la relaci on y los elementos 0 y 2 son las preim agenes de la relaci on R. Dada una relaci on R A B , el conjunto RanR = b : (b B ) (a A) (a, b) R se denomina el rango o codominio de la relaci on R, a los elementos de RanR se les denomina im agenes de la relaci on R. Ejemplo. Sean A = {0, 1, 2} y B = {p, o, n, m} dos conjuntos y sea R = (0, p), (0, m), (2, m), (2, o) una relaci on denida de A en B , el conjunto RanR = {p, o, m} es el rango de la relaci on y los elementos p, o y m son las im agenes de la relaci on R. 29
30
Dentro de una relaci on es posible vincular un elemento de un conjunto con m as de un elemento de otro conjunto, no tener elementos en la relaci on o incluir s olo algunos elementos que pertenecen al producto cartesiano de los dos conjuntos. En el ejemplo anterior, no se tienen elementos que incluyan el elemento 1 del conjunto de salida A ni el elemento n del conjunto de llegada B . Si se tiene una relaci on R de un conjunto cartesiano R A B , esta puede notarse como R : A ; B esto evita la notaci on de subconjunto pero aclara que se esta realizando una asignaci on de elementos de A en elementos de B . Una de las caracter sticas importantes del concepto de relaci on es su noci on de agrupar elementos de diferentes tipos. Esta forma de conectar elementos de diferentes conjuntos tiene mucha aplicaci on en programaci on, pues dicha relaci on puede ser vista como una asignaci on. La representaci on gr aca de una relaci on se puede hacer en t erminos de diagramas Sagitales. En la gura 4.1 se muestra una representaci on de la relaci on R = (0, p), (0, m), (2, m), (2, o) denida en el ejemplo anterior. Como se puede apreciar cada echa representa un vinculo entre cada uno de los elementos del conjunto A y los del conjunto B . A R B
0 1 2
p o n m
Figura 4.1. Representaci on de la relaci on R = (0, p), (0, m), (2, m), (2, o) mediante diagramas Sagitales.
Hay relaciones que se pueden establecer entre elementos del mismo conjunto, es decir, una relaci on que cumpla que R A A Ejemplo. Si se tiene el conjunto A = {p, o, n, m}, se puede construir la relaci on R = (p, o), (o, p), (n, m), (m, n) . En la gura 4.2 se muestra una representaci on de esta relaci on.
4.1. RELACIONES
31 A
p o n m
p o n m
Figura 4.2. Representaci on de la relaci on R = (p, o), (o, p), (n, m), (m, n) mediante diagramas Sagitales.
(a A) (a, a) R . Simetrica: se dice que una relaci on es sim etrica, si y s olo si, Si (a, b) R entonces (b, a) R. Antisimetrica: se dice que una relaci on es antisim etrica, si y s olo si, Si (a, b) R (b, a) R entonces a = b.
Transitiva: una relaci on se dice transitiva, si y s olo si, Si (a, b) R (b, c) R entonces (a, c) R.
Esta noci on puede relacionarse con el silogismo hipot etico en el cual si ( ) ( ), entonces se puede concluir que . Ejemplo. Si se toma el conjunto A = {0, 1, 2} una posible relaci on sobre este podr a ser R = (0, 0), (0, 1), (1, 1), (1, 2), (2, 2) , de la cual se puede armar que: La relaci on R es reexiva pues est an todas las parejas de los elementos vinculados consigo mismos (0, 0), (1, 1) y (2, 2). La relaci on R no es sim etrica pues est a la pareja (0, 1) pero no est a la pareja (1, 0). En este caso es suciente con un caso que no se de para decir que una relaci on no cumple la propiedad. La relaci on R es antisim etrica pues cumple con la denici on, ya que las tres parejas (0, 0), (1, 1) y (2, 2) son de la forma (a, a) que cumplen con la denici on, y para las otras parejas (0, 1) y (1, 2) no est an presentes las parejas (1, 0) o (2, 1), por lo que tambi en se cumplen con la denici on de antisimetr a.
32
La relaci on R no es transitiva pues est an las parejas (0, 1) y (1, 2), pero no est a la pareja (0, 2). El hecho de que una relaci on no sea sim etrica no quiere decir que la relaci on sea antisim etrica y viceversa. Ejemplo. Si se tiene el conjunto A = {0, 1, 2}, y sobre este se dene la relaci on R = (0, 0), (0, 1), (1, 0), (1, 2), (2, 2) , se tiene que la relaci on no es sim etrica pues la pareja (1, 2) est a, pero la pareja (2, 1) no est a, ni es antisim etrica pues las parejas (0, 1) y (1, 0) est an, y es sabido que 1 = 0. Ejemplo. Si se tiene el conjunto A = {0, 1, 2}, y sobre este se dene la relaci on R = (0, 0), (1, 1), (2, 2) , se tiene que la relaci on es tanto sim etrica como antisim etrica. Por qu e?.
33
Es transitiva: como las parejas (0, 1) y (1, 0) est an, deber a estar la pareja (0, 0), y de forma an aloga, como est an las parejas (1, 0) y (0, 1), deber a estar la pareja (1, 1); para el resto de los casos, como las parejas que quedan son aquellas que tienen igual la primera y la segunda componente, estas se relacionan consigo mismas, por lo que la transitividad se obtiene de forma directa. Las relaciones de equivalencia tienen una particular caracter stica, es que los elementos que est an relacionados se pueden interpretar como que representan el mismo objeto. As , una relaci on de equivalencia dene una partici on del conjunto en grupos de conjuntos con propiedades similares; tales como que no son vac os, que no tienen elementos en com un, y que la uni on de todos los grupos es el conjunto inicial. A estos grupos se les conoce como clases de equivalencia.
Ejemplo. Para el conjunto A = {0, 1, 2} y la relaci on de equivalencia R = (0, 0), (0, 1), (1, 0), (1, 1), (2, aqu se observa que se pueden formar los grupos {0, 1} y {2}, los cuales son una partici on del conjunto A y que denen dos clases de equivalencia. Obs ervese que los valores 0 y 1, resultan ser equivalentes, es decir, que representan el mismo objeto.
34
f A B
0 1 2 3 4
p o n m
Figura 4.3. Representaci on de la funci on f = (0, o), (1, o), (4, n) mediante diagramas Sagitales.
Ejemplo. Si a la funci on f = (0, p), (1, p), (2, n) se adicionara la pareja (1, m), esta nueva relaci on f = (0, p), (1, p), (2, n), (1, m) dejar a de ser funci on, pues a 1 le corresponder an dos valores diferentes p y m. En la gura 4.4 se representa la relaci on f .
f A B
0 1 2
p o n m
Figura 4.4. Representaci on de la relaci on f = (0, p), (1, p), (2, n), (1, m) mediante diagramas Sagitales.
A un elemento del conjunto B le corresponde una sola preimagen del conjunto A. Ejemplo. En la gura 4.5 se muestra una representaci on de la funci on inyectiva f = (0, m), (2, p) .
35 B
f A
0 1 2
Figura 4.5. Representaci on de la funci on inyectiva f = Sagitales.
p o n m
(0, m), (2, p) mediante diagramas
Sobreyectiva: una funci on f : A B se dice sobreyectiva o suprayectiva si y s olo si, (b B )(a A) tal que (a, b) f .
Cada elemento del conjunto B tiene una preimagen del conjunto A. Ejemplo. En la gura 4.6 se muestra una representaci on de la funci on sobreyectiva f = (0, p), (1, n), (2, m), (4, p) . f A B
0 1 2 3 4
p o n m
(0, p), (1, n), (2, m), (4, p) me-
Total: una funci on f : A B se dice total si y s olo si, (a A)(b B ) tal que (a, b) f .
Cada elemento del conjunto A tiene una imagen del conjunto B . Ejemplo. En la gura 4.7 se muestra una representaci on de la funci on total f = (0, n), (1, o), (2, p), (3, m), (4, o) . Biyectiva: una funci on f : A B se dice biyectiva si y s olo si, f es inyectiva, sobreyectiva y total.
36
f A B
0 1 2 3 4
p o n m
Figura 4.7. Representaci on de la funci on total f = (0, m), (1, o), (2, p), (3, m), (4, p) mediante diagramas Sagitales.
Ejemplo. En la gura 4.8 se muestra una representaci on de la funci on biyectiva f = (0, n), (1, o), (2, m), (3, p) . f A B
0 1 2 3
p o n m
Figura 4.8. Representaci on de la funci on biyectiva f = (0, n), (1, o), (2, m), (3, p) mediante diagramas Sagitales.
Ejemplo. La funci on identidad idA relaciona a cada elemento de un conjunto A con si mismo, de la siguiente manera idA : A A x idA (x) = x En la gura 4.9 se muestra una representaci on de la funci on identidad idA = (p, p), (o, o), (n, n), (m, m) para el conjunto A = {p, o, n, m}. Nota. N otese que cuando dos conjuntos tienen el mismo cardinal (son equipotentes), es por existe una funci on biyectiva entre los dos conjuntos, esta es la forma en que se verica la igualdad de la cardinalidad de dos conjuntos.
37
idA
p o n m
p o n m
Figura 4.9. Representaci on de la funci on identidad idA = (p, p), (o, o), (n, n), (m, m) mediante diagramas Sagitales.
as , se tiene que .14| = |3.14| = 3.14, | 1| = 1, |1| = 1, |0| = 0, | | = , |3 3.14, | | = , 2 = 2, 2 = 2. Ejemplo. Potencia La funci on potencia de b elevado al exponente x se denota como bx y se dene como: bx : R0,+ Z R0,+ 1, b b b, nveces 1 (b, x) , b| x | 0, ,
=4 , 00 = , 01 = . 9
Ejemplo. Ra z cuadrada La funci on ra z cuadrada de x se denota como x y se dene como: x : R0,+ R0,+ x b, donde b2 = x.
38
4 as , se tiene que 0 = 0, 1 = 1, 4 = 2, 9 = 3, 25 = 5, 0.25 = 0.5, = 2 , 9 3 2 = 1.4142135623730950488016887242096980785696718753769480731766797379907 . Se puede demostrar que x = x1/2 . Ejemplo. Logaritmo La funci on logaritmo en base b de x se denota como logb x y se dene como: logb x : R+ R+ R (b, x) y, donde by = x.
as , se tiene que log2 4 = 2, log2 8 = 3, log2 1 = 0 (en general logb 1 = 0), loge e = 1 (en general logb b = 1), log3 1 = 2, log0.5 0.125 = 3, log0.25 2 = 1 . 9 2 Ejemplo. Piso La funci on piso de x se denota como x y se dene como: x :RZ x n,
es decir, x es el mayor entero que es menor o igual a x; de esta forma se tiene que 3.141516 = 4, 3 = 3, 1.5 = 2, 0.1 = 1, 0 = 0, 0.1 = 0, 1.5 = 1, 3 = 3, 3.141516 = 3. Ejemplo. Techo La funci on techo de x se denota como x y se dene como: x :RZ x n,
es decir, x es el menor entero que es mayor o igual a x; de esta forma se tiene que 3.141516 = 3, 3 = 3, 1.5 = 1, 0.1 = 0, 0 = 0, 0.1 = 1, 1.5 = 2, 3 = 3, 3.141516 = 4. Ejemplo. Parte entera La funci on parte entera de x se denota como [x] y se dene como: [ x] : R Z x , x 0, x ,
si x 1; si 1 < x < 1; si x 1.
as , se tiene que [3.141516] = 3, [3] = 3, [1.5] = 1, [0.1] = 0, [0] = 0, [0.1] = 0, [1.5] = 1, [3] = 3, [3.141516] = 3. Ejemplo. Parte fraccionaria La funci on parte fraccionaria de x se denota como frac(x) y se dene como:
39
frac(x) : R Z x x [x]. as , se tiene que frac(3.141516) = 0.141516, frac(3) = 0.0, frac(1.5) = 0.5, frac(0.1) = 0.1, frac(0) = 0.0, frac(0.1) = 0.1, frac(1.5) = 0.5, frac(3) = 0.0, frac(3.141516) = 0.141516. Ejemplo. Redondeo La funci on redondeo de x se denota como round(x), retorna el entero m as pr oximo al n umero x. Para los reales no negativos retorna el techo si la parte fraccionaria es mayor o igual a 0.5, retorna el piso si la parte fraccionaria es menor a 0.5. Para los reales negativos retorna el piso si la parte fraccionaria es mayor o igual a 0.5, retorna el techo si la parte fraccionaria es menor a 0.5. Formalmente esto se dene como: round(x) : R Z x , x x , round(x),
as , se tiene que round(3.141516) = 3, round(3) = 3, round(1.5) = 2, round(0.1) = 0, round(0) = 0, round(0.1) = 0, round(1.5) = 2, round(3) = 3, round(3.141516) = 3, round(1.8) = 2, round(1.8) = 2.
As denida la composici on, se tiene que Domf g = Domg y Ranf g Ranf . Una representaci on que permite entender mejor como opera esta nueva funci on, es utilizando un diagrama conmutativo, como se muestra a continuaci on:
g
A
f g
B
f
C Ejemplo. Sea A = {1, 2, 3, 4, 5, 6}, B = {p, o, n, m, :} y C = {a, b, c, d} tres conjuntos. Si g = (1, n), (2, o), (3, :), (4, :), (6, p) y f = (p, c), (o, d), (n, a), (m, b), (:, c) entonces f g = (1, a), (2, d), (3, c), (4, c), (6, c) ; aqu tambi en se observa que Domf g =
40
Domg = {1, 2, 3, 4, 6} y Ranf g = {a, c, d} Ranf = {a, b, c, d}. En la gura 4.10 se muestra una representaci on de la composici on de las funciones f y g . g A 1 2 3 4 5 6 B p o n m : f g
Figura 4.10. Representaci on mediante diagramas Sagitales de la composici on de las funciones f y g , f g = (1, a), (2, d), (3, c), (4, c), (6, c) .
f C
a b c d
Ejemplo. Sean g y f las siguientes funciones: g:RN x x entonces la funci on compuesta de las funciones f y g ser a f g :RN x f g ( x) = f x = x x f :NN nnn
4.5. EJERCICIOS
41
4.5. Ejercicios
1. Sean A = {0, 1, 2} y B = {G, I, L, N} dos conjuntos. Cu antas relaciones de A en B existen?. 2. Sean A = {0, 1} y B = {G, L} dos conjuntos. Encuentre todas las relaciones de A en B . 3. Sea A = {G, I, L, N} un conjunto. Cu antas relaciones de A en A existen?. 4. Sea A = {G, I, L, N} un conjunto. Represente mediante un diagrama sagital las relaciones que se presentan a continuaci on. i. R1 = (G, G), (G, I), (I, G), (I, I), (L, N), (N, G), (N, N) ii. R2 = (G, G), (G, I), (I, G) iii. R3 = (G, G), (G, I), (G, N), (I, G), (I, I), (L, L), (N, G), (N, N) iv. R4 = (I, G), (L, G), (L, I), (N, G), (N, I), (N, L) v. R5 = (G, G), (G, I), (G, L), (G, N), (I, I), (I, L), (I, N), (L, L), (L, N), (N, N) vi. R6 = {(L, N) 5. De las relaciones del numeral 4. Cu al es el dominio?, Cu al es el rango?. 6. De las relaciones del numeral 4. Cu ales son reexivas?, Cu ales son sim etricas?, Cu ales son antisim etricas?, Cu ales son transitivas?. 7. De las relaciones del numeral 4. Cu ales son una relaci on de orden?, Cu ales son una relaci on de equivalencia?. 8. De las siguientes funciones denidas de Z a Z i. f1 (n) = 1 ii. f2 (n) = n iii. f3 (n) = n2 Cu al es el dominio?, Cu al es el rango?. 9. De las funciones denidas en el numeral 8. Cu ales son inyectivas?, cu ales son sobreyectivas?, cu ales son totales?, cu ales son biyecciones?. 10. De las siguientes relaciones denidas de Z en R i. f1 (x) = x ii. f2 (x) = x2 iii. f3 (x) = x iv. f4 (x) = |x| v. f5 (x) = x vi. f6 (x) = 1/x iv. f4 (n) = n3 v. f5 (n) = 2n vi. f6 (n) = log2 n
Cu ales son funciones?. 11. De las relaciones denidas en el numeral 10. Cu al es el dominio?, Cu al es el rango?. 12. De las relaciones denidas en el numeral 10 que son funciones. Cu ales son inyectivas?, cu ales son sobreyectivas?, cu ales son totales?, cu ales son biyecciones?.
Cap tulo
44CAP ITULO 5.
1er_mes primer nombre while p@dre d a Una variable es un espacio en memoria donde se almacena un dato, un espacio donde se guarda la informaci on necesaria para realizar las acciones que ejecutan los programas. Para declarar una variable se necesitan principalmente dos componentes, el tipo de variable y el nombre. Los tipos de variables se estudian en la siguiente secci on, con respecto al nombre, este simplemente debe ser un identicador valido que no sea una palabra reservada. Una nota importante es que el lenguaje C++ es sensible a may usculas y min usculas, esto quiere decir que por ejemplo los identicadores dia Dia DIA
sirven para declarar variables diferentes, pues al ser la misma palabra, diere en que algunas letras son may usculas en unos identicadores y en los otros no. Una buena t ecnica de programaci on es asignarle el nombre a una variable de tal manera que indique por un lado el papel que desempe na dicha variable en el algoritmo y por otro los posibles valores que almacena. Nombres de variables recomendados dependiendo del tipo de problema pueden ser: velocidad espacio masa valor_maximo area_circulo aceleracion exponente nombre_estudiante termino1 last_name
5.2.1. Enteros
Los enteros en C++ se codican con la palabra int y su declaraci on es la siguiente Si x es una variable algebraica que varia en el conjunto Z, para denir x en el lenguaje C++ se utiliza la expresi on int x;
45
lo que sirve para declarar que la variable x pertenece a los enteros que son representables en el lenguaje C++. El subconjunto de los n umeros enteros que pueden ser representados en el lenguaje C++, es el conjunto de enteros con signo que se representan con 32 bits (4 bytes) y que usan un tipo de codicaci on interna llamada complemento a 2, los valores de este conjunto var an en el rango 2147483648 x 2147483647 Los literales enteros, es decir, la sintaxis de los valores que pueden ser asignados a las variables de tipo int que soporta C++ son por ejemplo: -32768 32768 +32768 -0 0 +0 -1 1 +1 -127 127 +127
Cuando se declara una variable de tipo entero, no se sabe que valor tiene, por eso es necesario inicializar la variable. Los siguientes son ejemplos de inicializaciones de variables de tipo int int int int int int i j n p k = = = = = 0; 1; 5; -10; -1;
5.2.2. Reales
Los reales en C++ se codican con la palabra double y su declaraci on es la siguiente Si x es una variable algebraica que varia en el conjunto R, para denir x en el lenguaje C++ se utiliza la expresi on double x; lo que sirve para declarar que la variable x pertenece a los reales que son representables en el lenguaje C++. El subconjunto de los n umeros reales que pueden ser representados en el lenguaje C++, es un subconjunto propio de los racionales, que se representan con 64 bits (8 bytes) y que usan un tipo de codicaci on denida por el IEEE standard for Binary Floating-Point Arithmetic 754 de 1985, los valores distintos de 0 de este conjunto var an en el rango 1.7976931348623157 10+308 x 2.2250738585072014 10308 y 2.2250738585072014 10308 x 1.7976931348623157 10+308 que dan una precisi on cient ca de 15 d gitos. Los literales reales, es decir, la sintaxis de los valores que pueden ser asignados a las variables de tipo double que soporta C++ son por ejemplo:
46CAP ITULO 5.
Cuando se declara una variable de tipo real, no se sabe que valor tiene, por eso es necesario inicializar la variable. Los siguientes son ejemplos de inicializaciones de variables de tipo double double double double double double double e = 2.7182818284; a = +1.0; X = -1.0; Luz = 2.998e+8; const0 = 1.3806488E-23; coordenada_1 = -2.5;
5.2.3. Booleanos
Los booleanos en C++ se codican con la palabra bool y su declaraci on es la siguiente Si x es una variable algebraica que varia en el conjunto B, para denir x en el lenguaje C++ se utiliza la expresi on bool x; lo que sirve para declarar que la variable x pertenece al conjunto de los booleanos B = {V, F } . Como s olo hay dos valores de verdad V y F , en C++ s olo hay dos literales para representar los valores l ogicos, estos son: true false
donde la cadena true representa el valor de verdad V y la cadena false representa el valor de verdad F . Cuando se declara una variable de tipo real, no se sabe que valor tiene, por eso es necesario inicializar la variable. Los siguientes son ejemplos de inicializaciones de variables de tipo bool bool bool bool bool b = true; flag = true; exp = false; isPrime = false;
5.2.4. Caracteres
Los caracteres representan los s mbolos denidos por el ASCII (American Standard Code for Information Interchange ). Los caracteres se representan con 8 bits (1 byte), lo que ofrece 256 s mbolos distintos. El conjunto ASCII cumple con la siguiente caracter stica
47
ASCII !, ", #, $, %, &, , (, ), *, +, ,, -, ., /, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, :, ;, <, =, >, ?, @, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, [, \, ], ^, _, , a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, {, |, }, ~ Los ASCII en C++ se codican con la palabra char y su declaraci on es la siguiente Si x es una variable algebraica que varia en el conjunto ASCII , para denir x en el lenguaje C++ se utiliza la expresi on char x; lo que sirve para declarar que la variable x pertenece al conjunto de los ASCII . Existen algunos caracteres especiales que no tiene su propio s mbolo en el teclado o que no se imprime el s mbolo en la pantalla o que tienen un uso particular en C++ (son reservados) y que son utilizados com unmente; estos caracteres se representan de la siguiente manera: \n : Nueva l nea \t : Tabulador horizontal. \\ : Diagonal invertida. \ : Imprime ap ostrofo. \" : Imprime Comillas. \b : Retroceso (retrocede un espacio el cursor). \v : Tabulador vertical (coloca el cursor justo debajo del u ltimo car acter de la l nea actual). \r : Retorno de carro (coloca el cursor en el primer car acter de la l nea actual y sobreescribe el texto de la l nea). \? : Imprime el s mbolo de interrogaci on. Cuando se declara una variable de tipo car acter, no se sabe que valor tiene, por eso es necesario inicializar la variable. Los siguientes son ejemplos de inicializaciones de variables de tipo char, para indicar que se est a deniendo un literal de car acter, se encierra el s mbolo entre ap ostrofos , as como se muestra a continuaci on: char char char char char char char char c = ; CH = \n; letra = a; caracter = A; value = \"; _last = \; C_0 = &; cero = 0;
48CAP ITULO 5.
49
*= : Asignaci on con multiplicaci on. La parte de la izquierda debe ser una variable. Multiplica el valor almacenado en la variable denida en la parte de la izquierda con la evaluaci on de parte de la derecha y guarda el producto en la variable de parte de la izquierda. Por ejemplo, la expresi on x *= 2, es equivalente a la expresi on x = x * 2. /= : Asignaci on con divisi on. La parte de la izquierda debe ser una variable. Divide el valor almacenado en la variable denida en la parte de la izquierda entre el valor de la evaluaci on de la parte de la derecha y guarda el resultado en la variable de parte de la izquierda. Por ejemplo, la expresi on x /= 2, es equivalente a la expresi on x = x / 2. El valor de la evaluaci on de la parte de la derecha debe ser distinto de 0. %= : Asignaci on con residuo. La parte de la izquierda debe ser una variable. Calcula el residuo de dividir el valor almacenado en la variable denida en la parte de la izquierda entre el valor de la evaluaci on de la parte de la derecha y guarda el resultado en la variable de parte de la izquierda. Por ejemplo, la expresi on x %= 2, es equivalente a la expresi on x = x % 2. El valor de la evaluaci on de la parte de la derecha debe ser distinto de 0. Dos de los operadores m as utilizados para asignar valores a variables en programaci on son los siguientes operadores posjos: ++ : Incremento en una unidad y asignaci on, se utiliza como un operador unario y act ua s olo sobre variables, por ejemplo, si la variable i almacena el valor 0, cuando se eval ua la expresi on i++ el valor que almacenar a la variable ahora ser a igual a 1. Es equivalente a la expresi on i = i + 1 o a la expresi on i += 1. -- : Decremento en una unidad y asignaci on, se utiliza como un operador unario y act ua s olo sobre variables, por ejemplo, si la variable i almacena el valor 2, cuando se eval ua la expresi on i-- el valor que almacenar a la variable ahora ser a igual a 1. Es equivalente a la expresi on i = i - 1 o a la expresi on i -= 1.
50CAP ITULO 5.
!= : Devuelve V si dos valores son distintos. != = > : Mayor que, devuelve V si el primer operador es estrictamente mayor que el segundo. >> < : Menor que, devuelve V si el primer operador es estrictamente menor que el segundo. << >= : Mayor o igual, devuelve V si el primer operador es mayor o igual que el segundo. >= <= : Menor igual, devuelve V si el primer operador es menor o igual que el segundo. <= Ejemplo. Para escribir la expresi on x (0, 1] en el lenguaje C++ se utiliza la sentencia (0 < x && x <= 1)
<
+=
%=
Ejemplo. Hallar el valor de la siguiente expresi on teniendo en cuenta la prioridad de operadores y que los operandos son n umeros reales
51
12.0 * 3.0 + 4.0 - 8.0 / 2.0 % 3.0 i) (12.0 3.0) + 4.0 8.0 / 2.0 % 3.0 ( prioridad 4) ii) (12.0 3.0) + 4.0 (8.0 / 2.0) % 3.0 (/ prioridad 4) iii) (12.0 3.0) + 4.0 ((8.0 / 2.0) % 3.0) ( % prioridad 4) iv) ((12.0 3.0) + 4.0) ((8.0 / 2.0) % 3.0) (+ prioridad 5) v) (((12.0 3.0) + 4.0) ((8.0 / 2.0) % 3.0)) ( prioridad 5) 12.0 3.0 + 4.0 8.0 / 2.0 % 3.0 = 36.0 + 4.0 8.0 / 2.0 % 3.0 = 36.0 + 4.0 4.0 % 3.0 = 36.0 + 4.0 1.0 = 40.0 1.0 = 39.0 Ejemplo. Hallar el valor de la siguiente expresi on teniendo en cuenta la prioridad de operadores y que los operandos son n umeros enteros (-2 + 5 % 3 * 4) / 4 + 2 i) (2 + (5 % 3) 4) / 4 + 2 ( % prioridad 4) ii) (2 + ((5 % 3) 4)) / 4 + 2 ( prioridad 4) iii) (2 + ((5 % 3) 4)) / 4 + 2 (+ prioridad 5) iv) ((2 + ((5 % 3) 4)) / 4) + 2 (/ prioridad 4) v) (((2 + ((5 % 3) 4)) / 4) + 2) (+ prioridad 5) (2 + 5 % 3 4) / 4 + 2 = (2 + 2 4) / 4 + 2 = (2 + 8) / 4 + 2 =6 / 4+2 =1+2 =3
52CAP ITULO 5.
el valor, esto es, que a una variable de tipo int se le asigne un valor entero, que a una variable de tipo double se le asigne un valor real, que a una variable de tipo bool se le asigne un valor booleano, que a una variable de tipo char se le asigne un car acter, etc. Una asignaci on comprende dos partes: el valor al que se le asignar el valor y la expresi on. Se espera que el resultado de la evaluaci on de la expresi on sea del mismo tipo de la expresi on. En este sentido se podr a extender a expresiones de tipo l ogico, aritm etico o car acter. El proceso de asignar valores a variables es el objetivo central a la hora de construir un programa, ya que un programa no es m as que una funci on que transforma la memoria desde un estado inicial hasta un estado nal donde se encuentra el resultado que se quer a calcular. Visto as , en programaci on, la asignaci on es una operaci on temporal, que primero lee el valor de las variables existentes en la memoria, a partir de estos valores se eval ua la expresi on a la derecha de la asignaci on y luego se realiza la asignaci on a la variable de la izquierda correspondiente al resultado de la evaluaci on de la expresi on, es decir, se actualiza el valor de la variable en la memoria. Ejemplo. Sup onga que un programa contiene las variables x, y y z en el instante de tiempo t, que sus valores en este instante de tiempo son: x = 3, y=4 y z = 2
si a partir de estos valores se realiza la asignaci on x = y + z - 2; entonces se tendr a que en el instante de tiempo t se eval ua la expresi on y + z - 2 y el resultado de esta evaluaci on se asignar a a la variable x pero ya en el instante de tiempo t + 1. Con lo que los valores de las variables (memoria) en este nuevo instante de tiempo seria: x = 0, y=4 y z = 2 Ejemplo. Sup onga que se desea realizar la asignaci on x = x + 3 - 2 * y cuando x = 3 y y = 5. Para entender como se realiza la asignaci on es u til subindizar las variables teniendo en cuenta el instante de tiempo en el cual se esta leyendo o modicando la memoria. Con base en lo anterior, la expresi on se reescribe de la siguiente manera xt + 1 = xt + 3 2 yt As , si en el instante de tiempo t se tiene que x = 3 y y = 5, entonces en el instante de tiempo t + 1, se tendr a que x = 4 y y = 5. Cuando se desea estudiar el comportamiento de una secuencia de asignaciones es u til utilizar una tabla de la traza de ejecuciones.
53
En esta tabla se tiene una columna donde se ubica el instante de tiempo t que inicialmente debe ser igual a 0, en las otras columnas se ubican todas las variables que intervienen en los c alculos. Para las variables que tienen un valor inicial, este valor se ubica en la misma la del instante de tiempo t = 0 y para el resto de variables se utiliza el s mbolo para indicar que a un est a indenido. Tras iniciar la ejecuci on de las instrucciones, se va actualizando el valor de las variables a las que se les haya hecho alguna asignaci on, teniendo en cuenta el instante de tiempo en el cual se realiza la asignaci on. Esto se realiza hasta que se ejecute toda la secuencia de instrucciones. Ejemplo. La siguiente tabla es la traza obtenida tras ejecutar la instrucci on x = x + 3 - 2 * y cuando x = 3 y y = 5. t x y 0 3 5 1 4 5 Ejemplo. Sup onga que se desea ejecutar la siguiente secuencia de instrucciones i j i j = = = = k 2 i j + * * * 1; k; k * j; k - i;
Una secuencia de instrucciones se puede entender matem aticamente como la composici on de una serie de funciones, donde cada vez que se haga uso de una variable, esta se reemplaza por la asignaci on inmediatamente anterior, s existe una asignaci on de esta variable. Ejemplo. Para la siguiente secuencia de instrucciones i j i j = = = = k 2 i j + * * * 1; k; k * j; k - i;
54CAP ITULO 5.
se puede observar que utilizando la funciones +, , como funciones binarias usando una notaci on preja, se obtienen las siguientes expresiones matem aticas: i = +(k, 1) j = (2, k ) i = ((+(k, 1), k ), (2, k )) j = ((2, k ), k ), (+(k, 1), k ), (2, k ) Observes e que la u ltima expresi on est a escrita u nicamente en t erminos de k y si se eval ua en el valor k = 1, entonces se obtiene el valor para j del ejemplo anterior. j = ((2, k ), k ), (+(k, 1), k ), (2, k ) j = ((2, 1), 1), (+(1, 1), 1), (2, 1) j = (2, 1), (+(1, 1), 1), (2, 1) j = 2, (+(1, 1), 1), (2, 1) j = 2, (2, 1), (2, 1) j = 2, 2, (2, 1) j = 2, 2, 2 j = 2, 4 j = 2 El valor j = 2 es el mismo que se obtuvo al nal de la traza del ejemplo anterior.
5.5. Ejercicios
Se tienen dos retazos a y b. Rotar rota 90 en contra de las manecillas del reloj. Pegar pega verticalmente si se tienen retazos cuyo lado a pegar coincida.
Cap tulo
56
Entre par entesis se coloca el tipo y la variable de las variables del dominio. En este caso solamente se tiene la variable x quedando double x y se coloca una llave abierta {. double f(double x){ En las siguientes l neas se escribe la denici on de la funci on entre corchetes terminando con punto y coma ; cada linea de la funci on. Dicha denici on de funci on corresponde al algoritmo o computo, para generar la imagen calculada de la funci on se utiliza la palabra clave return, de la siguiente manera double f(double x){ return x*x; Despu es de escribir la funci on se cierra la llave } seguida de un punto y coma ;. double f(double x){ return x*x; }; Otra posible denici on de la funci on podr a escribirse almacenando el valor del producto x*x en una variable de tipo double y retorn andolo as : double f(double x){ double y; y = x * x; return y; }; Esto es similar al caso cuando se utiliza la notaci on f (x) = y donde x es una variable independiente y y es la variable dependiente. Ejemplo. Area de un c rculo Para el desarrollo de esta funci on lo primero es determinar el nombre. La funci on se llamar a area circulo cuyo dominio es el conjunto de los n umeros reales (para el radio) y cuyo rango pertenece al conjunto de los n umeros reales (el valor de retorno que corresponde al area del c rculo). Teniendo en cuenta que el algoritmo para el c alculo del a rea de un c rculo depende del valor de su radio, entonces, el area del c rculo est a dada por la expresi on Ac = r2 , donde las variables est an denidas as : r := Radio del c rculo Ac := Area del c rculo de radio r
57 entonces, el planteamiento matem atico de la funci on solicitada ser a el siguiente area circulo : R R (r) 3.14159265 r r N otese que para denir el valor se tom o como aproximaci on el valor 3.14159265. En vez de elevar el valor del radio al cuadrado se tom o la multiplicaci on de r r ya que la potencia no es una operaci on matem atica b asica. En la secci on de recursividad se denir a potencia como una funci on. Esta funci on se traduce al lenguaje C++ paso a paso de la siguiente forma: Primero se escribe el tipo de retorno en este caso el conjunto que corresponde al tipo de dato del a rea del c rculo, como es real el tipo de dato es double. double Posteriormente se escribe el nombre de la funci on area_circulo. double area_circulo obs ervese que la palabra circulo en el nombre de la funci on se escribe sin tilde, ya que u nicamente se pueden utilizar car acteres del alfabeto ingl es Entre par entesis se coloca el tipo y la variable de las variables del dominio. En este caso solamente se tiene la variable r de tipo double r y se coloca una llave abierta {. double area_circulo(double r){ En las siguientes l neas se escribe el c alculo del a rea del c rculo y se retorna el valor calculado. double area_circulo(double r){ return 3.14159265*r*r; Despu es de escribir la funci on se cierra la llave } seguida de un punto y coma ;. double area_circulo(double r){ return 3.14159265*r*r; }; Otra posible denici on de la funci on podr a escribirse almacenando el valor del a rea del c rculo en una variable de tipo double y retorn andolo as : double area_circulo(double r){ double area; area = 3.14159265*r*r; return area; };
58
Esto es similar al caso cuando se utiliza la notaci on area circulo(r) = area para expresar la funci on, las variables independientes y la dependiente.
59
double area_circulo(double r){ return 3.1415962*r*r; }; int main(){ double radio; cout << "radio del circulo? = "; cin >> radio; cout << "El area del circulo es: "; cout << area_circulo(radio); cout << "\n"; system("pause"); //windows return EXIT_SUCCESS; }; Como se aprecia en el programa anterior, se utilizan las funciones cin y cout que pertenecen a la librer a de entrada y salida de ujos de datos iostream. Las dos primeras l neas de c odigo permiten al compilador incluir las deniciones de estas funciones en el programa principal. La funci on cout lo que hace es mostrar una cadena de caracteres (texto) en la consola. La instrucci on cout << "\n" lo que hace es imprimir un car acter de n de l nea en la consola. La funci on cin lo que hace es asignar el valor que sea digitado en la consola a la variable de la parte de la izquierda del operador <<. En la instrucci on cin >> radio; se asigna a la variable radio el valor digitado por el usuario. system("pause") lo que hace es ejecutar el comando pause de Windows que permite pedirle al usuario que presione una tecla para continuar la ejecuci on del programa o en este caso por estar antes del retorno o n de la funci on principal para salir de el devolviendo al sistema operativo un valor de EXIT_SUCCESS para indicar que ejecuci on del programa fue satisfactoria, es decir, que en este caso el programa se ejecut o correctamente. El programa anterior pide al usuario digitar el radio del c rculo y almacena el valor de la lectura en la variable radio. Posteriormente despliega un mensaje y se realiza el llamado a la funci on area_circulo. N otese que los nombres de variables (en este caso radio) en el programa principal no necesariamente deben coincidir con los de la declaraci on de la funci on (en este caso la funci on recibe un valor de tipo double llamado r), sin embargo se debe notar que su tipo de dato si debe ser el mismo.
60
area rectangulo : R R R. Para el calculo del a rea de un rect angulo es necesario conocer el largo y el ancho del rect angulo, a partir de los cuales el a rea del rect angulo est a dada por la expresi on Ar = l a, donde las variables est an denidas as : l := Largo del rect angulo a := Ancho del rect angulo Ar := Area del rect angulo de largo l y ancho a entonces, la funci on matem atica queda denida de la siguiente forma area rectangulo : R R R (l, a) l a Para traducir a lenguaje C++ se toman las mismas reglas de traducci on: Primero se escribe el tipo de retorno en este caso el conjunto que corresponde al tipo de dato del a rea del rect angulo, como es real el tipo de dato es double. double Posteriormente se escribe el nombre de la funci on area_rectangulo. double area_rectangulo Entre par entesis se colocan el conjunto de cada variable del dominio y el nombre de la variable separados por comas. En este se tienen las variable l y a correspondientes al largo y al ancho del rect angulo y se coloca un corchete abierto. double area_rectangulo(double l, double a){ En las siguientes l neas se escribe el c alculo del area del rect angulo, se retorna el valor calculado y se cierra la denici on de la funci on. double area_rectangulo(double l, double a){ return l*a; }; Otra posible escritura de la funci on puede ser double area_rectangulo(double l, double a){ double area; area = l*a; return area; };
61
Esto es similar al caso cuando se utiliza la notaci on area rectangulo(l, a) = area para expresar la funci on, las variables independientes y la dependiente. Para el llamado de la funci on se podr a tener el siguiente programa principal: #include<iostream> #include<stdlib.h> using namespace std; double area_rectangulo(double l, double a){ return l*a; }; int main(){ double largo; double ancho; cout << "largo? = "; cin >> largo; cout << "ancho? = "; cin >> ancho; cout << "El area del rectangulo es: "; cout << area_rectangulo(largo, ancho); cout << "\n"; system("pause"); return EXIT_SUCCESS; };
62
donde se ejecutar a <body_1> si <cond> se eval ua verdadero, en caso de que <cond> se eval ue falso de ejecutar a <body_2>, despu es de ejecutar <body_1> o <body_2> se continua con la ejecuci on del resto del programa, despu es de la estructura if. Ejemplo. Valor absoluto de un n umero La funci on que permite calcular el valor absoluto de un n umero real es una funci on que recibe como par ametro de entrada un n umero real y retorna la distancia de ese valor al origen. La funci on valor absoluto en notaci on matem atica se dene como valor absoluto : R R ( x) x, si x 0; x, en otro caso.
La codicaci on en C++ de esta funci on junto con su programa principal es #include<iostream> #include<stdlib.h> using namespace std; double valor_absoluto(double x){ double valor; if(x >= 0){ valor = x; }else{ valor = -x; }; return valor; }; int main(){ double x; cout << "x? = "; cin >> x; cout << "El valor absoluto es: "; cout << valor_absoluto(x); cout << "\n"; system("pause"); return EXIT_SUCCESS; }; Ejemplo. El m aximo entre dos n umeros Una funci on que permite determinar el m aximo de dos n umeros reales, se puede denir como
63
maximo dos numeros : R R R aqu se tienen dos casos, si el n umero a es mayor que b el valor m aximo es a; en otro caso se debe retornar b. En notaci on matem atica esto puede ser escrito de la siguiente forma maximo dos numeros : R R R (a, b) a, si a > b; b, en otro caso.
La regla de traducci on a funci on es similar a la anterior, s olo hay que tener en cuenta la instrucci on condicional, y que si no se cumple la condici on especicada en el if, se ejecutar a el ujo de instrucciones especicado bajo el alcance del else double maximo_dos_numeros(double a, double b){ if(a > b){ return a; }else{ return b; }; };
64
La codicaci on en C++ de esta funci on es int siguiente_par(int n){ if(n % 2 == 1){ return n + 1; }; if(n % 2 == 0){ return n + 2; }; };
65
programa que dado el n umero de productos y el precio del producto determine el valor a pagar por el cliente.
La siguiente funci on permitir a calcular el valor deseado descuento(precio, n) = valor Si se establecen las variables: precio := Valor de cada producto n := N umero de productos valor := Valor total a pagar despues de aplicar el descuento entonces
descuento : R Z R n precio, n precio 0.95, (precio, n) n precio 0.90, n precio 0.80, La codicaci on en C++ de esta funci on es
double descuento(double precio, int n){ if(n <= 5){ return n*precio; }else if(5 < n && n <= 10){ return n*precio*0.95; }else if(10 < n && n <= 20){ return n*precio*0.90; }else{ return n*precio*0.80; }; };
66
double descuento(double precio, int n){ double valor; if(n <= 5){ valor = n*precio; }else if(5 < n && n <= 10){ valor = n*precio*0.95; }else if(10 < n && n <= 20){ valor = n*precio*0.90; }else{ valor = n*precio*0.80; }; return valor; };
67
int main(){ double largo; double ancho; cout << "largo? = "; cin >> largo; if(largo < 0){ cout << "El largo no es valido"; cout << "\n"; system("pause"); return EXIT_FAILURE; }; cout << "ancho? = "; cin >> ancho; if(ancho < 0){ cout << "El ancho no es valido"; cout << "\n"; system("pause"); return EXIT_FAILURE; }; cout << "El area del rectangulo es: "; cout << area_rectangulo(largo, ancho); cout << "\n"; system("pause"); return EXIT_SUCCESS; };
68
6.5. Ejercicios
1. Hacer un programa que dado el a rea del corral de unas gallinas y el n umero de gallinas en el corral determine el a rea que le corresponde a cada gallina. 2. Construir una funci on que dados tres n umeros reales calcule el m aximo de los tres. 3. Dadas las longitudes de los dos brazos de una palanca y el peso puesto en el brazo m as largo de la palanca, calcular el peso que se puede poner en el brazo m as corto para que la palanca quede en equilibrio. 4. Dadas las longitudes de los dos brazos de una palanca y el peso puesto en el brazo m as corto de la palanca, calcular el peso que se puede poner en el brazo m as largo para que la palanca quede en equilibrio. 5. Dados los pesos que se pueden poner en cada uno de los lados de la palanca y la longitud total de la palanca determinar la longitud del brazo mas largo para que la palanca quede en equilibrio. 6. Dados los pesos que se pueden poner en cada uno de los lados de la palanca y la longitud total de la palanca determinar la longitud del brazo mas corto para que la palanca quede en equilibrio. 7. Para crear un litro del compuesto D, se requiere que su composici on por partes est e conformada de la siguiente manera, 5 partes deben ser del producto A, 8 partes deben ser del producto B y 7 partes deben ser del producto C . Si se requiere crear 10 litros del compuesto D. Cu antos litros del producto A se requieren?, Cu antos litros del producto B se requieren?, Cu antos litros del producto C se requieren?. 8. Si se tienen x litros de A, y litros de B y z litros de C . Cu antos litros del compuesto D se pueden obtener?. 9. En la convenci on republicana, se re unen 100 personas de las cuales x son mujeres e y son hombres. Si en la convenci on se dispone de z mesas y se dispone que la diferencia entre n umero de hombres y mujeres en cada mesa no debe superar 2. Cuantas sillas para mujeres se deben poner por mesa?, Cuantas sillas por hombre se deben poner?. Si los votos de las mujeres valen 1.5 veces los votos del hombre. Cu antas mujeres deber an estar en la convenci on para que el candidato sea elegido por votos de solo mujeres? Si los votos de los hombres valen 1.5 veces los votos de las mujeres. Cu antas mujeres deber an estar en la convenci on para que el candidato sea elegido por votos de solo mujeres? 10. Dado el centro y el radio de un c rculo, determinar si un punto pertenece o no al c rculo. 11. Dadas tres longitudes positivas, determinar si con esas longitudes se puede construir un tri angulo.
Cap tulo
Funciones recursivas
Denici on. En 1952 Stephen Kleene deni o formalmente en [Kleene 1952] que una funci on parcial recursiva de enteros no negativos es cualquier funci on f denida por un sistema no contradictorio de ecuaciones de las cuales las partes derechas e izquierdas est an compuestas a partir de: i. S mbolos funcionales (por ejemplo, f , g , h, etc.), ii. Variables para enteros no negativos (por ejemplo, x, y , z , etc.), iii. La constante 0, y iv. La funci on primitiva sucesor s(x) = x + 1. Ejemplo. El siguiente es un sistema que dene la funci on parcial recursiva f (x, y ) que permite computar el producto de x con y . f (x, 0) = 0 f x, s(y ) = g f (x, y ), x g (x, 0) = x g x, s(y ) = s g (x, y ) N otese que las ecuaciones podr an no determinar el valor de f para cada posible entrada, y que en ese sentido la denici on es lo que se deni o como funci on parcial. Si el sistema de ecuaciones determina el valor de f para cada entrada, entonces la denici on es lo que se deni o como funci on total. Cuando se usa el t ermino funci on recursiva, en este caso se esta hablando de forma impl cita de que la funci on recursiva es total. El conjunto de funciones que pueden ser denidas recursivamente en esta forma se sabe que son equivalente a el conjunto de funciones computables por una m aquina de Turing o por medio del lambda calculo. Ya que este libro es un texto introductorio a la programaci on, no se tratar an las funciones recursivas con todo su detalle formal ya que esto est a mucho m as all a del alcance de este libro; en cambio se intentar a caracterizar m as concretamente las funciones recursivas que usualmente son utilizadas a un nivel introductorio de la programaci on, mediante la 69
70
siguiente denici on debilitada de funci on recursiva. Hay que tener en mente que no se pretende que esta caracterizaci on sea exhaustiva con respecto al conjunto de todas las funciones recursivas. Denici on (Denici on d ebil de funci on recursiva). Una funci on f : A B se dice recursiva si y s olo si f est a denida por casos (mediante un predicado sobre los argumentos), en donde al menos uno de los casos se dene usando la misma funci on f y los argumentos, y al menos uno de los otros casos se dene usando solamente los argumentos sin involucrar la funci on f . Mediante el uso de funciones recursivas se puede solucionar cualquier problema que es potencialmente solucionable haciendo uso de un computador. A continuaci on se presentan algunos ejemplos de problemas cl asicos que se pueden solucionar mediante el uso de funciones recursivas, haciendo enfasis en la metodol ogica que de debe seguir para identicar la regla recursiva que se encuentra impl cita en cada uno de los problemas. Ejemplo. Potencia de un n umero En este ejemplo se denir a una funci on recursiva que permita hallar un n umero real elevado a un n umero natural. Para expresar una funci on que calcul e esta operaci on, en primera instancia se construye la expresi on potencia : R N R que dene la funci on que tiene como entrada un n umero real que representa la base y un n umero natural que indica el exponente, y como salida se obtendr a un n umero real que ser a la potencia. Por 0 facilidad, aqu se asumir a que 0 = 1. Ahora observes e que en general si se tiene una base b y un exponente n, entonces por denici on bn = b b b b b
nveces
A partir de esta observaci on se puede dar una denici on recursiva usando funciones. La declaraci on de esta funci on junto con su cuerpo se har a de la siguiente manera potencia(b, n) = p Si se establecen las variables:
71 b := Base n := Exponente p := Potencia bn entonces potencia : R N R (b, n) 1, si n = 0; b potencia(b, n 1), en otro caso.
La codicaci on en C++ de esta funci on es #include<iostream> #include<stdlib.h> using namespace std; double potencia(double b, int n){ if(n == 0){ return 1; }; return b * potencia(b,n - 1); }; int main(){ double b; int n; cout << "b? = "; cin >> b; cout << "n? = "; cin >> b; cout << "potencia(b,n) = "; cout << potencia(b,n); cout << "\n"; system("pause"); return EXIT_SUCCESS; }; Ejemplo. Pago del inter es compuesto mes vencido Sup onga que solicita un pr estamo de $1000.000 durante un a no, el prestamista cobra un inter es del 5 % mensual mediante la modalidad de interes compuesto mes vencido. Cu al es el total del dinero que debe pagar cuando ha transcurrido el a no por el cual solicit o el prestamo?. Para calcular el valor solicitado hay que observar que:
72
Para cero meses se tiene que hay que pagar $1 000.000 pues no ha transcurrido ning un mes. Para un mes se tiene que hay que pagar $1 000.000 + $1 000.000 0.05 = $1 000.000(1 + 0.05) lo prestado m as los intereses de un mes. Para dos meses se tiene que hay que pagar $1 000.000(1 + 0.05) + $1 000.000(1 + 0.05)0.05 = $1 000.000(1 + 0.05)(1 + 0.05) lo que se deb a pagar en el mes anterior m as los intereses de esa cantidad. A partir de las observaciones anteriores, ya se detecta la regla recursiva con la que se puede calcular el inter es compuesto mes vencido en general, con lo cual se puede dise nar una funci on recursiva que permita calcular el valor total a pagar para cualquier monto, cualquier inter es y cualquier intervalo de tiempo. pago(m, i, n) = valor donde se tienen las variables m := Cantidad de dinero solicitado como prestamo i := Interes n := N umero de meses por el cual se solicita el pretamo valor := Valor total a pagar por el prestamo de la cantidad m por n meses con un inter es i utilizando el m etodo de inter es compuesto mes vencido entonces pago : R+ R+ Z+ R+ (m, i, n) m, n = 0; pago(m, i, n 1) (1 + i), en otro caso.
73 double pago(double m, double i, int n){ if(n == 0){ return m; }; return pago(m,i,n - 1) * (1 + i); }; int main(){ double m; double i; int n; cout << "m? = "; cin >> m; cout << "i? = "; cin >> i; cout << "n? = "; cin >> n; cout << "pago(m,i,n) = "; cout << pago(m,i,n); cout << "\n"; system("pause"); return EXIT_SUCCESS; }; Ejemplo. N umero de listas de los elementos de un conjunto Suponga que selecciona cuatro cartas distintas de una baraja de poker, que se van a representar por los s mbolos
si con estas cartas se forma el conjunto cartas = p, o, n, m . De cu antas formas distintas se pueden organizar las cartas? Como se van a listar todas las formas posibles en que se pueden organizar las cartas, el orden si importa. Una estrategia para encontrar el n umero de listas puede ser el siguiente: 1. Se selecciona una carta del conjunto cartas de forma arbitraria pero ja, por ejemplo la carta o. 2. Ya jada la carta o, el resto del trabajo consiste en hallar el n umero de formas distintas de organizar las cartas restantes, es decir, el conjunto cartas {o} = p, n, m . 3. Ahora por ejemplo se selecciona la carta m de forma arbitraria pero ja. 4. A continuaci on, el trabajo se reduce a hallar el n umero de formas distintas de organizar las cartas restantes, es decir, el conjunto cartas {o, m} = p, n .
74
5. Posteriormente, por ejemplo se puede seleccionar de forma arbitraria pero ja la carta n. 6. Para nalizar, el trabajo se reduce a hallar el n umero de formas distintas de organizar las cartas restantes, es decir el conjunto cartas {o, m, n} = p . Como para este conjunto s olo se tiene una opci on, entonces el n umero de formas distintas de organizar un conjunto de una carta es 1. Siguiendo los pasos anteriores, se obtuvo la lista omnp Como la selecci on de las cartas se hizo de forma arbitraria, entonces, para poder listar todos los posibles ordenamientos, se tiene que el paso del numeral 1 se puede realizar de cuatro formas. Por cada una de estas escog encias se hace la selecci on de una carta de un conjunto con un elemento menos, como ocurre en el paso del numeral 3; esto se puede realizar de tres formas posibles. Por cada par de escog encias se hace la selecci on de una carta de un conjunto con dos elementos menos, como ocurre en el paso del numeral 5; esto se puede realizar de dos formas posibles. Por cada tr o de escog encias se hace la selecci on de una carta de un conjunto con tres elementos menos. Para este caso el conjunto restante tiene un solo elemento y por lo tanto s olo hay una posible selecci on. De lo anterior se concluye que el n umero de formas de listar los elementos de un conjunto con cuatro elementos es 4 3 2 1 = 24 En los diagramas que se presentan a continuaci on se exhibe la forma sistem atica en que se pueden obtener todas la posibles listas que se forman con las cartas p, o, n, m. o n m o m o n n m p m p n m n m o n o m n m p n p
ponm pomn pnom pnmo pmon pmno opnm opmn onpm onmp ompn omnp
75 p o m p m p o o n p n p o m o m p o p n o n p o p
npom npmo nopm nomp nmpo nmop mpon mpno mopn monp mnpo mnop
El listado de las 24 posibles formas en que se pueden organizar las cuatro cartas es el siguiente
En general, para un conjunto A con cardinal |A| = n, se tiene que el n umero de formas de listar todas lo formas en que se pueden organizar los elementos de A es n (n 1) (n 2) 3 2 1 este valor depende solamente de n, es una funci on, se denota por el s mbolo n! y se llama es factorial del n umero n. Para el caso del conjunto , se puede demostrar que 0! = 1. A partir de las observaciones anteriores se puede obtener la funci on recursiva factorial n!, distinta a la exhibida anteriormente f act(n) = f Si se establecen las variables:
76
n := N umero al cual se le va a calcular el factorial f := Factorial de n entonces f act : N N (n) 1, si n = 0; n f act(n 1), en otro caso.
La codicaci on en C++ de esta funci on junto con su programa principal es #include<iostream> #include<stdlib.h> using namespace std; int fact(int n){ if(n == 0){ return 1; }; return n * fact(n - 1); }; int main(){ int n; cout << "n? = "; cin >> n; while(n < 0){ cout << "n? = "; cin >> n; }; cout << "fact(n) = "; cout << fact(n); cout << "\n"; system("pause"); return EXIT_SUCCESS; }; Ejemplo. Conteo de subconjuntos Los Simpsons van a un parque de diversiones y quieren subir a la monta na rusa, por lo que s olo pueden subir Homero, Marge, Bart y Lisa, y en dicha monta na rusa cada vag on s olo dispone de dos puestos. De cuantas formas se pueden formar parejas de la familia Simpson para que suban al vag on de la monta na rusa?. Como se van a formar parejas, el orden no importa. Una estrategia para encontrar el n umero de parejas puede ser el siguiente:
Simpsons =
, , , , , , C (4, 2)
2. Dado el conjunto Simpsons, para la pareja que se va seleccionar se puede escoger o no a Homero, como se observa a continuaci on
, , , C (3, 1) +
, , C (3, 2)
3. Si en el numeral 2 se seleccion o a Homero, entonces ahora se puede escoger o no a Marge, como se observa a continuaci on
, , , C (3, 1) , , , C (2, 0) = 1 , , + C (2, 1) si se escoge a Marge, entonces ya se tiene una pareja. 4. Si en el numeral 2 se seleccion o a Homero y en el 3 no se seleccion o a Marge, entonces ahora se puede escoger o no a Bart, como se observa a continuaci on
78
, , C (2, 1) +
, , C (1, 0) = 1
, C (1, 1) = 1
si se escoge a Bart, entonces ya se tiene otra pareja, si no entonces Lisa debe hacer parte de la siguiente pareja. 5. Si en el numeral 2 no se seleccion o a Homero, entonces ahora se puede escoger o no a Marge, como se observa a continuaci on
, , C (3, 2)
, , C (2, 1)
, C (2, 2) = 1
si se no escoge a Marge, entonces ya se tiene una nueva pareja. 6. Si en el numeral 5 se seleccion o a Marge, entonces ahora se puede escoger o no a Bart, como se observa a continuaci on
, , C (1, 0) = 1
, , C (2, 1) + , C (1, 1) = 1
si se escoge a Bart, entonces ya se tiene otra pareja, si no entonces Lisa debe hacer parte de la u ltima pareja.
79 7. Despu es de hacer el conteo exhaustivo de la parejas que se pueden formar, se observa que existen 6 parejas que contienen dos miembros de la familia de los Simpsons, estas son:
, , , , A partir del ejemplo anterior, si la funci on C (n, k ) = c
, ,
representa el n umero de subconjuntos de k elementos de un conjunto de n elementos, ahora se puede construir una funci on recursiva que permita hacer el conteo del n umero de estos subconjuntos, de esta forma Si se establecen las variables: n := N umero de elementos del conjunto k := N umero de elementos de los subconjuntos c := N umero de subconjuntos de k elementos de un conjunto de n elementos entonces
C :NNN si k > n; 0, (n, k ) 1, si k = 0 n = k ; C (n 1, k 1) + C (n 1, k ), en otro caso. La codicaci on en C++ de esta funci on junto con su programa principal es
80
int C(int n, int k){ if(k > n){ return 0; }; if(k == 0 || n == k){ return 1; }; return C(n - 1,k - 1) + C(n - 1,k); }; int main(){ int n; int k; cout << "n? = "; cin >> n; cout << "k? = "; cin >> k; while(k > n){ cout << "n? = "; cin >> n; cout << "k? = "; cin >> k; }; cout << "C(n,k) = "; cout << C(n,k); cout << "\n"; system("pause"); return EXIT_SUCCESS; }; Ejemplo. Los conejos y los n umeros de Fibonacci Una pareja de conejos reci en nacidos (uno de cada sexo) se liberan en una isla. Los conejos no pueden tener descendencia hasta que cumplen dos meses. Una vez que cumplen dos meses, cada pareja de conejos tiene como descendencia otra pareja de conejos cada mes1 . Cu al es la cantidad de parejas de conejos en la isla una vez transcurrido un a no, suponiendo que ning un conejo muere?. Si fn denota la cantidad de parejas de conejos en el mes n, entonces, en el mes cero, en este aun no se ha hecho la liberaci on de la pareja de conejos, por lo tanto la cantidad de parejas es f0 = 0. n = 0, f0 = 0
Este problema fu e propuesto originalmente por el italiano Leonardo Pisano Bigollo (11701250), m as conocido como Leonardo de Pisa o Fibonacci (que signica hijo de Bonacci, lius Bonacci ) en su libro Liber abaci publicado en 1202.
1
81 Durante el primer mes, en este se hace la liberaci on de la primera pareja de conejos, pero a un no han alcanzado la edad para reproducirse, por lo tanto, no ha habido descendencia, por lo tanto, f1 = 1.
n = 1, f1 = 1
Durante el segundo mes, ya hab a una pareja de conejos del mes anterior y estos a un no han alcanzado la edad para reproducirse, por lo tanto, no hubo descendencia, de donde f2 es igual a la cantidad de conejos que hab an en el mes anterior m as la descendencia que produjeron las parejas de m as de dos meses, es decir, f2 = 1.
n = 2, f2 = f1 + f0 = 1 + 0 = 1
Durante el tercer mes, ya hab a una pareja de conejos del mes anterior y durante el transcurso de este mismo mes los conejos alcanzaron la madures para reproducirse, por lo tanto hubo descendencia, de donde f3 es igual a la cantidad de conejos del mes anterior m as la descendencia que se produjo en este mes, es decir, f3 = 2.
n = 3, f3 = f2 + f1 = 1 + 1 = 2
Durante el cuarto mes ya hab an dos parejas de conejos del mes anterior, y la pareja madura es la que hab a en el segundo mes, por lo tanto, la descendencia fue generada s olo por esa pareja, de donde f4 es igual a la cantidad de parejas del mes anterior m as la descendencia que gener e la pareja del segundo mes, es decir, f4 = f3 + f2 = 2 + 1 = 3.
n = 4, f4 = f3 + f2 = 2 + 1 = 3
Durante el quinto mes ya hab an tres parejas de conejos del mes anterior, y de estas hay dos parejas maduras, que son las que hab an en el tercer mes, por lo tanto, la descendencia fue generada por esas dos parejas, de donde f5 es igual a la cantidad de parejas del mes anterior m as la descendencia que generen las parejas del tercer mes, es decir, f5 = f4 + f3 = 3 + 2 = 5.
n = 5, f5 = f4 + f2 = 3 + 2 = 5
82
Haciendo an alisis similares se obtienen los siguientes resultados: Para Para Para Para Para Para Para n = 6, n = 7, n = 8, n = 9, n = 10, n = 11, n = 12, se tiene que se tiene que se tiene que se tiene que se tiene que se tiene que se tiene que f6 = f5 + f4 = 5 + 3 = 8 f7 = f6 + f5 = 8 + 5 = 13 f8 = f7 + f6 = 13 + 8 = 21 f9 = f8 + f7 = 21 + 13 = 34 f10 = f9 + f8 = 34 + 21 = 55 f11 = f10 + f9 = 55 + 34 = 89 f12 = f11 + f10 = 89 + 55 = 144
De aqu que, transcurrido el primer a no, en la isla habr an 144 parejas de conejos. A los n umeros que son generados utilizando esta regla se les conoce como n umeros de Fibonacci. A partir del an alisis anterior, se puede dise nar una funci on recursiva que permite calcular cualquier n umero de Fibonacci. f ibo(n) = f donde se tienen las variables n := N umero del cual se desea calcular su n umero de Fibonacci f := N umero de Fibonacci de n entonces f ibo : N N (n) 1, si (n = 0) (n = 1); f ibo(n 1) + f ibo(n 2), en otro caso.
int fibo(int n){ if(n == 0){ return 0; }else if(n == 1){ return 1; }; return fibo(n - 1) + fibo(n - 2); };
83 int main(){ int n; cout << "n? = "; cin >> n; cout << "Fibonacci(n) = "; cout << fibo(n); cout << "\n"; system("pause"); return EXIT_SUCCESS; }; Ejemplo. N umero primo Determinar si un n umero mayor a 1 es primo o no (s olo es divisible por 1 y por el mismo). Por denici on, n es primo si no es compuesto. Un n umero m es compuesto si se puede descomponer en la forma m=pq donde p, q N, 1 < p < m y 1 < q < m. Entonces, para saber si un n umero es primo es equivalente a vericar que no es compuesto, es decir, que no hay un n umero k N, tal que 1 < k < m y que k sea divisor de m. De lo anterior, para saber si un n umero n es compuesto hay que ir probando con los n umeros desde 2 hasta n 1, y observar si alguno de ellos es divisor de n; si no es as , entonces n es primo. Una observaci on adicional que har a m as eciente el algoritmo es la siguiente Si un n umero n es compuesto, es decir, es de la forma n = p q , con p > 1 n o q n. Esto porque si no , entonces, se y q > 1, entonces, p es 2as tendr a que p > n y q > n, de donde, n = p q > ( n) = n, lo cual es una contradicci on, por lo tanto, se debe tener que p n o q n. A partir del an alisis anterior, se pueden dise nar las funciones que permiten determinar si un n umero es primo o no. Inicialmente es necesario construir una funci on auxiliar o ayudante (en ingl es helper ) que nos permita responder a la pregunta Dado un par de enteros positivos n y d, n es m ultiplo de alg un valor entre d y n inclusive?. La siguiente funci on recursiva permite a la pregunta anterior. multiplo(n, d) = valor donde se establecen las variables n := N umero del cual se desea saber si es multiplo de d d := N umero candidato a ser divisor de n valor := true si d es multiplo de n y f alse si no lo es entonces
84
multiplo : N P B si n m od d = 0; V, (n, d) F, si d > n; multiplo(n, d + 1), en otro caso. Con el uso de la anterior funci on se puede dise nar una nueva funci on que permita determinar si un entero mayor que 1 es primo o no, la idea es probar los n umeros entre 2 y n usando la funci on anterior y vericar si n es m ultiplo de alguno de estos n umeros, si se da este caso, entonces el n umero no es primo, en caso contrario se tendr a que el n umero es primo. La siguiente funci on permite determinar si un n umero es primo o no primo(n) = valor donde se tienen las variables n := N umero del cual se desea establecer si es primo o no valor := true si n es primo y f alse si no lo es entonces primo : N {0, 1} B (n) multiplo(n, 2)
La codicaci on en C++ de estas funciones es la siguiente, aqu se utiliza la funci on sqrt(x), la cual est a previamente construida en la librer a math.h, esta se puede incluir mediante la instrucci on #include<math.h>. En los ejercicios se solicitar a construir la x y en cap tulo de ciclos se explicar a como construir la funci on x en general: funci on
85 bool multiplo(int n, int d){ if(n % d == 0){ return true; }; if(d > sqrt(n)){ return false; }; return multiplo(n,d + 1); };
int main(){ int n; cout << "n? = "; cin >> n; cout << "Es n primo? = "; cout << primo(n); cout << "\n"; system("pause"); return EXIT_SUCCESS; }; Ejemplo. El mural de una empresa Una empresa tiene disponibles dos paredes como las siguientes que utilizan como murales para jar carteles, aches o pendones. Pared 1
p1 Pared 2
p2 El gerente de la empresa desea jar unos carteles del mismo ancho, con la condici on de que tiene que colocar los aches completos, que abarquen en su totalidad dichas paredes y que no se solapen. La empresa tiene la capacidad de mandar a imprimir y cortar los aches de cualquier ancho. Cu al ser a el ache de mayor ancho que puede colocar la empresa de tal manera que utilice en su totalidad las paredes y que los aches se peguen completos sin solaparse?
86
1. Para saber cu al es el ache m as ancho que se puede colocar en las paredes p1 y p2 , se debe observar que la pared m as corta es p2 , por lo tanto el ache m as ancho debe tener por mucho el ancho de esa pared. 2. Si a la pared m as ancha p1 se tapa con la pared m as corta p2 , se obtiene un resto r1 de pared como el siguiente p1
p2
r1
3. Como los aches tapar an completa y exactamente la pared p2 , para que estos aches tambi en tapen la pared p1 , entonces deben tapar completa y exactamente el resto r1 de la pared. Por lo que para este caso el ache m as ancho debe tener por mucho el ancho de ese resto r1 de pared. 4. El ancho de r1 pasa a ser entonces el candidato a ser el ancho del ache, por lo que es necesario que el ache que tape la pared r1 tambi en tape la pared p2 . As , si ahora se tapa pared p2 con la pared r1 tantas veces como sea posible, entonces, se obtiene un resto r2 de pared como el siguiente p2
r1
r1
r2
5. En este caso ocurre lo mismo que en el numeral 3, para tapar la pared p2 se debe tapar tambi en la pared restante r2 , por lo que el ache m as ancho debe tener por mucho el ancho de ese resto r2 de pared. 6. De lo anterior, se tiene que el ancho de r2 pasa a ser entonces el candidato a ser el ancho del ache, por lo que es necesario que el ache que tape la pared r2 tambi en tape la pared restante r1 . As , si ahora se tapa pared r1 con la pared r2 tantas veces como sea posible, entonces, se obtiene un resto r3 de pared como el siguiente r1
r2
r3
7. En este punto, el an alisis es similar a los casos anteriores, pues para tapar la pared r1 es necesario tapar el resto de pared r3 . Con lo cual se obtiene un nuevo candidato, el ancho de la pared r3 . Si con esta pared r3 se tapa la pared r2 tantas veces como
r3
r3
8. Por la construcci on anterior, se tiene que un ache que utilice en su totalidad las paredes y que se peguen completos sin solaparse est a dado por el ancho de la pared r3 . Un ache de este ancho ser a el de mayor tama no pues siempre se escogi o el de mayor tama no posible para ir descartando las otras opciones. 9. El aspecto de las paredes con los aches colocados de acuerdo al resultado obtenido es el siguiente
No siempre este problema es solucionable, ya que existen paredes de distinta longitud, tales que no tienen un segmento umero exacto de veces, por ejemplo, si que quepa una n la primera longitud mide l1 = 2 unidades y la segunda l2 = 2, no existe un segmento que quepa un n umero exacto de veces, a este tipo de medidas se les denomina inconmensurables, y para las que s existe un segmento que cabe un n umero exacto de veces se les llama conmensurables. Volviendo al problema de encontrar el ache de mayor longitud que quepa en un par de paredes de forma exacta sin solaparse, en el caso de que las paredes tengan longitudes n umeros naturales unidades, entonces en estas siempre es posible encontrar una longitud que cumpla con las condiciones impuestas anteriormente, pues estas longitudes con conmensurables, ya que en el peor de los casos los aches con longitud una (1) unidad siempre cabra un n umero exacto de veces sin solaparse. En matem aticas, a el segmento de mayor longitud en cabe un n umero exacto de veces en dos segmentos conmensurables se le conoce como el m aximo com un divisor de los dos segmentos. A partir del an alisis anterior, se puede dise nar una funci on recursiva que permite calcular el m aximo com un divisor de dos n umeros p y q , donde se supone que p q . mcd recur(p, q ) = m
p := Primer n umero natural positivo q := Segundo n umero natural positivo tal que q p m := M aximo com un divisor de los n umeros p y q entonces mcd recur : N N N (p, q ) p, si q = 0; od q ), en otro caso. mcd recur(q, p m
Como se desea que se pueda calcular el m aximo com un divisor de cualesquiera dos n umeros naturales, entonces la funci on anterior se utilizar a como una funci on auxiliar (helper ), y la siguiente funci on s permitir a calcular el m aximo com un divisor de cualesquiera dos n umeros, esta lo que hace es primero encontrar el mayor de los dos n umeros y luego utilizar la funci on mcd recur(p, q ) de forma correcta. mcd(p, q ) = m donde se tienen las variables p := Primer n umero natural positivo q := Segundo n umero natural positivo m := M aximo com un divisor de los n umeros p y q entonces mcd : N N N (p, q ) mcd recur(p, q ), si p > q ; mcd recur(q, p), en otro caso.
89 int mcd_recur(int p, int q){ if(q == 0){ return p; }else{ return mcd_recur(q,p % q); }; }; int mcd(int p, int q){ if(p > q){ return mcd_recur(p,q); }else{ return mcd_recur(q,p); }; }; int main(){ int p; int q; cout << "p? = "; cin >> p; cout << "q? = "; cin >> q; cout << "m.c.d(p,q) = "; cout << mcd(p,q); cout << "\n"; system("pause"); return EXIT_SUCCESS; };
90
7.1. Ejercicios
1. Modele mediante una funci on matem atica y dise ne un programa recursivo que determine el mayor de dos n umeros enteros no negativos que utilice s olo el operador de comparaci on de la igualdad (==), la funci on sucesor (sumar 1), la funci on predecesor (restar 1) y la estructura condicional (if). 2. Modele mediante una funci on matem atica y dise ne un programa recursivo que calcule n la suma de los primeros n n umeros positivos i=1 i . 3. Modele mediante una funci on matem atica y dise ne un programa recursivo que calcule n 2 la suma de los cuadrados de los primeros n n umeros positivos i=1 i . 4. Modele mediante una funci on matem atica y dise ne un programa recursivo que calcule n 2 el producto de los cuadrados de los primeros n n umeros positivos i=1 i . 5. Modele mediante una funci on matem atica y dise ne un programa recursivo que calcule el logaritmo entero en base 2 de n log2 n . Por ejemplo, log2 1 = 0, log2 4 = 2, log2 7 = 2, log2 15 = 3. 6. Modele mediante una funci on matem atica y dise ne un programa recursivo que calcule el logaritmo entero en base b de n logb n . 7. Modele mediante una funci on matem ne un programa recursivo que calcule atica y dise a . Por ejemplo, 0 = 0, 1 = 1, 5 = 2, la ra z cuadrada entera de a 10 = 3. 8. Modele mediante una funci on matem atica y dise ne un programa recursivo que calcule la ra z n- esima entera de a n a . 9. Modele mediante una funci on matem atica y dise ne un programa recursivo que calcule la funci on m odulo (m m od n = k ). Por ejemplo, 0 m od 2 = 0, 4 m od 2 = 0, 3 m od 3 = 0, 10 m od 3 = 1, 14 m od 5 = 4. 10. Modele mediante una funci on matem atica y dise ne un programa recursivo que determine la cantidad de d gitos que componen un n umero natural n. Por ejemplo, longitud(654321) = 6. 11. Modele mediante una funci on matem atica y dise ne un programa recursivo que invierta la cifras de un n umero n dado. Por ejemplo, inversa(654321) = 123456. 12. Modele mediante una funci on matem atica y dise ne un programa recursivo que determine si un n umero es pal ndromo. Un n umero se dice pal ndromo si al leerlo de izquierda a derecha es lo mismo que leerlo de derecha a izquierda. Por ejemplo, palindromo(1) = V , palindromo(1234321) = V , palindromo(123421) = F . 13. Modele mediante una funci on matem atica y dise ne un programa recursivo que calcule el m nimo com un m ultiplo de dos n umeros positivos a y b. Por ejemplo, mcm(18, 24) = 72.
7.1. EJERCICIOS
91
14. Modele mediante una funci on matem atica y dise ne un programa que dados dos n umero positivos p y q , donde p representa el numerador y q el denominador de la p p fracci on , imprima primero el numerador de la fracci on simplicada a su m nima q q p nima expresi on. expresi on y luego el denominador de la fracci on simplicada a su m q 15. Modele mediante una funci on matem atica y dise ne un programa que dados cuatro n umero positivos p, q , r y s, donde p representa el numerador y q el denominador p de la fracci on , y r representa el numerador y s el denominador de la fracci on q r p r , imprima primero el numerador de la fracci on resultante de la operaci on + s q s simplicada a su m nima expresi on y luego el denominador de la fracci on resultante p r nima expresi on. de la operaci on + simplicada a su m q s
92
Cap tulo
94
Ejemplo. Para el siguiente fragmento de c odigo que contiene un ciclo while int i = 0; while(i <= 5){ cout << i; cout << "\n"; i = i + 1; }; se tiene que el fragmento de c odigo: <init> corresponde a la instrucci on int i = 0; <cond> corresponde a la instrucci on i <= 5 <body> corresponde a las instrucciones cout << i; cout << "\n"; <update> corresponde a la instrucci on i = i + 1; cuando se ejecuta este ciclo lo que se obtiene en la consola de salida es el texto que se presenta a la derecha del siguiente cuadro int i = 0; while(i <= 5){ cout << i; cout << "\n"; i = i + 1; }; 0 1 2 3 4 5
en este caso la salida que se produce es la anterior porque el bloque cout << i; cout << "\n"; se ejecuta seis veces, variando i desde 0 hasta cuando i toma el valor 6, que hace que la condici on se evalu e falso; obs ervese que la variable termina el ciclo con valor i = 6, pero este valor no se imprime pues para este caso la condici on se eval ua falso. Ejemplo. Para el siguiente fragmento de c odigo que contiene un ciclo while
95
int i = 1; int j = 10; while(i < j){ cout << i; cout << "\n"; cout << j; cout << "\n"; i = i * 2; j = j + 10; }; la variables i y j se inicializan con los valores 1 y 10 respectivamente, luego se verica que 1 sea menor estrictamente que 10, a continuaci on se imprime el valor de la variable i seguido por un espacio, seguido por el valor de la variable j, seguido de una salto de l nea; a continuaci on se multiplica la variable i por 2 y a la variable j se le suma 10. Esto se realiza hasta que el valor de la variable i sea mayor o igual a el valor de la variable j. El resultado de la ejecuci on de este ciclo mostrado en la consola de salida es el texto que se presenta a la derecha del siguiente cuadro int i = 1; int j = 10; while(i < j){ cout << i; cout << " "; cout << j; cout << "\n"; i = i * 2; j = j + 10; };
1 10 2 20 4 30 8 40 16 50 32 60 64 70
Obs ervese que las variables i y j terminan el ciclo con los valores 128 y 80, y como 128 no es menor que 80, entonces el ciclo se para, por esta raz on no se imprimen estos valores.
96
la sintaxis general de un ciclo for que es equivalente al ciclo while es for(<init> ; <cond> ; <update>){ <body> }; Ejemplo. La suma de los primeros n n umeros naturales Las dos siguientes funciones permiten calcular la suma de los primeros n n umeros naturales positivos, es decir, permiten calcular el valor de la expresi on
n
int suma(int n){ int s = 0; int i = 1; while(i <= n){ s = s + i; i++; }; return s; }; int suma(int n){ int s = 0; for(int i = 1 ; i <= n ; i++){ s = s + i; }; return s; }; estas dos funciones son equivalentes, ya que ejecutan las mismas modicaciones de las variables, pues se tiene que el fragmento de c odigo: <init> corresponde a la instrucci on int i = 1; <cond> corresponde a la instrucci on i <= n <body> corresponde a la instrucci on s = s + i; <update> corresponde a la instrucci on i++;
97
En la construcci on de estas funciones aparecen dos variable que tienen una connotaci on muy importante: La variable i juega el rol de una variable contadora ya que permite llevar el conteo de cuantos ciclos se han efectuado. La variable s juega el rol de variable acumuladora pues en esta se acumula o almacena el valor parcial que se desea calcular utilizando el ciclo. La codicaci on en C++ de una funci on que permite sumar los primeros n n umeros naturales positivos junto con su programa principal es #include<iostream> #include<stdlib.h> using namespace std; int suma(int n){ int s = 0; for(int i = 0 ; i <= n ; i++){ s = s + i; }; return s; }; int main(){ int n; cout << "n? = "; cin >> n; cout << "La suma de los primeros n numeros es: "; cout << suma(n); cout << "\n"; system("pause"); return EXIT_SUCCESS; }; Si se ejecuta el anterior programa y como entrada se ingresa el valor n = 6 (por ejemplo el n umero de caras de un dado), el resultado que se obtiene es el siguiente n? = 6 La suma de los primeros n numeros es: 21 Presione una tecla para continuar . . . En general es f acil comprobar si el resultado que se obtiene utilizando la funci on suma(n) es correcto, pues existe una f ormula muy sencilla para calcular la suma de los primeros
98
n n umeros naturales positivos sin necesidad de realizar la suma exhaustivamente. Esta f ormula es n n(n + 1) i= 2 i=1 la cual se puede demostrar por inducci on matem atica y que para el valor n = 6 se obtiene el resultado
6
1+2+3+4+5+6=
i=1
i=
67 42 6(6 + 1) = = = 21 2 2 2
99
Como primer paso en el m etodo se da un valor inicial x0 que es cualquier n umero real positivo que servir on a la raiz cuadrada que se a como una primera aproximaci desea calcular, x0 a. En segunda instancia, por la ley de tricotom a de los n umeros reales, se cumple que: x0 = a x0 > a x0 < a a partir de estos casos se pueden hacer los siguientes an alisis: Si x0 = a entonces x0 = a x2 0 = a a x0 = x0 de donde x0 = Si x0 > a=
a . x0
a>
a . x0
de donde x0 <
a<
a . x0
100
double valor_absoluto(double x){ double valor; if(x >= 0){ valor = x; }else{ valor = -x; }; return valor; };
double raiz(double x){ double Xo; double Xi = x; do{ Xo = Xi; Xi = 0.5 * (Xo + x / Xo); }while(valor_absoluto(Xo - Xi) >= 1e-6); return Xi; };
int main(){ double x; cout << "x? = "; cin >> x; cout << "Una aproximacion de la raiz cuadrada de x es: "; cout << raiz(x); cout << "\n"; system("pause"); return EXIT_SUCCESS; };
101
void recHelperFunc(int loopVar) { if(<cond>) { <body> <update> recHelperFunc(loopVar); // llamada recursiva } } Que recursivamente como funci on puede ser visto matem aticamente de la siguiente forma: f :ZZZZ (k, i) f (k , i)|k = k + i, i = i + 1si k < 10 (i, k ) en otro caso
double area_rectangulo(double l, double a){ return l*a; }; int main(){ double largo; double ancho; cout << "largo? = "; cin >> largo; while(largo < 0){ cout << "El largo no es valido"; cout << "\n"; cout << "largo? = "; cin >> largo; }; cout << "ancho? = "; cin >> ancho; while(ancho < 0){ cout << "El ancho no es valido"; cout << "\n"; cout << "ancho? = "; cin >> ancho; }; cout << "area rectangulo: "; cout << area_rectangulo(largo, ancho); cout << "\n"; system("pause"); return EXIT_SUCCESS; };
8.7. EJERCICIOS
103
8.7. Ejercicios
1. Dise nar una funci on que permita calcular una aproximaci on de la funci on exponencial alrededor de 0 para cualquier valor x R, utilizando los primeros n t erminos de la serie de Maclaurin n xi exp(x) . i ! i=0 2. Dise nar una funci on que permita calcular una aproximaci on de la funci on seno alrededor de 0 para cualquier valor x R (x dado en radianes), utilizando los primeros n t erminos de la serie de Maclaurin
n
sen(x)
i=0
3. Dise nar una funci on que permita calcular una aproximaci on de la funci on coseno alrededor de 0 para cualquier valor x R (x dado en radianes), utilizando los primeros n t erminos de la serie de Maclaurin
n
cos(x)
i=0
4. Dise nar una funci on que permita calcular una aproximaci on de la funci on arco tangente para cualquier valor x [1, 1], utilizando los primeros n t erminos de la serie de Maclaurin (al evaluar esta funci on el resultado que se obtiene esta expresado en radianes) n (1)i x2i+1 arctan(x) . (2 i + 1) i=0
104
Cap tulo
106
int leer_entero(istream& is){ int a; is >> a; return a; }; Para escribir un dato de un tipo primitivo dado en un ujo, se tiene: escribir A : A OS OS (a, os) os|escribir(a, os); Que aplicada a datos de tipo entero lucir a as en C++ (se agrega el caracter tabulador una vez se escribe un entero por comodidad): ostream& escribir_entero(int a, ostream& os){ os << a << "\t"; return os; }; Para llamar las funciones anteriores, leyendo y escribiendo en la consola las funciones se pueden llamar de la siguiente forma: int main(){ cout << "Digite entero: "; int a = leer_entero(cin); cout << "Entero leido: "; escribir_entero(a, cout); cout << "\n"; system("pause"); return 0; }; Para el programa anterior se tiene como salida: Digite entero: -56 Entero leido: -56 Press any key to continue . . .
107
Sintaxis: ifstream f(localizacion). El parametro de ubicaci on depende del sistea ma operativo. Si se proporciona como localizacion . rchivo.txt, se abrir a el archivo a en llamado . rchivo.txt. la ruta del archivo ejecutable. Para proporcionar una ruta especica de un archivo en Windows es necesario especicar la unidad y el directorio c : \\misdocumentos\\archivo.txt y en linux la ruta se especica desde el directorio raiz / ejemplo /home/user/archivo.txt
9.3. Ejemplo
Dado que los IF S IS , la denici on anterior de ujos de entrada y salida aplica para manejar archivos. Si se tiene el archivo entrada.txt con los siguientes datos:
0 1 2 3 4 5
Y se quiere leer de este archivo para copiar los primeros 4 enteros del archivo al archivo salida.txt, se podr a tener el siguiente programa principal:
int leer_entero(istream& is){ int a; is >> a; return a; }; ostream& escribir_entero(int a, ostream& os){ os << a << "\t"; return os; }; int main(){ int a=0; ifstream ifs("entrada.txt"); ofstream ofs("salida.txt"); while(a < 4){ escribir_entero(leer_entero(ifs), ofs); a++; }; ofs.close(); ifs.close(); cout << "\n"; system("pause"); return 0; }; La salida de dicho programa ser a: Press any key to continue . . . Y se generar a el archivo salida.txt con el siguiente contenido: 0 1 2 3 Esta declaraci on de ujo sobreescribe el archivo cada vez que se ejecuta el programa. N otese que cada dato con esta sintaxis se lee hasta encontrar uno de los siguientes caracteres especiales: \t, \n, . La primera vez que se entra en el ciclo while se lee el entero 0, luego se realiza la lectura del 1 y as sucesivamente.
Cap tulo
10
Tn = T T T T
n-veces
A este producto cartesiano generalizado se le dice arreglo n-dimensional o de tama no n. Cuando se tiene la notaci on de producto cartesiano generalizado, se puede observar la denici on de un producto cartesiano indeterminado donde no se dene el tama no y se dene la uni on de todos los conjuntos que denen arreglos de diferentes tama nos: T =
nN
Para denir arreglos se utilizar a la notaci on de memoria din amica. x A en C++ se dene como A* x; y para denir a que tipo particular de arreglo pertenece, se dene a x = new A[10]. Cuando se dene un arreglo de esta forma, es necesario eliminar dicho arreglo, para esto se usara delete[] x.
2 2 2
2 2
[x[0]
, x[1] , x[2] ,
( x1 , x2 , x3 ,
109
, x n 1 , x n )
110
int main(){ double* x = new double[10]; //definicion de arreglo x[5] = 10.0; //A la posicion 5 del arreglo se le asigna 10 x[0] = 3.5; //El primer elemento de un arreglo esta en // la posicion cero. x[10] = 1E12; //Esta asignacion no es posible pues iniciando // en 0 el ultimo elemento del arreglo estara en la // posicion n-1, es decir 9. delete[] A; //Eliminacion de arreglo. }; Cuando se dene un arreglo en C++, es necesario tener en cuenta que la primera posici on de un arreglo es la posici on 0. Para un arreglo de tama no n se tiene que la posici on m axima de un arreglo ser a la posici on n 1. (x1 , x2 , x3 , . . . , xn1 , xn )
new T[n]
M
T T T T
T* x = new T[n]
111
M
x[0] x[1]
x[n-2] x[n-1]
crear arreglo A : N T (n) x, donde x An A En C++ se traduce A* crear_arreglo_A(int n){ return new A[n]; }; Para crear un arreglo de tipo entero se tiene int* crear_arreglo_int(int n){ return new int[n]; }; Para destruir o liberar un arreglo, se realizaran algunas salvedades matem aticas para facilitar la traducci on a lenguaje C++. En este caso para liberar el arreglo, se tomar a el tama no del arreglo aunque no se requiere. En este caso para simplicar las cosas se tiene una funci on que retornar a vac o. Lo que se realizar a es liberar el espacio en memoria para que este espacio pueda ser utilizado por otras variables. Matem aticamente se tiene: liberar arreglo A : A N (M) (x, n) M M(x) En C++ se traduce: void liberar_arreglo_A(A* x, int n){ delete[] x; return; }; Para liberar un arreglo de tipo entero se tiene:
112
10.3. Subindices
Un subindice es una variable de tipo Natural. Si i, j, k N es posible decir: xj +2i3k . Para b N10 , i, j N, x R7 , es posible decir: xbi+j o bbij . Por ejemplo: Si i = 3, j = 2 y b = 7, 3, 2, 8, 4, 1, 0, 6, 2, 1 el elemento que est a en la posici on bbij es bb32 = bb1 = b3 = 8. Tambien es posible usar funciones xf ib(3) .
113
114
xn en otro caso
Al realizar la funci on en C++ es necesario realizar los corrimientos de los xn desde n 1 hasta 0. double max_arreglo(double* x, int n){ if(n > 1){ int k = max_arreglo(x, n-1); if(k > x[n-1]){ return k; }; }; return x[n-1]; };
115
pos max : R N R (x, n) k |k = pos max(x, n 1) si k > xn n > 1 n en otro caso Al realizar la funci on en C++ es necesario realizar los corrimientos de los xn desde n 1 hasta 0. double pos_max(double* x, int n){ if(n > 1){ int k = pos_max(x, n-1); if(x[k] > x[n-1]){ return k; }; }; return n-1; }; La funci on que realiza el ordenamiento llamar a a la funci on anterior y realizar a un intercambio si el elemento es mayor al u ltimo. ordenar arreglo : R N R (x, n) ordenar(x, n 1)|k = pos max(x, n), t = xk , xk = xn , xn = t; si n > 1 x en otro caso /** Esta funcion ordena el arreglo reemplazando * la posicion del maximo elemento, con * la ultima posicion y realizando un llamado * recursivo reduciendo el tamano del arreglo * en 1. */ int* ordenar(int* x, int n){ if(n > 1){ int k=pos_max(x, n); //Swap entre la posicion del maximo y // la ultima posicion int t = x[k]; x[k] = x[n-1]; x[n-1] = t; return ordenar(x, n-1); }; return x; };
116
Cap tulo
11
Cadenas de Caracteres
Hasta ahora se ha trabajado con tipos de datos primitivos y arreglos. Entre los tipos de datos primitivos se encuentran los caracteres que se denieron matem aticamente como ASCII . Los caracteres ASCII (American Standard Code for Information Interchange) permiten representar letras, numeros y simbolos. Inicialmente se denieron de 7 bits (128 caracteres) y luego se extendieron a 8 bits (256 caracteres). Decir que x ASCII , en C++ equivale a decir char x. Sobre los caracteres se pueden tener las siguientes operaciones: char letra = A; //Asigna el caracter A char letra2 = 65; // Asigna la letra A //a letra 2, pues A // es el caracter en decimal // 65 del ASCII cout << letra + letra2 //imprime el numero 130 cout << (char)(letra + letra2) //imprime e tildada if(letra == letra2){ //Se pueden hacer cout << "igual"; //comparaciones entre char } cout << 0 + 1 //imprime 97 cout << (char)(0 + 1) //imprime a Como se vi o en la parte de ujos, existen tambien caracteres especiales como los siguientes: cout << (int)( ); //imprime 32 que corresponde al caracter // espacio cout << (int)(\n); // imprime el numero 13 // que en ASCII es el caracter //new line cout << (int)(\0); //imprime el valor cero que //equivale a NUL o fin de cadena 117
118
Las cadenas de caracteres corresponden a arreglos de char (ASCII ) y toda cadena termina con el caracter numero cero o NUL que representa n de linea. Es posible denir cadenas de forma est atica, si se denen as no podran modicarse o reasignarse: char* mensaje = "hola mundo\n\0"; //creacion // de cadena // estatica A continuaci on hay un ejemplo que muestra como cadenas pueden ser vistas como arreglos. Carga la cadena mensaje con el texto hola.eimprime un cambio de linea. N otese que el tama no del arreglo es de 100, pero la cadena resultante es de tama no 5 sin incluir el caracter de terminacion de cadena. int n = 100; char* mensaje = new cadena[n]; mensaje[0] = h; mensaje[1] = o; mensaje[2] = l; mensaje[3] = a; mensaje[4] = \n; mensaje[5] = \0; cout << mensaje; Sobre arreglos denimos algunas funciones clave que tambi en aplican para cadenas pero con algunos cambios que veremos a continuaci on: Funciones constructoras: Las funciones constructoras permiten como su nombre lo indica construir una cadena, cuando vimos arreglos la denici on general era esta: crear arreglo : N A (n) x|x An A En C++ se traduce:
A* crear_arreglo(int n){ return new A[n]; }; Con cadenas pasa lo mismo: crear cadena : N ASCII (n) x|x ASCII n ASCII
char* crear_cadena(int n){ return new char[n]; }; Funciones Liberadoras: Estas funciones permiten devolver la memoria empleada por un TDA al sistema operativo. Los tipos de datos primitivos no requieren esta denici on pero tipos de datos como los arreglos o los TDA escritos por un programador deben ser liberados. Est an asociadas al operador delete en C++. Para arreglos se ten a: liberar arreglo : A N (x, n) En C++ se traduce:
void liberar_arreglo(A* x, int n){ delete[] x; }; Para las cadenas se tiene lo mismo, pero sin tener el n de tama no. liberar cadena : ASCII (x, n) En C++ se traduce:
void liberar_arreglo(char* x){ delete[] x; }; Funciones de persistencia: Ac a esta la diferencia con arreglos. No se le preguntar a al usuario cuantos caracteres tiene el nombre ni leerlos letra por letra, nos toca aproximar un n que en este caso tambien lo enviamos como parametro (vease el main mas adelante). Lo interesante de las cadenas con respecto a los arreglos de enteros y reales es que podemos leer toda la cadena con una sola instrucci on de la librer a iostream: leer cadena : IS ASCII N ASCII (is, x, n) x|x = leer cadena(is, n)
120
En este caso el n puede ser aproximado por el programador, obs ervese que no se emple o is >> x pues no podr a leer nombres por ejemplo Sandra Milenaquedar a Sandra, getline leer a el ujo hasta encontrar un salto de linea o cumplirse la longitud de cadena dada. Para imprimir una cadena si podemos utilizar el operador <<: escribir cadena : OS ASCII OS (os, x) os|escribir cadena(os, x) En C++:
ostream& escribir_cadena(ostream& ofs, char* x){ ofs << x << "\t"; return ofs; };
A diferencia de los arreglos no es necesario imprimir elemento a elemento con un ciclo o una rutina recursiva. Otras funciones: Como se suele operar en cadenas con los datos que proporciona un usuario es necesario tener una funci on especial que nos indique cuantos caracteres hay al nal de una cadena, esto es contar cuantos caracteres hay antes del caracter \0. Recursivamente esta funci on puede denirse como obtener la longitud de una cadena: longitud cadena parcial : ASCII N N (x, i) 0 si x[i] = \0 1 + longitud cadena parcial(x, i + 1) en otro caso longitud cadena : ASCII N (x) longitud cadena parcial(x, 0) En C++ se traduce:
121
int longitud_cadena_p(char* str, int i){ if(str[i] == \0){ return 0; }; return 1 + longitud_cadena_p(str, i+1); }; int longitud_cadena(char* str){ return longitud_cadena_p(str, 0); };
Con esta funci on de longitud se pueden denir funciones interesantes como copiar cadena:
copiar cadena : ASCII ASCII (str) strcp|strcp = crear cadena(longitud cadena(str) + 1), strcpi = stri i=0,1,2,..,longitud cadena(str) , strcp(longitud cadena(str)) = \0
char* copiar_cadena(char* str){ int i; int lstr = longitud_cadena(str); char* strcp = crear_cadena(lstr+1); for(i=0; i < lstr; i++){ strcp[i] = str[i]; }; strcp[lstr] = \0; return strcp; };
int longitud_cadena_p(char* str, int i){ if(str[i] == \0){ return 0; }; return 1 + longitud_cadena_p(str, i+1); }; int longitud_cadena(char* str){ return longitud_cadena_p(str, 0); }; char* crear_cadena(int n){ return new char[n]; }; char* copiar_cadena(char* str){ int i; int lstr = longitud_cadena(str); char* strcp = crear_cadena(lstr+1); for(i=0; i < lstr; i++){ strcp[i] = str[i]; }; strcp[lstr] = \0; return strcp; }; void liberar_cadena(char* str){ delete[] str; }; char* leer_cadena(istream& is, char* str, int n){ is.getline(str, n); return str; }; ostream& escribir_cadena(ostream& os, char* str){ os << str << "\n"; }; int main(){ int n = 100; /* Crea una cadena de tamano 100 */ char* str = crear_cadena(n); char* str_copia = crear_cadena(n);
123
124
Cap tulo
12
126
Funciones Modicadoras: Estas funciones permiten cambiar un dato de un TDA, est an relacionadas con las asignaciones. Funciones Analizadoras: Estas funciones permiten obtener un dato miembro de un TDA. Funciones Liberadoras: Estas funciones permiten devolver la memoria empleada por un TDA al sistema operativo. Los tipos de datos primitivos no requieren esta denici on pero tipos de datos como los arreglos o los TDA escritos por un programador deben ser liberados. Est an asociadas al operador delete en C++. Funciones de persistencia: Son funciones que permiten mantener el dato a trav es del tiempo. En este caso se han utilizado los ujos de datos para leer o escribir los datos en archivos o enviarlos a la salida est andar de la consola.
a_n;
typedef base_A* A; La palabra struct declara la construcci on de la estructura como el producto cartesiano y typedef nos permite nombrar un puntero a la estructura base A y as poder manipular el TDA como par ametro en una funci on o retornarlo como salida de funciones sin realizar cambios adicionales utilizando memoria din amica. Como ejemplo pueden denirse los numeros complejos C como un TDA constituido por dos numeros reales, uno que representa la parte real del y otro que representa la parte imaginaria. C = R R. En C++ se declararan as : struct base_complejo{ double x; //parte real double y; //parte imaginaria }; typedef base_complejo* complejo;
127
Una funci on analizadora para un numero complejo es la obtenci on de la parte real del numero: 1 : C R (x, y ) x Para la parte imaginaria del n umero: 2 : C R (x, y ) y En C++: double parte_real(complejo z){ return z->x; }; double parte_imaginaria(complejo z){ return z->y; };
129
complejo modificar_parte_real(complejo z, double x){ z->x = x; return z; }; complejo modificar_parte_imaginaria(complejo z, double y){ z->y = y; return z; };
130
leer complejo : IS C (is) (leer real(is), leer real(is)) En C++ se tiene: double leer_real(istream& is){ double i; is >> i; return i; }; complejo leer_complejo(istream& is){ return crear_complejo(leer_real(is), leer_real(is)); }; Para escribir un TDA, debe escribirse cada uno de los componentes de la estructura en el ujo de datos y retornar el ujo de datos. Se puede denir esta funci on matem aticamente aprovechando la composici on de funciones: escribir A : OS A OS (os, a) escribir An (escribir An1 (...(escribir A1 (os, a1 ), ...)an1 ), an ) En C++: ostream& escribir_A(ostream& os, A a){ return escribir_An(...(escribir_A2(escribir_A_1(os, a_1), a2),...), a_n); }; Para la escritura de un n umero complejo en un ujo se tiene: escribir complejo : OS C OS (os, z ) (escribir real(escribir real(os, x), y ) En C++ (se agrega el codigo de escribir real por comodidad): ostream& escribir_real(ostream& os, double x){ os << x << "\t"; }; ostream& escribir_complejo(ostream& os, complejo z){ return escribir_real(escribir_real(os, z->x), z->y); }; Debe tenerse en cuenta que para mejorar la escritura del tipo de dato la funci on escribir real que se deni o en la parte de ujos de datos escribe un caracter tabulador al nal de cada dato. La declaraci on de esta funci on equivale a:
131
ostream& escribir_complejo(ostream& os, complejo z){ return os << x << "\t" << y << "\t"; };
132
int main(){ complejo z1 = leer_complejo(cin); complejo z2 = leer_complejo(cin); complejo z3 = sumar_complejo(z1, z2); escribir_complejo(cout, z3); liberar_complejo(z1); liberar_complejo(z2); liberar_complejo(z3); system("pause"); return 0; }; Dado el siguiente ujo de entrada de consola dado por un usuario correspondiente a la suma de dos complejos (3, 4i) y (2, 5i), el programa retorna a la salida de consola la suma de dos complejos (1, 1i) como se aprecia a continuaci on:
-3 4 2 -5 -1 -1 Press any key to continue . . . Debe observarse que toda estructura creada despues de utilizarse es liberada en el programa principal.
Cap tulo
13
134
0 0 X= 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
A los objetos de la matriz se les llaman componentes o entradas de la matriz, y para referirse a una componente en particular, a esta se le dice que es la componente en la posici on (i, j ), esto signica que el objeto es la componente ubicada en la la i y en el columna j , se denota por la expresi on Xij y se puede ubicar dentro de la matriz como se muestra a continuaci on
columna j
x11 . .. . . . xi 1 . .. . . . xn1 x1j . . . xij . . . xnj .. . .. . x1m . . . xim . . . xnm
la i
Ejemplo. Para la matriz 3 2 1 0 . 25 e 4 1 2 4 0.0 6 5 X= 1 3 3 3 . 14 2 3 5 10 0 5 0.9 de tama no 4 5 se tiene que sus componentes son: X11 = 2. X12 = 1.
3 X13 = 4 . 1 X21 = 5 . X22 = 2.
X41 =
3 5.
Cuando en una matriz se tiene que el n umero de las es igual al n umero de columnas se dice que la matriz es cuadrada. Ejemplo. La siguiente matriz de tama no 2 2, es una matriz cuadrada cuyas entradas son valores del conjunto booleano (B) X= V F F V
135
Ejemplo. La siguiente matriz de tama no 4 4, es una matriz cuadrada cuyas entradas son n umeros reales, se le conoce como la matriz identidad de tama no 4 4 y se denota por la expresi on I4 1 0 0 0 0 1 0 0 I4 = 0 0 1 0 0 0 0 1
136
A =
mN
Am
A partir del concepto de arreglo y usando la denici on (i) se puede ahora denir el conjunto de las matrices A como la uni on de todos los productos cartesianos del conjunto de los arreglos del conjunto A, de la siguiente manera A
=
nN
Am
mN
El producto externo debe entenderse como un producto cartesiano que genera vectores columna y el interno genera vectores la, as como en la denici on (i). m n Un elemento gen erico del conjunto A es de la forma (A ) , donde n es el n umero de las y m es el n umero de columnas. Para abreviar, de aqu en adelante se utilizar a la notaci on (Am )n Anm .
137
2 2
n . . . n . . .
. . .
2 2 2 2
2 2
2 n . . .
2 2 2 2
. . .
2 2
n2
. . .
2 2 2 2 2 2
. . .
2 2 2
n1
. . .
2 2 2 2 2 2 2 2
. . .
2 2
n
2 2
En C++ se traduce: A** crear_matriz_A(int n, int m){ A** X = new A*[n]; // define un arreglo columna de n componentes for(int i = 0; i < n; i++){ X[i] = new A[m]; // crea y asigna cada arreglo fila de tama~ no m }; return X; }; Ejemplo. Para crear una matriz de tipo entero se tiene la siguiente funci on
138
int** crear_matriz_entero(int n, int m){ int** X = new int*[n]; for(int i = 0; i < n; i++){ X[i] = new int[m]; }; return X; };
13.3.1.2. Liberaci on de matrices Para destruir o liberar una matriz, se realizaran algunas salvedades matem aticas para facilitar la traducci on a lenguaje C++. En este caso para liberar la matriz, se deber a liberar cada uno de los arreglos que conforman la matriz. En este caso para simplicar las cosas se tiene una funci on que retornar a vac o. Lo que se realizar a es liberar el espacio en memoria para que este espacio pueda ser utilizado por otras variables. Matem aticamente se tiene:
M( X )
. . .
2 2 2 2 2 2 2 2
. . . m
2 2
n n
. . .
2 2 2 2 2 2
. . . m
2 2 2
n1
2 2
. . .
. . .
. . .
2 2 2 2
2 2
n2
2 2 2 2
2 2
139
. . .
. . .
2 2
En C++ se traduce:
void liberar_matriz_A(A** X, int n, int m){ for(int i = 0; i < n; i++){ delete[] X[i]; // libera la memoria usada por los n vectores fila }; delete[] X; // libera la memoria usada por el vector columna }; Ejemplo. Para liberar la memoria usada por una matriz de tipo entero se tiene la siguiente funci on void liberar_matriz_entero(int** X, int n, int m){ for(int i = 0; i < n; i++){ delete[] X[i]; }; delete[] X; }; 13.3.1.3. Matrices y ujos de datos Dada una matriz de tipo A, es posible realizar operaciones de lectura y escritura sobre ujos de datos, y dichas operaciones se denen como: Para la entrada de una matriz desde un ujo de datos se tiene: leer matriz A : IS A N N A (is, X, n, m) X, donde
2 3 5 21 13 8
3 5 8 21 13
i = 0, j = 0
i = 0, j = 1
140
3
5 8 13 21
8 13 21
i = 0, j = 2
6
i = 0, j = 3
8 13 21
2 8
13 21
2 8
3 13
i = 1, j = 0
7 8
i = 1, j = 1
21
2 8
2 8
13 21
13 21
i = 1, j = 2
9
i = 1, j = 3
2 8
13 21
i=2
Ejemplo. En C++ para una matriz de tipo entero se tiene (como se mencion o previamente, las matrices en C++ comienzan en la posici on (0, 0)) la siguiente funci on int** leer_matriz_entero(istream& ifs, int** X, int n, int m){ for(int i=0; i < n; i++){ for(int j=0; j < m; j++){ ifs >> X[i][j]; }; }; return X; }; Para enviar una matriz hacia un ujo de datos se tiene:
141
En C++: ostream& escribir_matriz_entera(ostream& ofs, int** X, int n, int m){ ofs << "\n"; for(int i=0; i < n; i++){ for(int j=0; j < m; j++){ ofs << X[i][j]; if(j < m-1){ ofs << "\t"; }; }; ofs << "\n"; }; return ofs; };
2
2 8
2 8
13 21
13 21
2
i = 0, j = 0
4
2 8
2 8
2
13 21
13 21
3 2
i = 0, j = 0
5
i = 0, j = 1
6
2 8
2 8
3 2
2 5 3
13 21
13 21
i = 0, j = 1
i = 0, j = 2
142
2 8
5
2 5
3
2 8
5
2
3 8 5
13 21
i=0
13 21
i = 1, j = 0
10
2 8
5
2
3
2 8
2 13 3 5 8
13 21
13 21
i = 1, j = 0
11
8 5
i = 1, j = 1
12
2 8
2 3 13 5
2 8
2 3 21 5 8 13
13 21
13 21
i = 1, j = 1
13
i = 1, j = 2
14
2 8
5
3
5 8
13 21
i=1
21
13
2 3 5 8 13 21
2 8
3 13
5 21
143
int** tablas_mult(int** X, int n, int m){ for(int i = 1; i <= n; i++){ for(int j = 1; j <= m; j++){ X[i-1][j-1] = i * j; }; }; return X; };
Ejemplo. Determinantes 2 2 Dado un sistema de ecuaciones de dos ecuaciones con dos inc ognitas ax + by = c ax+by =c este sistema de ecuaciones se puede expresar mediante matrices de la siguiente manera a b a b x c = c y
una soluci on del sistema es una pareja (x0 , y0 ) tal que ax0 + by0 = c y a x0 + b y 0 = c .
El sistema tiene una soluci on u nica si la expresi on a b a b = 0, a dicha expresi on se le conoce como el determinante de la matriz, y efectivamente sirve para determinar si un sistema tiene una u nica soluci on, o si no tiene, o si no es u nica. A continuaci on se presenta una funci on que permite calcular el determinante de una matriz 2 2. det 2 2 : R22 R X X11 X22 X21 X12 En C++:
Ejemplo. Producto escalar Una de los operaciones b asicas sobre las matrices es el producto escalar. En este se elige un valor sobre un campo (por ejemplo los reales R) y se multiplica este valor por cada componente de la matriz.
144
x11 x12 x1m x21 x22 x2m As , si R y X = . . . .. . . . . . . . xn1 xn2 xnm entonces x11 x12 x1m x11 x12 x1m x21 x22 x2m x21 x22 x2m Y =X = . = . . . . . .. .. . . . . . . . . . . . . . . xn1 xn2 xnm xn1 xn2 xnm La denici on de esta funci on ser a formalmente producto escalar : R R N N R (, X, n, m) Y, donde Yij = Xij , i = 1, 2, . . . , n, j = 1, 2, . . . , m En C++: double** producto_escalar(double alpha, double** X, int n, int m){ double** Y = crear_matriz_double(n,m); for(int i = 0; i < n; i++){ for(int j = 0; j < m; j++){ Y[i][j] = alpha*X[i][j]; }; }; return X; };
145
Ejercicios
1. Desarrollar un algoritmo que permita hallar el vector soluci on de un sistema de dos ecuaciones con dos inc ognitas, utilizando la regla de Cramer. 2. Desarrollar un algoritmo que permita hallar la matriz inversa de una matriz 2 2, si esta existe. 3. Desarrollar un algoritmo que permita calcular el determinante de una matriz 3 3, utilizando la regla de Sarrus. 4. Desarrollar un algoritmo que permita hallar el vector soluci on de un sistema de tres ecuaciones con tres inc ognitas, utilizando la regla de Cramer. 5. Desarrollar un algoritmo que permita calcular la traza de una matriz cuadrada. 6. Desarrollar un programa que sume los elementos de una columna dada de una matriz. 7. Desarrollar un programa que sume los elementos de una la dada de una matriz. 8. Desarrollar un algoritmo que permita sumar dos matrices de n umeros reales. 9. Desarrollar un algoritmo que permita hallar la transpuesta de una matriz. 10. Desarrollar un algoritmo que permita multiplicar dos matrices de n umeros reales. 11. Desarrollar un algoritmo que determine si una matriz es m agica. Se dice que una matriz cuadrada es m agica si la suma de cada una de sus las, de cada una de sus columnas y de cada diagonal es igual. Ejemplo: 8 1 6 3 5 7 4 9 2 12. Desarrollar un algoritmo que dado un entero, reemplace en una matriz todos los n umeros mayores al n umero dado por un uno y todos los menores o iguales por un cero. Si el n umero dado es: 5 y una matriz en 8 3 4 La matriz de salida es: el arreglo es: 1 6 5 7 9 2
1 0 1 0 0 1 0 1 0
146
13. Desarrollar un programa que genere una matriz marco cuadrada de tama no n n. Entrada: n = 3 1 1 1 1 0 1 1 1 1
14. Desarrollar un programa que tome un arreglo de tama no n2 y llene en espiral hacia adentro una matriz cuadrada de tama no n. Ejemplo: arreglo de entrada: [1, 2, 3, 4, 5, 6, 7, 8, 9], la matriz de salida es: 1 2 3 8 9 4 7 6 5 15. Desarrollar un algoritmo que permita resolver un sistema de n ecuaciones con n inc ognitas, usando el m etodo de eliminaci on de Gauss-Jordan. 16. Desarrollar un algoritmo que permita hallar la matriz inversa de una matriz cuadrada, si esta existe. 17. Desarrollar un algoritmo que permita calcular el determinante de una matriz cuadrada, usando el teorema de Laplace (desarrollo por menores y cofactores).
Bibliograf a
Alpuente, M. & Iranzo, P. J. [2007]. Programaci on l ogica: teor a y pr actica, Pearson Educaci on. Deitel, H. M. & Deitel, P. J. [2004]. C omo programar en C, C++ y Java, Pearson Educaci on. Iranzo, P. J. [2005]. L ogica simb olica para inform aticos, Alfaomega. Johnsonbaugh, R. [2005]. Matem aticas Discretas, 6a edn, Pearson. Kleene, S. [1952]. Introduction to Metamathematics, North-Holland, Amsterdam. Kolman, B., Busby, R. C. & Ross, S. [1997]. Estructuras de matem aticas discretas para la computaci on, Pearson educaci on, Prentice-Hall Hispanoamericana. Rosen, K. H. [2004]. Matem atica discreta y sus aplicaciones, McGraw-Hill. Savitch, W. A. [2000]. Resolucion de problemas Con C++, 2nd edn, Pearson Educaci on, M exico.
147