SlideShare una empresa de Scribd logo
1 de 102
Descargar para leer sin conexión
A nuestros compa˜eros y alumnos
                n
´
Indice


Presentaci´n
          o                                                                          xix


Tema I       Algoritmos e introducci´n a Pascal
                                    o                                                 1

Cap´
   ıtulo 1      Problemas, algoritmos y programas                                     3
  1.1   Soluci´n de problemas mediante programas . . . . . . . . . . . .
              o                                                                        3
  1.2   Concepto de algoritmo . . . . . . . . . . . . . . . . . . . . . . . .          5
        1.2.1    Una definici´n de algoritmo . . . . . . . . . . . . . . . . .
                            o                                                          6
        1.2.2    Una definici´n formal de algoritmo . . . . . . . . . . . . .
                            o                                                          8
  1.3   Aspectos de inter´s sobre los algoritmos . . . . . . . . . . . . . .
                         e                                                            11
        1.3.1    Computabilidad . . . . . . . . . . . . . . . . . . . . . . .         11
        1.3.2    Correcci´n de algoritmos
                         o                     . . . . . . . . . . . . . . . . . .    14
        1.3.3    Complejidad de algoritmos . . . . . . . . . . . . . . . . .          15
  1.4   Lenguajes algor´
                       ıtmicos y de programaci´n . . . . . . . . . . . . .
                                              o                                       16
  1.5   Desarrollo sistem´tico de programas . . . . . . . . . . . . . . . .
                         a                                                            18
  1.6   Conclusi´n
                o      . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .    20
  1.7   Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .      20
  1.8   Referencias bibliogr´ficas
                            a          . . . . . . . . . . . . . . . . . . . . . .    21

Cap´
   ıtulo 2      El lenguaje de programaci´n Pascal
                                         o                                           23
  2.1   Introducci´n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
                  o                                                                   23
  2.2   Otros detalles de inter´s . . . . . . . . . . . . . . . . . . . . . . .
                               e                                                      24
  2.3   Origen y evoluci´n del lenguaje Pascal . . . . . . . . . . . . . . .
                        o                                                             24
  2.4   Pascal y Turbo Pascal . . . . . . . . . . . . . . . . . . . . . . . .         25

Cap´
   ıtulo 3      Tipos de datos b´sicos
                                a                                                    27
  3.1   Introducci´n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
                  o                                                                   28
viii                                                                                ´
                                                                                    Indice

       3.2   El tipo integer . . . . . . . . . . . . . . . . . . . . . . . . . . . .     28
       3.3   El tipo real . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .    32
       3.4   El tipo char . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .    35
       3.5   El tipo boolean . . . . . . . . . . . . . . . . . . . . . . . . . . . .     36
       3.6   Observaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . .     39
       3.7   El tipo de una expresi´n . . . . . . . . . . . . . . . . . . . . . . .
                                   o                                                     43
       3.8   Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .    43

   ıtulo 4
Cap´                 Elementos b´sicos del lenguaje
                                a                                                        47
       4.1   Un ejemplo introductorio . . . . . . . . . . . . . . . . . . . . . .        47
       4.2   Vocabulario b´sico . . . . . . . . . . . . . . . . . . . . . . . . . .
                          a                                                              48
             4.2.1    Constantes y variables . . . . . . . . . . . . . . . . . . . .     52
       4.3   Instrucciones b´sicas . . . . . . . . . . . . . . . . . . . . . . . . .
                            a                                                            52
             4.3.1    Asignaci´n . . . . . . . . . . . . . . . . . . . . . . . . . .
                              o                                                          52
             4.3.2    Instrucciones de escritura . . . . . . . . . . . . . . . . . .     54
             4.3.3    Instrucciones de lectura . . . . . . . . . . . . . . . . . . .     57
       4.4   Partes de un programa . . . . . . . . . . . . . . . . . . . . . . . .       59
             4.4.1    Encabezamiento . . . . . . . . . . . . . . . . . . . . . . .       59
             4.4.2    Declaraciones y definiciones . . . . . . . . . . . . . . . . .      60
             4.4.3    Cuerpo del programa . . . . . . . . . . . . . . . . . . . . .      62
             4.4.4    Conclusi´n: estructura general de un programa . . . . . .
                              o                                                          63
       4.5   Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .    63

Cap´
   ıtulo 5           Primeros programas completos                                        67
       5.1   Algunos programas sencillos . . . . . . . . . . . . . . . . . . . . .       68
             5.1.1    Dibujo de la letra ‘‘C’’ . . . . . . . . . . . . . . . . . . . .   68
             5.1.2    Suma de dos n´meros . . . . . . . . . . . . . . . . . . . .
                                   u                                                     69
       5.2   Programas claros ⇒ programas de calidad . . . . . . . . . . . . .           69
       5.3   Desarrollo descendente de programas . . . . . . . . . . . . . . . .         71
       5.4   Desarrollo de programas correctos . . . . . . . . . . . . . . . . .         73
             5.4.1    Estado de los c´mputos . . . . . . . . . . . . . . . . . . .
                                     o                                                   73
             5.4.2    Desarrollo descendente con especificaciones . . . . . . . .         78
       5.5   Observaciones finales . . . . . . . . . . . . . . . . . . . . . . . . .      79
       5.6   Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .    81
´
Indice                                                                              ix

Tema II      Programaci´n estructurada
                       o                                                           83

Cap´
   ıtulo 6       Instrucciones estructuradas                                       85
  6.1    Composici´n de instrucciones . . . . . . . . . . . . . . . . . . . .
                  o                                                                 86
  6.2    Instrucciones de selecci´n . . . . . . . . . . . . . . . . . . . . . .
                                 o                                                  88
         6.2.1    La instrucci´n if-then-else . . . . . . . . . . . . . . . . .
                              o                                                     88
         6.2.2    La instrucci´n case . . . . . . . . . . . . . . . . . . . . .
                              o                                                     92
  6.3    Instrucciones de iteraci´n . . . . . . . . . . . . . . . . . . . . . .
                                 o                                                  94
         6.3.1    La instrucci´n while . . . . . . . . . . . . . . . . . . . . .
                              o                                                     94
         6.3.2    La instrucci´n repeat . . . . . . . . . . . . . . . . . . . .
                              o                                                     98
         6.3.3    La instrucci´n for . . . . . . . . . . . . . . . . . . . . . . 100
                              o
  6.4    Dise˜o y desarrollo de bucles . . . . . . . . . . . . . . . . . . . . 103
             n
         6.4.1    Elecci´n de instrucciones iterativas . . . . . . . . . . . . . 103
                        o
         6.4.2    Terminaci´n de un bucle . . . . . . . . . . . . . . . . . . . 105
                           o
         6.4.3    Uso correcto de instrucciones estructuradas . . . . . . . . 106
  6.5    Dos m´todos num´ricos iterativos . . . . . . . . . . . . . . . . . . 113
              e         e
         6.5.1    M´todo de bipartici´n . . . . . . . . . . . . . . . . . . . . 113
                   e                 o
         6.5.2    M´todo de Newton-Raphson . . . . . . . . . . . . . . . . 115
                   e
         6.5.3    Inversi´n de funciones . . . . . . . . . . . . . . . . . . . . 117
                         o
  6.6    Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117

Cap´
   ıtulo 7       Programaci´n estructurada
                           o                                                       123
  7.1    Introducci´n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
                   o
  7.2    Aspectos te´ricos . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
                    o
         7.2.1    Programas y diagramas de flujo . . . . . . . . . . . . . . . 125
         7.2.2    Diagramas y diagramas propios . . . . . . . . . . . . . . . 126
         7.2.3    Diagramas BJ (de B¨hm y Jacopini) . . . . . . . . . . . . 130
                                    o
         7.2.4    Equivalencia de diagramas . . . . . . . . . . . . . . . . . . 135
         7.2.5    Teoremas de la programaci´n estructurada . . . . . . . . 137
                                           o
         7.2.6    Recapitulaci´n . . . . . . . . . . . . . . . . . . . . . . . . 138
                              o
  7.3    Aspectos metodol´gicos . . . . . . . . . . . . . . . . . . . . . . . 139
                         o
         7.3.1    Seudoc´digo . . . . . . . . . . . . . . . . . . . . . . . . . . 139
                        o
         7.3.2    Dise˜o descendente . . . . . . . . . . . . . . . . . . . . . . 141
                      n
  7.4    Refinamiento correcto de programas con instrucciones
         estructuradas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
x                                                                               ´
                                                                                Indice

          7.4.1    Un ejemplo detallado     . . . . . . . . . . . . . . . . . . . . 147
          7.4.2    Recapitulaci´n . . . . . . . . . . . . . . . . . . . . . . . . 150
                               o
    7.5   Conclusi´n
                  o      . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
    7.6   Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
    7.7   Referencias bibliogr´ficas
                              a         . . . . . . . . . . . . . . . . . . . . . . 153


Tema III          Subprogramas                                                     155

Cap´
   ıtulo 8        Procedimientos y funciones                                       157
    8.1   Introducci´n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
                    o
    8.2   Subprogramas con par´metros . . . . . . . . . . . . . . . . . . . . 162
                              a
          8.2.1    Descripci´n de un subprograma con par´metros . . . . . . 162
                            o                           a
          8.2.2    Par´metros formales y reales . . . . . . . . . . . . . . . . 165
                      a
          8.2.3    Mecanismos de paso de par´metros . . . . . . . . . . . . . 165
                                            a
          8.2.4    Consistencia entre definici´n y llamada
                                             o                 . . . . . . . . . . 168
    8.3   Estructura sint´ctica de un subprograma . . . . . . . . . . . . . . 169
                         a
    8.4   Funcionamiento de una llamada . . . . . . . . . . . . . . . . . . . 170
    8.5   ´
          Ambito y visibilidad de los identificadores . . . . . . . . . . . . . 174
          8.5.1    Tipos de identificadores seg´n su ´mbito . . . . . . . . . . 174
                                              u     a
          8.5.2    Estructura de bloques . . . . . . . . . . . . . . . . . . . . 175
          8.5.3    Criterios de localidad . . . . . . . . . . . . . . . . . . . . 181
          8.5.4    Efectos laterales . . . . . . . . . . . . . . . . . . . . . . . 181
    8.6   Otras recomendaciones sobre el uso de par´metros . . . . . . . . 183
                                                   a
          8.6.1    Par´metros por valor y por referencia . . . . . . . . . . . 183
                      a
          8.6.2    Par´metros por referencia y funciones . . . . . . . . . . . 183
                      a
          8.6.3    Funciones con resultados m´ltiples . . . . . . . . . . . . . 184
                                             u
    8.7   Desarrollo correcto de subprogramas . . . . . . . . . . . . . . . . 184
    8.8   Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186

Cap´
   ıtulo 9        Aspectos metodol´gicos de la programaci´n con
                                  o                      o
                  subprogramas                                                     189
    9.1   Introducci´n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
                    o
    9.2   Un ejemplo de referencia . . . . . . . . . . . . . . . . . . . . . . . 190
    9.3   Metodolog´ de la programaci´n con subprogramas . . . . . . . . 192
                   ıa                o
          9.3.1    Dise˜o descendente con subprogramas . . . . . . . . . . . 193
                       n
´
Indice                                                                              xi

         9.3.2    Programa principal y subprogramas . . . . . . . . . . . . 194
         9.3.3    Documentaci´n de los subprogramas . . . . . . . . . . . . 195
                             o
         9.3.4    Tama˜o de los subprogramas . . . . . . . . . . . . . . . . 196
                      n
         9.3.5    Refinamiento con subprogramas y con instrucciones
                  estructuradas . . . . . . . . . . . . . . . . . . . . . . . . . 197
  9.4    Estructura jer´rquica de los subprogramas . . . . . . . . . . . . . 199
                       a
  9.5    Ventajas de la programaci´n con subprogramas . . . . . . . . . . 201
                                  o
  9.6    Un ejemplo detallado: representaci´n de funciones . . . . . . . . 203
                                           o
  9.7    Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207

Cap´
   ıtulo 10 Introducci´n a la recursi´n
                      o              o                                           211
  10.1 Un ejemplo de referencia . . . . . . . . . . . . . . . . . . . . . . . 212
  10.2 Conceptos b´sicos . . . . . . . . . . . . . . . . . . . . . . . . . . 213
                  a
  10.3 Otros ejemplos recursivos . . . . . . . . . . . . . . . . . . . . . . 216
         10.3.1 La sucesi´n de Fibonacci . . . . . . . . . . . . . . . . . . 216
                         o
         10.3.2 Torres de Hanoi      . . . . . . . . . . . . . . . . . . . . . . . 216
         10.3.3 Funci´n de Ackermann . . . . . . . . . . . . . . . . . . . . 219
                     o
  10.4 Correcci´n de subprogramas recursivos . . . . . . . . . . . . . . . 219
               o
         10.4.1 Principios de inducci´n . . . . . . . . . . . . . . . . . . . 220
                                     o
  10.5 Recursi´n mutua . . . . . . . . . . . . . . . . . . . . . . . . . . . 222
              o
  10.6 Recursi´n e iteraci´n . . . . . . . . . . . . . . . . . . . . . . . . . 226
              o           o
  10.7 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227
  10.8 Referencias bibliogr´ficas
                           a           . . . . . . . . . . . . . . . . . . . . . . 228


Tema IV          Tipos de datos definidos por el programador                      231

Cap´
   ıtulo 11 Tipos de datos simples y compuestos                                  233
  11.1 Tipos ordinales definidos por el programador . . . . . . . . . . . 234
         11.1.1 Tipos enumerados . . . . . . . . . . . . . . . . . . . . . . 235
         11.1.2 Tipo subrango . . . . . . . . . . . . . . . . . . . . . . . . 238
  11.2 Definici´n de tipos . . . . . . . . . . . . . . . . . . . . . . . . . . 240
              o
         11.2.1 Observaciones sobre la definici´n de tipos . . . . . . . . . 242
                                              o
  11.3 Conjuntos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
         11.3.1 Operaciones sobre el tipo conjunto . . . . . . . . . . . . . 245
         11.3.2 Observaciones sobre el tipo conjunto . . . . . . . . . . . . 247
xii                                                                            ´
                                                                               Indice

           11.3.3 Un ejemplo de aplicaci´n . . . . . . . . . . . . . . . . . . 248
                                        o
      11.4 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250

Cap´
   ıtulo 12 Arrays                                                                253
      12.1 Descripci´n del tipo de datos array . . . . . . . . . . . . . . . . . 253
                    o
           12.1.1 Operaciones del tipo array y acceso a sus componentes . . 257
           12.1.2 Caracter´
                          ısticas generales de un array . . . . . . . . . . . . 260
      12.2 Vectores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261
      12.3 Matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
      12.4 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268

   ıtulo 13 Registros
Cap´                                                                              271
      13.1 Descripci´n del tipo de datos registro . . . . . . . . . . . . . . . . 271
                    o
           13.1.1 Manejo de registros: acceso a componentes y operaciones . 273
           13.1.2 Registros con variantes . . . . . . . . . . . . . . . . . . . . 276
      13.2 Arrays de registros y registros de arrays . . . . . . . . . . . . . . 279
      13.3 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282

Cap´
   ıtulo 14 Archivos                                                              285
      14.1 Descripci´n del tipo de datos archivo . . . . . . . . . . . . . . . . 285
                    o
      14.2 Manejo de archivos en Pascal . . . . . . . . . . . . . . . . . . . . 286
           14.2.1 Operaciones con archivos . . . . . . . . . . . . . . . . . . 288
      14.3 Archivos de texto . . . . . . . . . . . . . . . . . . . . . . . . . . . 294
      14.4 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298

Cap´
   ıtulo 15 Algoritmos de b´ squeda y ordenaci´n
                           u                  o                                   301
      15.1 Algoritmos de b´squeda en arrays . . . . . . . . . . . . . . . . . 301
                          u
           15.1.1 B´squeda secuencial . . . . . . . . . . . . . . . . . . . . . 302
                   u
           15.1.2 B´squeda secuencial ordenada
                   u                                  . . . . . . . . . . . . . . . 304
           15.1.3 B´squeda binaria . . . . . . . . . . . . . . . . . . . . . . . 304
                   u
      15.2 Ordenaci´n de arrays . . . . . . . . . . . . . . . . . . . . . . . . . 306
                   o
           15.2.1 Selecci´n directa . . . . . . . . . . . . . . . . . . . . . . . 307
                         o
           15.2.2 Inserci´n directa . . . . . . . . . . . . . . . . . . . . . . . 309
                         o
           15.2.3 Intercambio directo . . . . . . . . . . . . . . . . . . . . . . 310
           15.2.4 Ordenaci´n r´pida (Quick Sort) . . . . . . . . . . . . . . 312
                          o a
           15.2.5 Ordenaci´n por mezcla (Merge Sort) . . . . . . . . . . . . 316
                          o
´
Indice                                                                           xiii

         15.2.6 Vectores paralelos . . . . . . . . . . . . . . . . . . . . . . 318
  15.3 Algoritmos de b´squeda en archivos secuenciales . . . . . . . . . 320
                      u
         15.3.1 B´squeda en archivos arbitrarios . . . . . . . . . . . . . . 321
                 u
         15.3.2 B´squeda en archivos ordenados . . . . . . . . . . . . . . 321
                 u
  15.4 Mezcla y ordenaci´n de archivos secuenciales . . . . . . . . . . . 322
                        o
  15.5 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329
  15.6 Referencias bibliogr´ficas
                           a          . . . . . . . . . . . . . . . . . . . . . . 330


Tema V       Memoria din´mica
                        a                                                       333

Cap´
   ıtulo 16 Punteros                                                            335
  16.1 Introducci´n al uso de punteros . . . . . . . . . . . . . . . . . . . 336
                 o
         16.1.1 Definici´n y declaraci´n de punteros . . . . . . . . . . . . 337
                       o             o
         16.1.2 Generaci´n y destrucci´n de variables din´micas . . . . . 338
                        o             o                  a
         16.1.3 Operaciones b´sicas con datos apuntados . . . . . . . . . 339
                             a
         16.1.4 Operaciones b´sicas con punteros . . . . . . . . . . . . . . 341
                             a
         16.1.5 El valor nil . . . . . . . . . . . . . . . . . . . . . . . . . . 343
  16.2 Aplicaciones no recursivas de los punteros . . . . . . . . . . . . . 344
         16.2.1 Asignaci´n de objetos no simples . . . . . . . . . . . . . . 345
                        o
         16.2.2 Funciones de resultado no simple . . . . . . . . . . . . . . 346
  16.3 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348

Cap´
   ıtulo 17 Estructuras de datos recursivas                                     351
  17.1 Estructuras recursivas lineales: las listas enlazadas . . . . . . . . 351
         17.1.1 Una definici´n del tipo lista . . . . . . . . . . . . . . . . . 352
                           o
         17.1.2 Inserci´n de elementos . . . . . . . . . . . . . . . . . . . . 353
                       o
         17.1.3 Eliminaci´n de elementos . . . . . . . . . . . . . . . . . . 355
                         o
         17.1.4 Algunas funciones recursivas . . . . . . . . . . . . . . . . 355
         17.1.5 Otras operaciones sobre listas . . . . . . . . . . . . . . . . 358
  17.2 Pilas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362
         17.2.1 Definici´n de una pila como lista enlazada . . . . . . . . . 363
                       o
         17.2.2 Operaciones b´sicas sobre las pilas . . . . . . . . . . . . . 363
                             a
         17.2.3 Aplicaciones . . . . . . . . . . . . . . . . . . . . . . . . . . 365
  17.3 Colas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370
         17.3.1 Definici´n del tipo cola
                       o                   . . . . . . . . . . . . . . . . . . . 371
xiv                                                                            ´
                                                                               Indice

           17.3.2 Operaciones b´sicas . . . . . . . . . . . . . . . . . . . . . 371
                               a
           17.3.3 Aplicaci´n: gesti´n de la caja de un supermercado . . . . 374
                          o        o
           ´
      17.4 Arboles binarios . . . . . . . . . . . . . . . . . . . . . . . . . . . 376
           17.4.1 Recorrido de un ´rbol binario . . . . . . . . . . . . . . . . 378
                                  a
                  ´
           17.4.2 Arboles de b´squeda . . . . . . . . . . . . . . . . . . . . . 379
                              u
           17.4.3 Aplicaciones . . . . . . . . . . . . . . . . . . . . . . . . . . 383
      17.5 Otras estructuras din´micas de datos . . . . . . . . . . . . . . . . 387
                                a
      17.6 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389
      17.7 Referencias bibliogr´ficas
                               a        . . . . . . . . . . . . . . . . . . . . . . 391


Tema VI          Aspectos avanzados de programaci´n
                                                 o                                393

Cap´
   ıtulo 18 Complejidad algor´
                             ıtmica                                               395
      18.1 Conceptos b´sicos . . . . . . . . . . . . . . . . . . . . . . . . . . 396
                      a
      18.2 Medidas del comportamiento asint´tico . . . . . . . . . . . . . . 402
                                           o
           18.2.1 Comportamiento asint´tico . . . . . . . . . . . . . . . . . 402
                                      o
           18.2.2 Notaci´n O may´scula (una cota superior)
                        o       u                                  . . . . . . . . 404
           18.2.3 Notaci´n Ω may´scula (una cota inferior) . . . . . . . . . 405
                        o       u
           18.2.4 Notaci´n Θ may´scula (orden de una funci´n) . . . . . . 405
                        o       u                         o
           18.2.5 Propiedades de O, Ω y Θ . . . . . . . . . . . . . . . . . . 406
           18.2.6 Jerarqu´ de ´rdenes de frecuente aparici´n . . . . . . . . 407
                         ıa   o                           o
      18.3 Reglas pr´cticas para hallar el coste de un programa . . . . . . . 408
                    a
           18.3.1 Tiempo empleado       . . . . . . . . . . . . . . . . . . . . . . 408
           18.3.2 Ejemplos . . . . . . . . . . . . . . . . . . . . . . . . . . . 411
           18.3.3 Espacio de memoria empleado . . . . . . . . . . . . . . . 417
           ´
      18.4 Utiles matem´ticos . . . . . . . . . . . . . . . . . . . . . . . . . . 418
                       a
           18.4.1 F´rmulas con sumatorios . . . . . . . . . . . . . . . . . . 419
                   o
           18.4.2 Sucesiones de recurrencia lineales de primer orden . . . . 419
           18.4.3 Sucesiones de recurrencia de orden superior . . . . . . . . 421
      18.5 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 422
      18.6 Referencias bibliogr´ficas
                               a        . . . . . . . . . . . . . . . . . . . . . . 425

Cap´
   ıtulo 19 Tipos abstractos de datos                                             427
      19.1 Introducci´n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 428
                     o
      19.2 Un ejemplo completo . . . . . . . . . . . . . . . . . . . . . . . . . 429
´
Indice                                                                           xv

         19.2.1 Desarrollo de programas con tipos concretos de datos . . 430
         19.2.2 Desarrollo de programas con tipos abstractos de datos . . 431
         19.2.3 Desarrollo de tipos abstractos de datos . . . . . . . . . . . 434
  19.3 Metodolog´ de la programaci´n de TADs . . . . . . . . . . . . . 440
                ıa                o
         19.3.1 Especificaci´n de tipos abstractos de datos . . . . . . . . 440
                           o
         19.3.2 Implementaci´n de tipos abstractos de datos . . . . . . . 441
                            o
         19.3.3 Correcci´n de tipos abstractos de datos . . . . . . . . . . 443
                        o
  19.4 Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 446
  19.5 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 447
  19.6 Referencias bibliogr´ficas
                           a         . . . . . . . . . . . . . . . . . . . . . . 448

Cap´
   ıtulo 20 Esquemas algor´
                          ıtmicos fundamentales                                449
  20.1 Algoritmos devoradores . . . . . . . . . . . . . . . . . . . . . . . 450
         20.1.1 Descripci´n . . . . . . . . . . . . . . . . . . . . . . . . . . 450
                         o
         20.1.2 Adecuaci´n al problema . . . . . . . . . . . . . . . . . . . 451
                        o
         20.1.3 Otros problemas resueltos vorazmente . . . . . . . . . . . 452
  20.2 Divide y vencer´s . . . . . . . . . . . . . . . . . . . . . . . . . . . 453
                      a
         20.2.1 Equilibrado de los subproblemas . . . . . . . . . . . . . . 454
  20.3 Programaci´n din´mica . . . . . . . . . . . . . . . . . . . . . . . 455
                 o     a
         20.3.1 Problemas de programaci´n din´mica . . . . . . . . . . . 455
                                       o     a
         20.3.2 Mejora de este esquema . . . . . . . . . . . . . . . . . . . 457
         20.3.3 Formulaci´n de problemas de programaci´n din´mica . . 460
                         o                            o     a
  20.4 Vuelta atr´s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462
                 a
         20.4.1 Mejora del esquema de vuelta atr´s
                                                a       . . . . . . . . . . . . 466
  20.5 Anexo: algoritmos probabilistas . . . . . . . . . . . . . . . . . . . 468
         20.5.1 B´squeda de una soluci´n aproximada . . . . . . . . . . . 468
                 u                    o
         20.5.2 B´squeda de una soluci´n probablemente correcta . . . . 469
                 u                    o
  20.6 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 470
  20.7 Referencias bibliogr´ficas
                           a         . . . . . . . . . . . . . . . . . . . . . . 473


Ap´ndices
  e                                                                            475

Ap´ndice A Aspectos complementarios de la programaci´n
  e                                                 o                          477
  A.1 Subprogramas como par´metros . . . . . . . . . . . . . . . . . . . 477
                           a
         A.1.1 Ejemplo 1: derivada . . . . . . . . . . . . . . . . . . . . . 479
xvi                                                                            ´
                                                                               Indice

           A.1.2 Ejemplo 2: bipartici´n . . . . . . . . . . . . . . . . . . . . 480
                                     o
           A.1.3 Ejemplo 3: transformaci´n de listas . . . . . . . . . . . . 482
                                        o
      A.2 Variables aleatorias . . . . . . . . . . . . . . . . . . . . . . . . . . 482
           A.2.1 Generaci´n de n´meros aleatorios en Turbo Pascal . . . . 483
                         o      u
           A.2.2 Simulaci´n de variables aleatorias . . . . . . . . . . . . . . 484
                         o
           A.2.3 Ejemplos de aplicaci´n . . . . . . . . . . . . . . . . . . . . 486
                                     o
      A.3 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 488
      A.4 Referencias bibliogr´ficas
                              a         . . . . . . . . . . . . . . . . . . . . . . 490

Ap´ndice B El lenguaje Turbo Pascal
  e                                                                               491
      B.1 Elementos l´xicos . . . . . . . . . . . . . . . . . . . . . . . . . . . 492
                     e
      B.2 Estructura del programa . . . . . . . . . . . . . . . . . . . . . . . 492
      B.3 Datos num´ricos enteros . . . . . . . . . . . . . . . . . . . . . . . 492
                   e
      B.4 Datos num´ricos reales . . . . . . . . . . . . . . . . . . . . . . . . 493
                   e
      B.5 Cadenas de caracteres . . . . . . . . . . . . . . . . . . . . . . . . 494
           B.5.1 Declaraci´n de cadenas . . . . . . . . . . . . . . . . . . . 494
                          o
           B.5.2 Operadores de cadenas . . . . . . . . . . . . . . . . . . . . 495
           B.5.3 Funciones de cadenas       . . . . . . . . . . . . . . . . . . . . 496
           B.5.4 Procedimientos de cadenas . . . . . . . . . . . . . . . . . 496
      B.6 Tipos de datos estructurados . . . . . . . . . . . . . . . . . . . . 498
      B.7 Instrucciones estructuradas . . . . . . . . . . . . . . . . . . . . . 498
      B.8 Paso de subprogramas como par´metros . . . . . . . . . . . . . . 499
                                       a
      B.9 Archivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 500
      B.10 Memoria din´mica . . . . . . . . . . . . . . . . . . . . . . . . . . 501
                      a
      B.11 Unidades . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 501
           B.11.1 Unidades predefinidas de Turbo Pascal . . . . . . . . . . . 502
           B.11.2 Unidades definidas por el usuario . . . . . . . . . . . . . . 503
           B.11.3 Modularidad incompleta de Turbo Pascal . . . . . . . . . 505

Ap´ndice C El entorno integrado de desarrollo
  e                                                                               507
      C.1 Descripci´n del entorno . . . . . . . . . . . . . . . . . . . . . . . 507
                   o
      C.2 Desarrollo completo de un programa en Turbo Pascal          . . . . . . 508
           C.2.1 Arranque del entorno . . . . . . . . . . . . . . . . . . . . 508
           C.2.2 Edici´n del programa fuente . . . . . . . . . . . . . . . . . 510
                      o
           C.2.3 Grabar el programa fuente y seguir editando . . . . . . . 510
´
Indice                                                                          xvii

         C.2.4 Compilaci´n
                        o      . . . . . . . . . . . . . . . . . . . . . . . . . 512
         C.2.5 Ejecuci´n . . . . . . . . . . . . . . . . . . . . . . . . . . . 514
                      o
         C.2.6 Depuraci´n . . . . . . . . . . . . . . . . . . . . . . . . . . 514
                       o
         C.2.7 Salida de Turbo Pascal . . . . . . . . . . . . . . . . . . . . 516
  C.3 Otros men´s y opciones . . . . . . . . . . . . . . . . . . . . . . . 517
               u
         C.3.1 Search (B´squeda) . . . . . . . . . . . . . . . . . . . . . . 517
                        u
         C.3.2 Tools (Herramientas) . . . . . . . . . . . . . . . . . . . . . 517
         C.3.3 Options (Opciones) . . . . . . . . . . . . . . . . . . . . . . 517
         C.3.4 Window (Ventana) . . . . . . . . . . . . . . . . . . . . . . 519
         C.3.5 Help (Ayuda) . . . . . . . . . . . . . . . . . . . . . . . . . 519
  C.4 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 519
  C.5 Referencias bibliogr´ficas
                          a          . . . . . . . . . . . . . . . . . . . . . . 520


Bibliograf´
          ıa                                                                   521


´
Indice alfab´tico
            e                                                                  527
Presentaci´n
          o


    Este libro trata sobre m´todos de resoluci´n de problemas mediante el desa-
                             e                  o
rrollo de algoritmos y estructuras de datos, desde el principio y paso a paso, y
su materializaci´n en programas de computador.
                 o
    Desde luego, no es el primer libro sobre este tema; de hecho, ha habido
en los ultimos quince a˜os un gran aluvi´n de textos sobre algoritmos y sobre
        ´                n                  o
programaci´n. La raz´n para ello ha sido sin lugar a dudas doble: por un
            o           o
lado, la difusi´n que estos temas han tenido y siguen teniendo, integr´ndose
               o                                                            a
en los estudios m´s diversos; por otro, la evoluci´n que est´ experimentando el
                   a                               o           a
desarrollo de algoritmos y programas, pasando de ser un arte (reinventado por
cada programador a base de t´cnicas personales, estrechamente vinculadas con
                                e
su lenguaje de programaci´n) a una actividad m´s cient´
                            o                        a        ıfica, metodol´gica y
                                                                           o
disciplinada.
    Por consiguiente, resulta necesario aclarar cu´l es el enfoque adoptado en este
                                                  a
libro. Examinando la bibliograf´ existente actualmente sobre programaci´n a
                                  ıa                                          o
un nivel introductorio permite afirmar las siguientes conclusiones:
   • Una parte importante de los libros existentes han adoptado un enfoque
     pr´ctico puro, no metodol´gico, que es el m´s tradicional, y a´n subsiste
       a                       o                   a                u
     en demasiados libros. Se confunde la ense˜anza de la programaci´n con
                                                 n                      o
     la de un lenguaje concreto, ofreciendo muchas veces un mero “manual
     de referencia” del lenguaje elegido. Bajo el atractivo de los llamativos
     resultados inmediatos (programas que funcionan), este enfoque ignora la
     base conceptual y metodol´gica necesaria, y propicia los peores h´bitos de
                               o                                      a
     programaci´n, que son adem´s dif´
                o                a     ıciles de erradicar.
   • Otra postura extrema se centra en el an´lisis y desarrollo de soluciones
                                                 a
     algor´ıtmicas puras, de forma independiente de cualquier lenguaje de pro-
     gramaci´n. Esta independencia permite ignorar las peculiaridades de los
              o
     lenguajes reales, yendo a los conceptos; sin embargo, esa independencia de
     los lenguajes de programaci´n es a nuestro entender innecesaria e inconve-
                                 o
     niente en los primeros pasos, ya que obliga al aprendiz de la programaci´n
                                                                             o
     a estudiar aparte los detalles concretos del lenguaje de programaci´n con
                                                                         o
     que necesariamente debe desarrollar sus pr´cticas.
                                                  a
xx                                                                          ´
                                                                  Presentacion

       En cambio, encontramos este enfoque interesante en niveles superiores de
       la ense˜anza de la programaci´n, donde interesa concentrarse en los con-
              n                       o
       ceptos, m´s dif´
                 a    ıciles y donde ya no supone obst´culo alguno expresar las
                                                      a
       ideas en cualquier lenguaje de programaci´n.
                                                o

    El enfoque adoptado en este libro recoge ambos aspectos: por un lado, viene a
cubrir la necesidad de un enfoque metodol´gico en el aprendizaje y en el ejercicio
                                           o
de la programaci´n, pero tambi´n la necesidad de experimentar con programas
                   o            e
concretos, expresarlos en un lenguaje real y hacerlos funcionar con un traduc-
tor concreto. En resumen, intentamos compaginar las ventajas de los enfoques
anteriores, presentando la base conceptual y metodol´gica necesaria para desa-
                                                      o
rrollar los algoritmos de forma razonada y disciplinada, sin olvidar por ello la
conveniencia de expresarlos en un lenguaje de programaci´n, materializ´ndolos
                                                           o              a
y experimentando con ellos, y que el lector ha de ser instruido tambi´n en esta
                                                                      e
tarea.
    En relaci´n con el enfoque metodol´gico que se impone actualmente, se con-
             o                         o
sidera necesario atender a la correcci´n de los programas. El tratamiento que
                                      o
se le da en la literatura ha llevado nuevamente a dos posturas artificialmente
extremas:

     • Algunos autores ignoran completamente el estudio de la correcci´n, con-
                                                                      o
       tent´ndose con algunas comprobaciones para deducir que un programa es
           a
       correcto.

     • En cambio, otros adoptan un tratamiento exhaustivo, utilizando t´cnicas
                                                                       e
       formales de especificaci´n o verificaci´n.
                              o             o

    A nuestro entender, es incuestionable la importancia de garantizar que los
programas desarrollados funcionar´n de la forma deseada. Sin embargo, la ve-
                                  a
rificaci´n formal de los programas de cierto tama˜o es impracticable. Por ello,
       o                                         n
asumimos de nuevo una posici´n intermedia y realista consistente en los siguien-
                              o
tes planteamientos:

     • Plantear el desarrollo de programas correctos con el empleo de t´cnicas
                                                                       e
       semiformales.

     • Limitar el estudio de la correcci´n a los elementos que resulten delicados,
                                        o
       bien por su dificultad o por su novedad.

     • Atender a la correcci´n de los algoritmos durante su desarrollo en lugar de
                            o
       a posteriori. Esta idea resulta ser una ayuda esencial en el aprendizaje de
       la programaci´n.
                     o
´
Presentacion                                                                   xxi

    En resumidas cuentas, este libro va dirigido a aqu´llos que desean introdu-
                                                       e
cirse en la programaci´n, con una base s´lida, con una buena metodog´ de
                        o                  o                               ıa
dise˜o y desarrollo de programas correctos y con h´bitos disciplinados desde una
    n                                             a
perspectiva realista y pragm´tica. Se presentan las t´cnicas con un cierto ni-
                             a                         e
vel de abstracci´n para identificar los conceptos esenciales e independientes del
                o
lenguaje de programaci´n empleado, y al mismo tiempo se aterriza expresando
                        o
estas t´cnicas en un lenguaje concreto.
       e
    El lenguaje escogido para estas implementaciones ha sido Pascal. Esta elec-
ci´n se debe a que este lenguaje es simple y tiene una sintaxis sencilla, que
  o
hace que sea f´cil de aprender, y al mismo tiempo es lo bastante completo como
              a
para plasmar las diferentes t´cnicas y m´todos necesarios en programas de com-
                             e          e
plejidad media-alta. Esto lo hace una herramienta pedag´gica id´nea para el
                                                           o        o
aprendizaje de la programaci´n. A todo esto hay que sumar las numerosas im-
                              o
plementaciones existentes y su accesibilidad, as´ como su evoluci´n y continua
                                                ı                 o
puesta al d´ para permitir t´cnicas de programaci´n actuales (por ejemplo, mo-
           ıa                e                    o
dular u orientada a los objetos) y su gran difusi´n y aceptaci´n en el ambito
                                                  o             o       ´
acad´mico.
     e


Organizaci´n del libro
          o

    El libro est´ estructurado en siete partes. En cada una de ellas se estudian
                a
las t´cnicas y mecanismos nuevos, conceptualmente primero, detallando luego
     e
su tratamiento en Pascal y, finalmente, compaginando ambas facetas con el as-
pecto metodol´gico. Cada tema se ha dividido en varios cap´
                o                                               ıtulos para evitar
una excesiva fragmentaci´n. En cada cap´
                          o               ıtulo se ha incluido una lista de ejerci-
cios propuestos de dificultad aproximadamente creciente. Al final de cada tema
se desarrolla un ejemplo completo pensado para mostrar a la vez los aspectos
m´s destacados del mismo, as´ como unas pocas referencias comentadas que se
  a                            ı
sugieren como lecturas complementarias o de consulta.


Contenido

    El contenido se ha seleccionado partiendo de las directrices se˜aladas en
                                                                     n
[DCG  + 89] y [Tur91]. Incluye los contenidos cursos CS1 y CS2 [GT86, KSW85]

salvo los aspectos de organizaci´n de computadores, que se estudian en [PAO94],
                                o
de los mismos autores que este libro.
    En el primer tema se presentan, entre otros, los conceptos esenciales de algo-
ritmo, dato y programa. Se introduce el lenguaje Pascal y la estructura de los
programas escritos en ´l, as´ como los elementos b´sicos del lenguaje. Se incluyen
                      e     ı                     a
xxii                                                                         ´
                                                                   Presentacion

algunos programas sencillos, y se adelantan la t´cnica descendente de dise˜o de
                                                e                         n
programas y algunos apuntes sobre la correcci´n.
                                              o
    El segundo tema se dedica a la programaci´n estructurada. Se pone espe-
                                                o
cial ´nfasis en el dise˜o descendente o por refinamientos sucesivos partiendo de
     e                 n
especificaciones escritas en pseudoc´digo, y se muestra c´mo compaginar esta
                                     o                    o
t´cnica con la derivaci´n de programas correctos.
 e                      o
   En el tercer tema se estudian los subprogramas. Al igual que en el tema
anterior, se detalla c´mo enfocar la correcci´n en el uso de esta t´cnica. Se
                       o                       o                   e
concluye con un cap´ ıtulo de introducci´n a la recursi´n.
                                        o              o
    En la mayor´ de los programas no basta con los tipos de datos b´sicos, sino
                ıa                                                 a
que es necesario que el programador defina otros m´s complejos. A ello se dedica
                                                 a
el cuarto tema.
    El quinto tema estudia las t´cnicas propias de la gesti´n de memoria din´mica.
                                e                          o                  a
Se justifica su necesidad, y se presenta su principal aplicaci´n, que es la definici´n
                                                             o                    o
de estructuras de datos recursivas.
    El sexto tema introduce tres aspectos avanzados: la programaci´n con tipos
                                                                     o
abstractos de datos, el coste de los algoritmos y los principales esquemas de
dise˜o de algoritmos. Aunque, ciertamente, su estudio en profundidad rebasa un
    n
primer curso, es frecuente introducir –o siquiera mencionar– sus ideas b´sicas.
                                                                           a
Por supuesto, siempre es altamente recomendable consultar otras referencias
(nosotros mismos las seleccionamos para cada tema), pero tambi´n es cierto
                                                                     e
que el alumno se ve obligado con frecuencia a usar varios textos b´sicos para
                                                                      a
cubrir diferentes partes de la materia. Justamente, estos ultimos cap´
                                                            ´            ıtulos se
incluyen para que el lector interesado se pueda asomar a ellos sin verse obligado
a consultar los cap´
                   ıtulos introductorios de otros libros.
    Finalmente se incluyen tres ap´ndices: en el primero se introducen un par
                                   e
de aspectos complementarios para un primer curso de programaci´n (el paso
                                                                   o
de subprogramas como par´metros y el uso de variables aleatorias); el segundo
                           a
es un prontuario de uso del entorno integrado de desarrollo Turbo Pascal; y el
tercero indica algunos detalles de Turbo Pascal en que se separa del est´ndar,
                                                                        a
pero que son de uso frecuente.

Notaci´n empleada
      o
    En la lectura de este texto se encontrar´n fragmentos escritos en distintos
                                            a
lenguajes:

   • En castellano puro, donde se ha usado este tipo de letra.

   • En Pascal, para lo que se ha elegido el teletipo, salvo las palabras reser-
     vadas, que van en negrita.
´
Presentacion                                                                   xxiii

      Tambi´n se ha empleado el teletipo para indicar las salidas y entradas de
             e
      datos, porque es el tipo de letra m´s parecido al que aparece en el monitor.
                                         a

   • En seudoc´digo, que se expresa con letra cursiva.
              o

   • En lenguaje matem´tico, en que se usan los s´
                      a                          ımbolos usuales.

   • Otros s´
            ımbolos especiales:

               El espacio en blanco (v´ase la p´gina 206)
                                       e       a
        ;      Uno o m´s pasos al evaluar una expresi´n (v´ase la p´gina 30)
                        a                             o   e        a
        •      Fin de archivo (v´ase la p´gina 57)
                                e        a
        ←      Fin de l´
                       ınea (v´ase la p´gina 57)
                              e        a

Advertencia para el alumno
    No existe un m´todo general para resolver problemas mediante algoritmos;
                      e
por ello, es de gran importancia estudiar las t´cnicas de forma gradual, yendo
                                               e
de lo f´cil a lo dif´ y vincul´ndolas con situaciones ampliamente conocidas.
       a            ıcil      a
    Nosotros pretendemos haber cumplido con este objetivo, proporcionando
ejemplos de f´cil comprensi´n y ejercicios a la medida de lo explicado. Y eso es
              a              o
lo bueno. Lo malo es que el alumno puede percibir la sensaci´n de comprenderlo
                                                                o
todo a la velocidad que lee. . . y aqu´ reside el peligro. Porque una mera lectura
                                      ı
del texto, o incluso una lectura atenta, no basta para asimilarlo, adquiriendo las
t´cnicas necesarias para resolver otros problemas de dificultad similar a la de los
 e
planteados. Es preciso adoptar una actitud cr´    ıtica durante la lectura, trabajar
minuciosamente con los problemas propuestos e incluso tatar de imaginar solu-
ciones alternativas a los ejemplos dados. Y cuanto antes se acepte esa realidad,
mejor que mejor.


Agradecimientos
    Muchas personas han contribuido de diferentes maneras a que este libro sea
lo que es. En primer lugar, debemos a nuestros alumnos de estos a˜os su ayuda,
                                                                  n
aun sin saberlo, porque ellos han sido la raz´n de que emprendi´ramos este
                                               o                    e
trabajo, y porque sus preguntas y comentarios, d´ a d´ tienen una respuesta
                                                 ıa    ıa,
en las p´ginas que siguen. En segundo lugar, debemos a muchos de nuestros
         a
compa˜eros su aliento y apoyo, tan necesario cuando uno se enfrenta a un trabajo
       n
de esta envergadura. Y por ello, lo dedicamos a ambos, alumnos y compa˜eros.
                                                                           n
   De un modo muy especial, deseamos expresar nuestro agradecimiento a Juan
Falgueras Cano, Luis Antonio Gal´n Corroto y Yolanda Ortega y Mall´n por
                                  a                                    e
su cuidadosa lectura de la primera versi´n completa del manuscrito, y por sus
                                        o
xxiv                                                                     ´
                                                               Presentacion

valiosos comentarios y sugerencias. No podemos olvidar tampoco la ayuda de
Manuel Enciso Garc´ ıa-Oliveros en los ultimos retoques, as´ como su proximidad
                                       ´                   ı
y apoyo durante todo el tiempo que nos ha ocupado este trabajo.
   Por ultimo, deseamos expresar nuestra gratitud y cari˜o a Jos´ Luis Gal´n
        ´                                               n       e         a
Garc´ que ha dejado en este libro muchas horas.
    ıa,
Tema I

Algoritmos e introducci´n a
                       o
          Pascal
Cap´
   ıtulo 1

Problemas, algoritmos y programas


        1.1   Soluci´n de problemas mediante programas . . . . . .
                    o                                                               3
        1.2   Concepto de algoritmo . . . . . . . . . . . . . . . . . . .           5
        1.3   Aspectos de inter´s sobre los algoritmos . . . . . . . .
                               e                                                   11
        1.4   Lenguajes algor´
                             ıtmicos y de programaci´n . . . . . . .
                                                    o                              16
        1.5   Desarrollo sistem´tico de programas . . . . . . . . . .
                               a                                                   18
        1.6   Conclusi´n . . . . . . . . . . . . . . . . . . . . . . . . . . .
                      o                                                            20
        1.7   Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . .   20
        1.8   Referencias bibliogr´ficas . . . . . . . . . . . . . . . . . .
                                  a                                                21




    En este primer cap´ıtulo se trata la resoluci´n de problemas por medio de
                                                 o
un computador. Puesto que ´ste no es m´s que un mero ejecutor de tareas, es
                              e           a
fundamental conocer un m´todo de resoluci´n del problema en cuesti´n, esto
                            e                 o                       o
es, un algoritmo. La escritura de este algoritmo como un conjunto de ´rdenes
                                                                      o
comprensibles por el computador es lo que se llama programa.


1.1    Soluci´n de problemas mediante programas
             o

    Los computadores desempe˜an una gran variedad de tareas, liberando as´
                               n                                              ı
al hombre de tener que realizarlas personalmente. Para ello, es preciso ense˜ar
                                                                            n
al computador cu´l es su trabajo y c´mo llevarlo a cabo, esto es, programarlo,
                 a                   o
4                     Cap´
                         ıtulo 1. Problemas, algoritmos y programas

d´ndole instrucciones precisas (programas) en un lenguaje que comprenda (Pas-
 a
cal, Modula-2, C, etc.). Una vez “aprendido” el programa, el computador seguir´
                                                                              a
ciegamente sus instrucciones cuantas veces sea requerido.
    Precisamente, la tarea de la programaci´n consiste en describir lo que debe
                                            o
hacer el computador para resolver un problema concreto en un lenguaje de pro-
gramaci´n. Sin embargo, el programa es solamente el resultado de una serie de
        o
etapas que no se pueden pasar por alto. Hablando en t´rminos muy amplios, se
                                                      e
identifican de momento las siguientes fases:

    1. An´lisis del problema, estableciendo con precisi´n lo que se plantea.
         a                                             o

    2. Soluci´n conceptual del problema, describiendo un m´todo (algoritmo) que
             o                                            e
       lo resuelva.

    3. Escritura del algoritmo en un lenguaje de programaci´n.
                                                           o

    En la primera fase es corriente partir de un problema definido vagamente, y
el an´lisis del mismo consiste en precisar el enunciado, identificando los datos
      a
de partida y los resultados que se desean obtener. La descripci´n precisa de un
                                                                 o
problema se llama especificaci´n. Con frecuencia, el lenguaje natural no basta
                                o
para lograr la precisi´n deseada, por lo que se recurre en mayor o menor medida
                      o
a lenguajes formales, como la l´gica o las matem´ticas. Supongamos por ejemplo
                                o                 a
que se plantea el problema de dividir dos n´meros. En primer lugar, se necesita
                                             u
saber si se trata de la divisi´n entera o de aproximar el resultado con decimales
                              o
y, en ese caso, hasta d´nde. Pongamos por caso que interesa la divisi´n eucl´
                       o                                              o     ıdea.
Una descripci´n precisa deber´ tener en cuenta que los datos son dos enteros
               o                 a
(llam´mosles dividendo y divisor, como es usual), de los que el segundo es no
      e
nulo. El resultado es tambi´n un par de enteros (llam´mosles cociente y resto,
                              e                          e
como siempre) tales que

                     dividendo = divisor ∗ cociente + resto

    Pero eso no es todo: si nos contentamos con ese enunciado, para todo par de
enteros (dividendo, divisor), el par (0, dividendo) siempre es una soluci´n. Por
                                                                         o
eso, hay que a˜adir que resto debe ser adem´s tal que 0 ≤ resto < divisor.
              n                                a
    Con este peque˜o ejemplo se pretende resaltar la importancia de analizar
                    n
bien el problema planteado, definiendo con precisi´n los requisitos que deben
                                                    o
verificar los datos y las condiciones en que deben estar los resultados.
    Sin embargo, en esta fase s´lo se ha estudiado qu´ se desea obtener, y no
                                 o                      e
 o               ´
c´mo lograrlo. Este es el cometido de la segunda etapa: describir un m´todo e
(algoritmo) tal que partiendo de datos apropiados lleve sistem´ticamente a los re-
                                                              a
sultados descritos en la especificaci´n. Del concepto de algoritmo nos ocupamos
                                    o
1.2. Concepto de algoritmo                                                     5



                          1                            2                 3
                                  ¿Est´ abierto el
                                      a                        Esperar
             Principio
                                plazo de matr´ıcula?          a ma˜ana
                                                                  n
               →2
                                  s´ → 4 no → 3
                                   ı                             →2
                           4                        5                     6
         Comprar impresos       Leer instrucciones.        Preguntar dudas
          de matriculaci´n
                        o      ¿Tengo alguna duda?          en Secretar´
                                                                       ıa
               →5                s´ → 6 no → 7
                                  ı                             →7
                           7                        8                     9
         Rellenar el sobre
                                 Entregar el sobre
        y pagar en el banco                                      Fin
                                       →9
               →8



                                  Figura 1.1.


en el siguiente apartado. Es evidente que s´lo se puede confiar en un algoritmo
                                             o
si ha superado con ´xito determinado control de calidad: la primera e inexcusa-
                     e
ble exigencia es que sea correcto; esto es, que resuelva el problema especificado.
Cuando un problema admita varios algoritmos como soluci´n, convendr´ dispo-
                                                              o          a
ner de criterios para escoger; y cuando un problema no tenga soluci´n, no resulta
                                                                    o
sensato buscar un algoritmo para resolverlo. Estos aspectos los estudiamos en el
apartado 1.3.
     Finalmente, para que un computador resuelva problemas hay que escribir el
algoritmo en un lenguaje de programaci´n; de ello hablaremos en el apartado
                                       o
1.4.


1.2     Concepto de algoritmo
    Los conceptos de algoritmo y de m´todo son parecidos: los m´todos para
                                         e                           e
efectuar procesos forman parte de las costumbres o rutinas que el hombre aprende
un d´ y luego repite de manera inconsciente, sin reparar ya en las acciones, m´s
     ıa                                                                       a
sencillas, que integran el proceso (por ejemplo andar, leer o conducir). Por eso
el concepto de algoritmo suele compararse a otros como m´todo o rutina de
                                                               e
acciones.
   La secuencia de pasos de la figura 1.1 describe un m´todo para efectuar la
                                                      e
matr´
    ıcula en la universidad.
   Sin embargo, el t´rmino “algoritmo” tiene connotaciones m´s formales que
                     e                                         a
cualquier otro debido a su origen: se trata de una acomodaci´n al castellano del
                                                            o
6                         Cap´
                             ıtulo 1. Problemas, algoritmos y programas

nombre de Muhammad ibn M¯s¯ al-Jw¯r¯ ı, matem´tico persa que populariz´
               .              ua        a ızm¯        a                        o
su descripci´n de las cuatro reglas (algoritmos) de sumar, restar, multiplicar y
            o
dividir.


1.2.1      Una definici´n de algoritmo
                      o

    Hablando informalmente, un algoritmo es la descripci´n precisa de los pasos
                                                           o
que nos llevan a la soluci´n de un problema planteado. Estos pasos son, en gene-
                          o
ral, acciones u operaciones que se efect´an sobre ciertos objetos. La descripci´n
                                        u                                      o
de un algoritmo afecta a tres partes: entrada (datos), proceso (instrucciones)
y salida (resultados).1 En este sentido, un algoritmo se puede comparar a una
funci´n matem´tica:
      o         a

                        +      :   Z ×Z
                                   Z Z        −→        Z
                                                        Z
                   (algoritmo)   (entrada) (proceso) (salida)

    Incluso en algoritmos no matem´ticos es f´cil identificar las tres partes: entra-
                                   a         a
da, proceso y salida. As´ ocurre, por ejemplo, en las instrucciones para hacer la
                         ı
declaraci´n de la renta.
         o


Caracter´
        ısticas de los algoritmos

    La descripci´n de algoritmo que se ha dado es algo imprecisa. Una caracte-
                o
rizaci´n m´s completa deber´ incluir adem´s los siguientes requisitos:
      o   a                  ıa            a

    1. Precisi´n
              o
        Un algoritmo debe expresarse de forma no ambigua. La precisi´n afecta
                                                                    o
        por igual a dos aspectos:

        (a) Al orden (encadenamiento o concatenaci´n) de los pasos que han de
                                                  o
            llevarse a cabo.
        (b) Al contenido de las mismas, pues cada paso debe “saberse realizar”
            con toda precisi´n, de forma autom´tica.
                            o                 a

        Por lo tanto, una receta de cocina puede ser considerada como un m´todo,
                                                                           e
        pero carece de la precisi´n que requieren los algoritmos debido al uso de
                                 o
        expresiones como a˜adir una pizca de sal, porque ¿qu´ debe entenderse por
                           n                                 e
        una pizca?
    1
    Es habitual llamar “datos” a la entrada y “resultados” a la salida, aunque el concepto de dato
es m´s amplio, y abarca a toda la informaci´n que maneja un algoritmo, ya sea inicialmente o a
     a                                      o
su t´rmino, as´ como tambi´n durante el transcurso de su utilizaci´n.
    e         ı            e                                        o
1.2. Concepto de algoritmo                                                                   7




                                                        NO
         Principio         a         b         a = 0         a ← a-1         b ← b+1
                       1        2         3             4               5
                                                   ´
                                                6 SI

                                                    b

                                                7

                                                Fin




                     Figura 1.2. Diagrama de flujo de la “suma lenta”.


   2. Determinismo
       Todo algoritmo debe responder del mismo modo ante las mismas condicio-
       nes.
       Por lo tanto, la acci´n de barajar un mazo de cartas no es un algoritmo,
                            o
       ya que es y debe ser un proceso no determinista.
   3. Finitud
       La descripci´n de un algoritmo debe ser finita.
                   o

Un primer ejemplo

    Consideremos el ejemplo que, expresado gr´ficamente,2 aparece en la fi-
                                                  a
gura 1.2. El algoritmo descrito tiene por objetivo sumar dos cantidades enteras.
Si se anotan esas cantidades inicialmente en sendas casillas (a las que llamaremos
a y b para abreviar), este m´todo consiste en ir pasando de a a b una unidad
                              e
cada vez, de forma que, cuando a = 0, el resultado ser´ el valor de b.
                                                        a
    Vemos un ejemplo de su funcionamiento con los datos 2 y 3 en la figura 1.3.
(Los n´meros se han incluido para seguir mejor la evoluci´n de los c´lculos.)
       u                                                    o           a
    Se observa que la descripci´n del algoritmo que se ha dado es, en efecto,
                                 o
precisa (cada paso est´ exento de ambig¨edad, as´ como el orden en que se debe
                       a                 u        ı
efectuar) y determinista (el efecto de cada paso es siempre el mismo para unos
datos concretos cualesquiera). Estas dos caracter´  ısticas son una consecuencia
del lenguaje escogido para expresar el algoritmo.
   2
    El lenguaje empleado es el de los diagramas de flujo, que estudiaremos en el cap´   ıtulo 7,
apartado 7.2.1. Esperamos que, debido a su sencillez, el funcionamiento de este ejemplo resulte
comprensible directamente.
8                      Cap´
                          ıtulo 1. Problemas, algoritmos y programas

        Posici´n
              o    Datos pendientes     Resultados emitidos      Var a      Var b
           1            [2, 3]                  []                 ?          ?
           2              [3]                   []                 2          ?
           3              []                    []                 2         3
           4              []                    []                 2         3
           5              []                    []                 1         3
           3              []                    []                 1         4
           4              []                    []                 1         4
           5              []                    []                 0         4
           3              []                    []                 0         5
           6              []                    []                 0         5
           7              []                    [5]                0         5


              Figura 1.3. Ejecuci´n de la suma lenta con los datos 2 y 3.
                                 o


    En cambio, si bien es cierto que, con los datos del ejemplo, se ha obtenido
una soluci´n, si se examina con detenimiento se ver´ que ese “algoritmo” no
          o                                            a
siempre termina para dos cantidades enteras cualesquiera (v. g. − 3 y − 1).
De hecho, la terminaci´n es una caracter´
                      o                  ıstica escurridiza de la que hablaremos
m´s tarde (v´ase el apartado 1.3.1).
  a          e

1.2.2     Una definici´n formal de algoritmo
                     o
    La caracterizaci´n hecha hasta ahora de los algoritmos es satisfactoria a efec-
                    o
tos pr´cticos. M´s concreta a´n resulta a la vista de un lenguaje algor´
      a           a            u                                            ıtmico
como el de los diagramas de flujo, que deja entrever dos aspectos:

    • El mantenimiento de unas variables (a y b) y de unas posiciones (1, . . . , 7),
      a lo que llamamos estado. Por ejemplo, cada fila de la tabla de la figura 1.3
      representa un estado en la evoluci´n del algoritmo 1.2.
                                        o
    • La descripci´n de transiciones entre estados, que vienen dadas por el propio
                  o
      diagrama.

   Estos aspectos de los algoritmos est´n ausentes de la primera definici´n,
                                        a                                  o
por lo que puede resultar a´n algo incompleta; surge pues la necesidad de una
                           u
definici´n m´s formal:
       o    a
Definici´n:
        o      Un algoritmo es una cu´drupla que comprende los siguientes ele-
                                     a
mentos:

    1. El conjunto de los estados (llam´mosle E) que pueden presentarse en todo
                                       e
       momento durante el c´lculo.
                             a
1.2. Concepto de algoritmo                                                     9

     Un estado viene dado por una tupla, incluyendo:
        • los valores de las variables que entran en juego;
        • los datos sin leer y los resultados emitidos, y
        • la marca, identificando la posici´n del algoritmo en la que se da este
                                          o
          estado de los c´lculos.
                         a
     Es decir, un estado se puede expresar as´
                                             ı:

             <Datos por leer; Resultados emitidos; Variables; Posici´n>
                                                                    o

  2. La identificaci´n de los estados iniciales, I ⊂ E, o estados posibles al
                   o
     comienzo del algoritmo.
  3. La identificaci´n de los estados finales, F ⊂ E, como posibles estados al
                    o
     terminar el algoritmo.
  4. Una funci´n de transici´n entre estados,
              o             o
                                         t : E −→ E
     que describe el efecto de cada paso del c´mputo asociado al algoritmo.
                                              o
     Esta funci´n deber´:
               o        a
        • Estar definida dentro de E, esto es, para cualquier e ∈ E debemos
          tener que t(e) ∈ E. As´ las transiciones entre estados son precisas y
                                ı,
          deterministas.
        • A partir de cualquier estado inicial, la funci´n de transici´n t debe
                                                        o             o
          llevar a un estado final en un n´mero finito de pasos, formalmente:
                                           u
          para cualquier e ∈ I existe un k ∈ IN tal que
                                       t se aplica k veces
                                       t(t(· · · t(e) · · ·)) ∈ F
          y, adem´s, no tiene efecto alguno sobre los estados finales, es decir:
                  a
          para cualquier e ∈ F ocurre que t(e) = e. De aqu´ se obtiene la
                                                               ı
          caracter´
                  ıstica de finitud.

    Siguiendo con el algoritmo del diagrama de flujo de la figura 1.2, identificamos
los siguientes estados:

           E = { < 1 ; [d1 , d2 ] ; [ ] ;                     —       >
                   < 2 ;       [d2 ]      ; [] ;             a ≡ a0   >
                   < p ;        []        ; [ ] ; a ≡ a 0 , b ≡ b0 >
                   < 7 ;        []        ; [r] ;             —       > }
10                           Cap´
                                ıtulo 1. Problemas, algoritmos y programas

donde d1 , d2 , a, b, r ∈ IN, p ∈ {3, . . . , 6}, y siendo

                                    I = {< 1; [d1 , d2 ]; [ ]; — >}

y
                                     F = {< 7; [ ]; [r]; — >}.

      La funci´n de transici´n t es la siguiente:
              o             o

     t(< 1; [d1 , d2 ]; [ ]; — >)           = < 2; [d2 ]; [ ]; a ≡ d1 >
     t(< 2; [d2 ]; [ ]; a ≡ d1 >)        = < 3; [ ]; [ ]; a ≡ d1 , b ≡ d2 >
                                            < 6; [ ]; [ ]; b ≡ b0 >            si a = 0
     t(< 3; [ ]; [ ]; a ≡ a0 , b ≡ b0 >) =
                                            < 4; [ ]; [ ]; a ≡ a0 , b ≡ b0 > si a = 0
     t(< 4; [ ]; [ ]; a ≡ a0 , b ≡ b0 >) = < 5; [ ]; [ ]; a ≡ a0 − 1, b ≡ b0 >
     t(< 5; [ ]; [ ]; a ≡ a0 , b ≡ b0 >) = < 3; [ ]; [ ]; a ≡ a0 , b ≡ b0 + 1 >
     t(< 6; [ ]; [ ]; b ≡ b0 >)             = < 7; [ ]; [b0 ]; — >
     t(< 7; [ ]; [r]; — >)                  = < 7; [ ]; [r]; — >

     Desde el punto de vista del usuario de un algoritmo, se puede considerar un
algoritmo como una caja opaca cuyos detalles internos se ignoran, aflorando s´lo  o
la lectura de los datos y la escritura de los resultados. Estos aspectos observables
desde el exterior se llaman frecuentemente la interfaz externa. No obstante, el
mecanismo interno interesa al autor de algoritmos, esto es, al programador. Para
atender esta necesidad, algunos entornos de programaci´n permiten “trazar”
                                                              o
programas, con lo que el programador puede ver evolucionar el estado interno
durante la marcha de su programa con el grado de detalle que desee (v´anse     e
los apartados 5.4.1 y C.2.6). Esta posibilidad es interesante para depurar los
programas, esto es, para buscar los posibles errores y subsanarlos.
     Para terminar este apartado, debemos decir que el esquema de funciona-
miento descrito a base de transiciones entre estados se conoce con el nombre de
modelo de von Neumann (v´ase el apartado 7.2.1 de [PAO94]). Se dice que este
                              e
modelo es secuencial, en el sentido de que los pasos se efect´an uno tras otro. De
                                                              u
hecho, no es posible acelerar el proceso efectuando m´s de un paso a un tiempo,
                                                         a
porque cada paso tiene lugar desde el estado dejado por el paso anterior. Este
“cuello de botella” es un defecto propio de las m´quinas de von Neumann.
                                                     a

Cualidades deseables de un algoritmo

    Es muy importante que un algoritmo sea suficientemente general y que se
ejecute eficientemente. Veamos con m´s detalle qu´ se entiende por general y
                                    a           e
por eficiente:
´
1.3. Aspectos de interes sobre los algoritmos                                11

  1. Generalidad
      Es deseable que un algoritmo sirva para una clase de problemas lo m´s  a
      amplia posible. Por ejemplo, la clase de problemas “resolver una ecuaci´n
                                                                             o
      de segundo grado, a + bx + cx2 = 0” es m´s general que la consistente
                                                    a
      en “resolver ecuaciones de primer grado, a + bx = 0”.
  2. Eficiencia
      Hablando en t´rminos muy generales, se considera que un algoritmo es
                      e
      tanto m´s eficiente cuantos menos pasos emplea en llevar a cabo su come-
              a
      tido. Por ejemplo, para hallar la suma de dos n´meros naturales, la regla
                                                       u
      tradicional que se aprende en ense˜anza primaria es m´s eficiente que el
                                         n                     a
      rudimentario procedimiento de contar con los dedos, de uno en uno. Este
      tema se revisar´ en el apartado 1.3.3, y ser´ tratado con mayor detalle en
                      a                           a
      el cap´
            ıtulo 18.

    Estas dos cualidades no son siempre conciliables, por lo que frecuentemente
hay que optar por una soluci´n en equilibrio entre ambas cuando se dise˜a un
                              o                                           n
algoritmo. Por ejemplo, un algoritmo que estudia y resuelve “sistemas de ecua-
ciones” es m´s general que uno que resuelve “sistemas de ecuaciones lineales”, y
             a
´ste a su vez es m´s general que otro que s´lo considera “sistemas de dos ecua-
e                  a                       o
ciones lineales con dos inc´gnitas”. Sin embargo, a mayor generalidad se tiene
                           o
tambi´n una mayor complejidad puesto que hay que tratar m´s casos y no se
      e                                                         a
pueden aplicar algoritmos espec´ ıficos. Por consiguiente, si un buen n´mero de
                                                                       u
situaciones puede resolverse con un algoritmo r´pido aunque poco general, es
                                                 a
preferible adoptar ´ste.
                   e


1.3     Aspectos de inter´s sobre los algoritmos
                         e
1.3.1    Computabilidad
    Con el aumento de potencia y el abaratamiento de los computadores, cada vez
se plantean aplicaciones m´s sorprendentes y de mayor envergadura, capaces de
                           a
resolver problemas m´s generales. Da la impresi´n de que cualquier problema que
                     a                         o
se plantee ha de ser computable (esto es, ha de tener una soluci´n algor´
                                                                o       ıtmica),
sin otra limitaci´n que la potencia de la m´quina ejecutora.
                 o                         a
    Sin embargo, esto no es as´ Por rotunda que pueda parecer esta afirmaci´n,
                               ı.                                            o
se debe aceptar que

                         hay problemas no computables

    La cuesti´n que se plantea es algo delicada: advi´rtase que, si no se conoce
             o                                       e
algoritmo que resuelva un problema planteado, s´lo se puede asegurar “que no
                                                 o
12                    Cap´
                         ıtulo 1. Problemas, algoritmos y programas

se conoce algoritmo que resuelva ese problema”; en cambio, establecer que un
problema “no es computable” requiere demostrar que nunca se podr´ encontrar
                                                                 a
ning´n algoritmo para resolver el problema planteado.
     u
    Los siguientes son ejemplos de problemas no computables:

     • D´cimo problema de Hilbert.
        e
       Resolver una ecuaci´n diof´ntica con m´s de una inc´gnita.
                          o      a           a            o
       Esto significa encontrar soluciones enteras de una ecuaci´n de la forma
                                                                      o
       P (x1 , x2 , . . .) = 0, donde P es un polinomio con coeficientes enteros.
     • Problema de la parada.
       Determinar si un algoritmo a finaliza o no cuando opera sobre una entrada
       de datos d:                        
                                           S´ı    si a(d) ↓
                            Stop(a, d) =
                                          
                                             No si a(d) ↑
       donde a(d) ↓ (resp. a(d) ↑) expresa que el algoritmo a, aplicado al dato d,
       s´ para (resp. no para).
        ı

     Examinaremos con m´s atenci´n el problema de la parada, y despu´s veremos
                          a        o                                 e
cu´n escurridizo puede resultar determinar si un algoritmo particular para o no
   a
considerando un sencillo ejemplo. Claro est´ que esto no demuestra nada salvo,
                                             a
en todo caso, nuestra incapacidad para analizar este algoritmo en concreto. Por
ello, incluimos seguidamente una demostraci´n de que es imposible hallar un
                                               o
algoritmo capaz de distinguir entre los algoritmos que paran y los que no.
     Obs´rvese que se plantea aqu´ estudiar “algoritmos que operan sobre algorit-
        e                        ı
mos, vistos como datos”. Por extra˜o que parezca al principio, en Computaci´n
                                     n                                        o
se desarrollan frecuentemente programas que manejan otros programas con di-
versos fines.

El problema de la parada no es computable

    El problema de la parada, definido m´s arriba, se puede expresar como sigue:
                                           a
¿se puede examinar cualquier algoritmo y decidir si para? Demostraremos que
no existe, ni puede existir, el algoritmo Stop que distinga si un algoritmo a para
cuando se aplica a los datos d.
    Procederemos por reducci´n al absurdo: Suponiendo que existe ese algoritmo
                                o
(descrito m´s arriba como Stop), a partir de ´l es posible construir otro similar,
            a                                  e
Stop’, que averig¨e si un algoritmo a para cuando se aplica “a su propio texto”:
                  u

                                                 ı
                                                S´    si p(p) ↓
                  Stop’(p) = Stop(p, p) =
                                                No    si p(p) ↑
´
1.3. Aspectos de interes sobre los algoritmos                                        13

    Y entonces, tambi´n se puede definir el siguiente algoritmo a partir del an-
                     e
terior:
                           ↑      si Stop’(p) = S´
                                                 ı                  ↑    si p(p) ↓
           Raro(p) =                                        =
                           No     si Stop’(p) = No                  No   si p(p) ↑
    Veamos que el algoritmo Raro tiene un comportamiento verdaderamente
extra˜o cuando se aplica a s´ mismo:
     n                      ı


                                           ↑          si Stop’(Raro) = S´
                                                                        ı
                Raro(Raro) =
                                          No          si Stop’(Raro) = No
                                          ↑           si Raro(Raro) ↓
                                  =
                                          No          si Raro(Raro) ↑
lo que resulta obviamente imposible.
    La contradicci´n a que hemos llegado nos lleva a rechazar la hip´tesis inicial
                  o                                                 o
(la existencia de un algoritmo para el problema de la parada), como quer´  ıamos
demostrar.

N´ meros pedrisco
 u

    Como ejemplo de la dificultad de examinar un algoritmo y decidir si concluir´
                                                                               a
tarde o temprano, consideremos la siguiente funci´n t: IN → IN:
                                                  o
                              
                               3n + 1 si n es impar
                       t(n) =
                              
                                n/2      si n es par
   Partiendo de un n´mero natural cualquiera, le aplicamos t cuantas veces sea
                      u
necesario, hasta llegar a 1. Por ejemplo,
                      t       t       t        t        t       t    t
                   3 −→ 10 −→ 5 −→ 16 −→ 8 −→ 4 −→ 2 −→ 1 · · ·


   Esta sencilla sucesi´n genera n´meros que saltan un n´mero de veces impre-
                       o          u                     u
decible,
                                               t111
                                          27 −→ 1
de manera que cabe preguntarse si todo natural n alcanza el 1 tras una cantidad
finita de aplicaciones de t, o por el contrario existe alguno que genera t´rminos
                                                                           e
que saltan indefinidamente.3
    Se ha comprobado, por medio de computadores, que la sucesi´n llega a 1 si
                                                                     o
se comienza con cualquier n´mero natural menor que 2
                            u                            40  10 12 , pero a´ n no se
                                                                           u
ha podido demostrar para todo n.
  3
      Este problema tambi´n se conoce como problema 3n+1.
                         e
14                            Cap´
                                 ıtulo 1. Problemas, algoritmos y programas

1.3.2          Correcci´n de algoritmos
                       o
    El aspecto de la correcci´n es de crucial importancia para quien desarrolla un
                             o
algoritmo. Sin embargo, es imposible detectar los posibles errores de una forma
sistem´tica. Con frecuencia, la b´squeda de errores (depuraci´n) consiste en la
       a                           u                              o
comprobaci´n de un algoritmo para unos pocos juegos de datos. Sin embargo, eso
           o
no garantiza nada m´s que el buen funcionamiento del algoritmo para esos juegos
                      a
de datos y no para todos los posibles. Volviendo al algoritmo de la suma lenta, la
comprobaci´n con los juegos de datos [2, 3] y [3, -1] ofrecer´ resultados correctos,
            o                                                ıa
y sin embargo el algoritmo unicamente termina cuando el primer sumando es (un
                            ´
entero) positivo.
    Frente a la comprobaci´n, la verificaci´n consiste en la demostraci´n del buen
                           o              o                           o
funcionamiento de un algoritmo con respecto a una especificaci´n. Esto es, la
                                                                  o
verificaci´n trata de garantizar que, para todos los datos considerados (descritos
         o
en la especificaci´n), el algoritmo lleva a los resultados (tambi´n descritos en la
                  o                                             e
especificaci´n) deseados. Por eso, aunque frecuentemente se habla de correcci´n
           o                                                                   o
de un algoritmo, sin m´s, en realidad hay que decir correcci´n de un algoritmo
                        a                                     o
con respecto a una especificaci´n.
                                o
    Por lo general, la verificaci´n se basa en establecer aserciones (propiedades)
                                o
del estado de la m´quina en cada paso del algoritmo. Se profundizar´ en esta
                    a                                                    a
idea a lo largo de todo el texto. Por ejemplo, para verificar el funcionamiento del
algoritmo de “suma lenta”, consideremos que se hace funcionar sobre dos enteros
gen´ricos m y n. Claramente, al llegar a la posici´n 3 por vez primera, a = m y
    e                                              o
b = n. Por otra parte, en la posici´n 3 se tiene invariablemente la propiedad
                                    o

                                            a+b=m+n

independientemente de las vueltas que se den y de las modificaciones que se
efect´en sobre a y b,4 ya que cada unidad que se reste a a se le suma a b. Ahora
     u
bien, cuando se pasa de la posici´n 3 a la 6 es por ser a = 0, con lo que se tiene,
                                 o
simult´neamente, el invariante a + b = m + n y a = 0, es decir:
       a

                                              b=m+n

lo que asegura que la salida es correcta. . . cuando ´sta se produzca. Un algoritmo
                                                     e
que ofrece una soluci´n correcta cuando para, pero del que no sepamos si para
                      o
o no, se dice parcialmente correcto. Ese es el caso de la suma lenta de n´meros
                                                                             u
enteros.
    Adem´s, si inicialmente a es un n´mero natural, es seguro que el algoritmo
          a                          u
para, ya que la operaci´n a ← a − 1 lo llevar´ a cero, precisamente en a vueltas
                       o                     a
del bucle. Si se asegura que un algoritmo es parcialmente correcto y que para
     4
         Por ello, esta propiedad se conoce como invariante.
´
1.3. Aspectos de interes sobre los algoritmos                                             15

                                                                       ´
en un tiempo finito, se dice que el algoritmo es (totalmente) correcto. Ese es el
caso de la suma lenta de pares de n´meros, siendo el primero de ellos entero y
                                    u
positivo.
    La verificaci´n de algoritmos no es una tarea f´cil. Al contrario, verificar
                o                                      a
completamente un algoritmo involucra el uso de l´gica matem´tica, y con fre-
                                                     o            a
cuencia resulta incluso m´s complicado que desarrollarlo. De ah´ el inter´s que
                          a                                         ı       e
tiene esmerarse, desde el principio, en escribir algoritmos correctos, adquiriendo
un buen estilo y esforz´ndose en emplear metodolog´ apropiadas para ello.
                       a                               ıas

1.3.3       Complejidad de algoritmos
    Resulta de gran inter´s poder estimar los recursos que un algoritmo necesita
                         e
para resolver un problema. En m´quinas secuenciales, estos recursos son el
                                    a
tiempo y la memoria.5
    Muchas veces, un algoritmo tarda tanto en ofrecer el resultado que resulta,
en realidad, in´til. Un ejemplo de esta situaci´n se da en sistemas de control
                u                                o
de procesos, en donde la respuesta a determinadas circunstancias debe disparar
mecanismos de seguridad en un tiempo cr´    ıtico (por ejemplo, en centrales nu-
cleares). An´logamente para el espacio, es posible que la m´quina en que ha
             a                                                 a
de funcionar un programa disponga de una capacidad de memoria limitada y
nos veamos obligados a elegir algoritmos que usen poca memoria. Por lo tanto,
existen situaciones en las que si disponemos de varios algoritmos para un mismo
problema, deberemos decidir cu´l es el m´s r´pido o el que menos cantidad de
                                  a        a a
memoria requiere. En el cap´ ıtulo 18 se ahondar´ en esta idea.
                                                 a
    Como el tiempo requerido por los programas depende en gran medida de la
potencia de la m´quina ejecutora, es frecuente medir en “pasos” (de coste fijo)
                  a
el coste del algoritmo correspondiente. Para concretar un poco, y siguiendo con
el ejemplo de la suma lenta, consideremos que cada bloque o caja del diagrama
es un paso y, por tanto, cuesta una unidad. Entonces, es f´cil deducir que sumar
                                                          a
los naturales m y n lleva 3m + 4 pasos.
       En efecto, llamando tm al coste de sumar m y n, se tiene que

                               t0 = 4 pasos
                               tm = tm−1 + 3, si n ≥ 1

pues para sumar 0 y n hay que realizar cuatro pasos (v´ase la figura 1.2) y si
                                                       e
m = 0 hay que realizar tres pasos para reducir m en una unidad; resumiendo

                              t0 = 4
   5
    En los ultimos a˜os, tambi´n est´ interesando medir el n´mero de procesadores en m´quinas
           ´        n         e     a                       u                         a
de procesamiento en paralelo (v´ase el apartado 3.5 de [PAO94]).
                               e
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos
Algoritmos

Más contenido relacionado

La actualidad más candente

La actualidad más candente (7)

Tutorial de maxima
Tutorial de maximaTutorial de maxima
Tutorial de maxima
 
Calculo diferencial
Calculo diferencialCalculo diferencial
Calculo diferencial
 
Compiladores
CompiladoresCompiladores
Compiladores
 
Matemáticas Computacionales
Matemáticas ComputacionalesMatemáticas Computacionales
Matemáticas Computacionales
 
Java 2d
Java 2dJava 2d
Java 2d
 
Java 2D
Java 2DJava 2D
Java 2D
 
Calculo diferencial integral_func_una_var.pdf 03
Calculo diferencial integral_func_una_var.pdf   03Calculo diferencial integral_func_una_var.pdf   03
Calculo diferencial integral_func_una_var.pdf 03
 

Destacado

OCP, JSE 6 Programmer (1Z0-851) - Guia practica 6 de 7(Colecciones y Genericos)
OCP, JSE 6 Programmer (1Z0-851) - Guia practica 6 de 7(Colecciones y Genericos)OCP, JSE 6 Programmer (1Z0-851) - Guia practica 6 de 7(Colecciones y Genericos)
OCP, JSE 6 Programmer (1Z0-851) - Guia practica 6 de 7(Colecciones y Genericos)Oscar V
 
Guia de estudio para Oracle Certified Java EE 6 Web Component Developer
Guia de estudio para Oracle Certified Java EE 6 Web Component DeveloperGuia de estudio para Oracle Certified Java EE 6 Web Component Developer
Guia de estudio para Oracle Certified Java EE 6 Web Component DeveloperOscar V
 
documento para contestar la Guia de estudio informatica 1
documento para contestar la Guia de estudio informatica 1documento para contestar la Guia de estudio informatica 1
documento para contestar la Guia de estudio informatica 1soniagomezmorales
 
Guia de estudio OCA Java SE 7 Programmer
Guia de estudio OCA Java SE 7 ProgrammerGuia de estudio OCA Java SE 7 Programmer
Guia de estudio OCA Java SE 7 ProgrammerOscar V
 
Guia informatica 2014
Guia informatica 2014Guia informatica 2014
Guia informatica 2014solinfags
 
ejercicios diseño:_entidad relación en la creación de una BD
ejercicios diseño:_entidad relación en la creación de una BDejercicios diseño:_entidad relación en la creación de una BD
ejercicios diseño:_entidad relación en la creación de una BDJomar Burgos Palacios
 
Java y Bases de Datos
Java y Bases de DatosJava y Bases de Datos
Java y Bases de DatosRonny Parra
 
Problemas de diseño de base de datos
Problemas de diseño de base de datosProblemas de diseño de base de datos
Problemas de diseño de base de datosgonzalopomboza
 
Transformación de Modelo E-R a Modelo Relacional Ejemplo y Reporte
Transformación de Modelo E-R a Modelo Relacional Ejemplo y ReporteTransformación de Modelo E-R a Modelo Relacional Ejemplo y Reporte
Transformación de Modelo E-R a Modelo Relacional Ejemplo y ReporteNeoinquisidor
 
Transformar modelo entidad relacion a modelo logico
Transformar modelo entidad relacion a modelo logicoTransformar modelo entidad relacion a modelo logico
Transformar modelo entidad relacion a modelo logicojosecuartas
 
Guia practica funciones en java con NetBeans
Guia practica funciones en java con NetBeansGuia practica funciones en java con NetBeans
Guia practica funciones en java con NetBeansEmerson Garay
 
Cuaderno de informatica
Cuaderno de informaticaCuaderno de informatica
Cuaderno de informaticak_laf
 
Guia de estudio para el primer examen computacion 1
Guia de estudio para  el primer  examen computacion 1Guia de estudio para  el primer  examen computacion 1
Guia de estudio para el primer examen computacion 1soniagomezmorales
 
Taller modelo entidad relacion
Taller modelo entidad relacionTaller modelo entidad relacion
Taller modelo entidad relacionBrayan Vega Diaz
 
Ejercicio completo colegio
Ejercicio completo colegioEjercicio completo colegio
Ejercicio completo colegiogusanchez2668
 
10 Ways to Win at SlideShare SEO & Presentation Optimization
10 Ways to Win at SlideShare SEO & Presentation Optimization10 Ways to Win at SlideShare SEO & Presentation Optimization
10 Ways to Win at SlideShare SEO & Presentation OptimizationOneupweb
 
Masters of SlideShare
Masters of SlideShareMasters of SlideShare
Masters of SlideShareKapost
 

Destacado (20)

OCP, JSE 6 Programmer (1Z0-851) - Guia practica 6 de 7(Colecciones y Genericos)
OCP, JSE 6 Programmer (1Z0-851) - Guia practica 6 de 7(Colecciones y Genericos)OCP, JSE 6 Programmer (1Z0-851) - Guia practica 6 de 7(Colecciones y Genericos)
OCP, JSE 6 Programmer (1Z0-851) - Guia practica 6 de 7(Colecciones y Genericos)
 
Guia de estudio para Oracle Certified Java EE 6 Web Component Developer
Guia de estudio para Oracle Certified Java EE 6 Web Component DeveloperGuia de estudio para Oracle Certified Java EE 6 Web Component Developer
Guia de estudio para Oracle Certified Java EE 6 Web Component Developer
 
documento para contestar la Guia de estudio informatica 1
documento para contestar la Guia de estudio informatica 1documento para contestar la Guia de estudio informatica 1
documento para contestar la Guia de estudio informatica 1
 
Guia de estudio OCA Java SE 7 Programmer
Guia de estudio OCA Java SE 7 ProgrammerGuia de estudio OCA Java SE 7 Programmer
Guia de estudio OCA Java SE 7 Programmer
 
Guia informatica 2014
Guia informatica 2014Guia informatica 2014
Guia informatica 2014
 
ejercicios diseño:_entidad relación en la creación de una BD
ejercicios diseño:_entidad relación en la creación de una BDejercicios diseño:_entidad relación en la creación de una BD
ejercicios diseño:_entidad relación en la creación de una BD
 
Java y Bases de Datos
Java y Bases de DatosJava y Bases de Datos
Java y Bases de Datos
 
Problemas de diseño de base de datos
Problemas de diseño de base de datosProblemas de diseño de base de datos
Problemas de diseño de base de datos
 
Transformación de Modelo E-R a Modelo Relacional Ejemplo y Reporte
Transformación de Modelo E-R a Modelo Relacional Ejemplo y ReporteTransformación de Modelo E-R a Modelo Relacional Ejemplo y Reporte
Transformación de Modelo E-R a Modelo Relacional Ejemplo y Reporte
 
Transformar modelo entidad relacion a modelo logico
Transformar modelo entidad relacion a modelo logicoTransformar modelo entidad relacion a modelo logico
Transformar modelo entidad relacion a modelo logico
 
Enunciados de casos para Bases de Datos
Enunciados de casos para Bases de DatosEnunciados de casos para Bases de Datos
Enunciados de casos para Bases de Datos
 
Guia practica funciones en java con NetBeans
Guia practica funciones en java con NetBeansGuia practica funciones en java con NetBeans
Guia practica funciones en java con NetBeans
 
Cuaderno de informatica
Cuaderno de informaticaCuaderno de informatica
Cuaderno de informatica
 
Guia de estudio para el primer examen computacion 1
Guia de estudio para  el primer  examen computacion 1Guia de estudio para  el primer  examen computacion 1
Guia de estudio para el primer examen computacion 1
 
Taller modelo entidad relacion
Taller modelo entidad relacionTaller modelo entidad relacion
Taller modelo entidad relacion
 
Guia informática 2 contestada
Guia informática 2   contestadaGuia informática 2   contestada
Guia informática 2 contestada
 
Ejemplos de entidad relacion
Ejemplos de entidad relacionEjemplos de entidad relacion
Ejemplos de entidad relacion
 
Ejercicio completo colegio
Ejercicio completo colegioEjercicio completo colegio
Ejercicio completo colegio
 
10 Ways to Win at SlideShare SEO & Presentation Optimization
10 Ways to Win at SlideShare SEO & Presentation Optimization10 Ways to Win at SlideShare SEO & Presentation Optimization
10 Ways to Win at SlideShare SEO & Presentation Optimization
 
Masters of SlideShare
Masters of SlideShareMasters of SlideShare
Masters of SlideShare
 

Similar a Algoritmos

Compiladores java a_tope
Compiladores java a_topeCompiladores java a_tope
Compiladores java a_topeEmmanuel Lara
 
ApuntesC++.pdf
ApuntesC++.pdfApuntesC++.pdf
ApuntesC++.pdfbilgrado01
 
Vba excel numericos
Vba excel numericosVba excel numericos
Vba excel numericosJOHN BONILLA
 
Programacion en Phyton desde ce..........................ro
Programacion en Phyton desde ce..........................roProgramacion en Phyton desde ce..........................ro
Programacion en Phyton desde ce..........................roMa Florencia Ferrari
 
Matematicas en ingenieria_con_matlab_y_o
Matematicas en ingenieria_con_matlab_y_oMatematicas en ingenieria_con_matlab_y_o
Matematicas en ingenieria_con_matlab_y_oriberthancco
 
Fundamentos de Programacion.pdf
Fundamentos de Programacion.pdfFundamentos de Programacion.pdf
Fundamentos de Programacion.pdfJorge Serran
 
Introducción a la programación en c
Introducción a la programación en cIntroducción a la programación en c
Introducción a la programación en cvictdiazm
 
pensar_en_cpp-vol1.pdf
pensar_en_cpp-vol1.pdfpensar_en_cpp-vol1.pdf
pensar_en_cpp-vol1.pdfmacario17
 
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdfLibro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdfJavier Perez
 

Similar a Algoritmos (20)

Compiladores java a_tope
Compiladores java a_topeCompiladores java a_tope
Compiladores java a_tope
 
ApuntesC++.pdf
ApuntesC++.pdfApuntesC++.pdf
ApuntesC++.pdf
 
Vba excel mnumericos1
Vba excel mnumericos1Vba excel mnumericos1
Vba excel mnumericos1
 
Vba excel mnumericos
Vba excel mnumericosVba excel mnumericos
Vba excel mnumericos
 
Vba excel numericos
Vba excel numericosVba excel numericos
Vba excel numericos
 
Scd 13-14 todo
Scd 13-14 todoScd 13-14 todo
Scd 13-14 todo
 
Teoriapto
TeoriaptoTeoriapto
Teoriapto
 
Libro logica
Libro logicaLibro logica
Libro logica
 
Guia_Analisis_Exp.pdf
Guia_Analisis_Exp.pdfGuia_Analisis_Exp.pdf
Guia_Analisis_Exp.pdf
 
Linux benchmarking como
Linux benchmarking comoLinux benchmarking como
Linux benchmarking como
 
Programacion en Phyton desde ce..........................ro
Programacion en Phyton desde ce..........................roProgramacion en Phyton desde ce..........................ro
Programacion en Phyton desde ce..........................ro
 
Matematicas en ingenieria_con_matlab_y_o
Matematicas en ingenieria_con_matlab_y_oMatematicas en ingenieria_con_matlab_y_o
Matematicas en ingenieria_con_matlab_y_o
 
Fundamentos de Programacion.pdf
Fundamentos de Programacion.pdfFundamentos de Programacion.pdf
Fundamentos de Programacion.pdf
 
Introducción a la programación en C
Introducción a la programación en CIntroducción a la programación en C
Introducción a la programación en C
 
Introducción a la programación en c
Introducción a la programación en cIntroducción a la programación en c
Introducción a la programación en c
 
pensar_en_cpp-vol1.pdf
pensar_en_cpp-vol1.pdfpensar_en_cpp-vol1.pdf
pensar_en_cpp-vol1.pdf
 
Libro logica
Libro logicaLibro logica
Libro logica
 
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdfLibro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
 
Intro2
Intro2Intro2
Intro2
 
Intro progvb
Intro progvbIntro progvb
Intro progvb
 

Algoritmos

  • 2.
  • 3. ´ Indice Presentaci´n o xix Tema I Algoritmos e introducci´n a Pascal o 1 Cap´ ıtulo 1 Problemas, algoritmos y programas 3 1.1 Soluci´n de problemas mediante programas . . . . . . . . . . . . o 3 1.2 Concepto de algoritmo . . . . . . . . . . . . . . . . . . . . . . . . 5 1.2.1 Una definici´n de algoritmo . . . . . . . . . . . . . . . . . o 6 1.2.2 Una definici´n formal de algoritmo . . . . . . . . . . . . . o 8 1.3 Aspectos de inter´s sobre los algoritmos . . . . . . . . . . . . . . e 11 1.3.1 Computabilidad . . . . . . . . . . . . . . . . . . . . . . . 11 1.3.2 Correcci´n de algoritmos o . . . . . . . . . . . . . . . . . . 14 1.3.3 Complejidad de algoritmos . . . . . . . . . . . . . . . . . 15 1.4 Lenguajes algor´ ıtmicos y de programaci´n . . . . . . . . . . . . . o 16 1.5 Desarrollo sistem´tico de programas . . . . . . . . . . . . . . . . a 18 1.6 Conclusi´n o . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 1.7 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 1.8 Referencias bibliogr´ficas a . . . . . . . . . . . . . . . . . . . . . . 21 Cap´ ıtulo 2 El lenguaje de programaci´n Pascal o 23 2.1 Introducci´n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . o 23 2.2 Otros detalles de inter´s . . . . . . . . . . . . . . . . . . . . . . . e 24 2.3 Origen y evoluci´n del lenguaje Pascal . . . . . . . . . . . . . . . o 24 2.4 Pascal y Turbo Pascal . . . . . . . . . . . . . . . . . . . . . . . . 25 Cap´ ıtulo 3 Tipos de datos b´sicos a 27 3.1 Introducci´n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . o 28
  • 4. viii ´ Indice 3.2 El tipo integer . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 3.3 El tipo real . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 3.4 El tipo char . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 3.5 El tipo boolean . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 3.6 Observaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 3.7 El tipo de una expresi´n . . . . . . . . . . . . . . . . . . . . . . . o 43 3.8 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 ıtulo 4 Cap´ Elementos b´sicos del lenguaje a 47 4.1 Un ejemplo introductorio . . . . . . . . . . . . . . . . . . . . . . 47 4.2 Vocabulario b´sico . . . . . . . . . . . . . . . . . . . . . . . . . . a 48 4.2.1 Constantes y variables . . . . . . . . . . . . . . . . . . . . 52 4.3 Instrucciones b´sicas . . . . . . . . . . . . . . . . . . . . . . . . . a 52 4.3.1 Asignaci´n . . . . . . . . . . . . . . . . . . . . . . . . . . o 52 4.3.2 Instrucciones de escritura . . . . . . . . . . . . . . . . . . 54 4.3.3 Instrucciones de lectura . . . . . . . . . . . . . . . . . . . 57 4.4 Partes de un programa . . . . . . . . . . . . . . . . . . . . . . . . 59 4.4.1 Encabezamiento . . . . . . . . . . . . . . . . . . . . . . . 59 4.4.2 Declaraciones y definiciones . . . . . . . . . . . . . . . . . 60 4.4.3 Cuerpo del programa . . . . . . . . . . . . . . . . . . . . . 62 4.4.4 Conclusi´n: estructura general de un programa . . . . . . o 63 4.5 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 Cap´ ıtulo 5 Primeros programas completos 67 5.1 Algunos programas sencillos . . . . . . . . . . . . . . . . . . . . . 68 5.1.1 Dibujo de la letra ‘‘C’’ . . . . . . . . . . . . . . . . . . . . 68 5.1.2 Suma de dos n´meros . . . . . . . . . . . . . . . . . . . . u 69 5.2 Programas claros ⇒ programas de calidad . . . . . . . . . . . . . 69 5.3 Desarrollo descendente de programas . . . . . . . . . . . . . . . . 71 5.4 Desarrollo de programas correctos . . . . . . . . . . . . . . . . . 73 5.4.1 Estado de los c´mputos . . . . . . . . . . . . . . . . . . . o 73 5.4.2 Desarrollo descendente con especificaciones . . . . . . . . 78 5.5 Observaciones finales . . . . . . . . . . . . . . . . . . . . . . . . . 79 5.6 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
  • 5. ´ Indice ix Tema II Programaci´n estructurada o 83 Cap´ ıtulo 6 Instrucciones estructuradas 85 6.1 Composici´n de instrucciones . . . . . . . . . . . . . . . . . . . . o 86 6.2 Instrucciones de selecci´n . . . . . . . . . . . . . . . . . . . . . . o 88 6.2.1 La instrucci´n if-then-else . . . . . . . . . . . . . . . . . o 88 6.2.2 La instrucci´n case . . . . . . . . . . . . . . . . . . . . . o 92 6.3 Instrucciones de iteraci´n . . . . . . . . . . . . . . . . . . . . . . o 94 6.3.1 La instrucci´n while . . . . . . . . . . . . . . . . . . . . . o 94 6.3.2 La instrucci´n repeat . . . . . . . . . . . . . . . . . . . . o 98 6.3.3 La instrucci´n for . . . . . . . . . . . . . . . . . . . . . . 100 o 6.4 Dise˜o y desarrollo de bucles . . . . . . . . . . . . . . . . . . . . 103 n 6.4.1 Elecci´n de instrucciones iterativas . . . . . . . . . . . . . 103 o 6.4.2 Terminaci´n de un bucle . . . . . . . . . . . . . . . . . . . 105 o 6.4.3 Uso correcto de instrucciones estructuradas . . . . . . . . 106 6.5 Dos m´todos num´ricos iterativos . . . . . . . . . . . . . . . . . . 113 e e 6.5.1 M´todo de bipartici´n . . . . . . . . . . . . . . . . . . . . 113 e o 6.5.2 M´todo de Newton-Raphson . . . . . . . . . . . . . . . . 115 e 6.5.3 Inversi´n de funciones . . . . . . . . . . . . . . . . . . . . 117 o 6.6 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 Cap´ ıtulo 7 Programaci´n estructurada o 123 7.1 Introducci´n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 o 7.2 Aspectos te´ricos . . . . . . . . . . . . . . . . . . . . . . . . . . . 125 o 7.2.1 Programas y diagramas de flujo . . . . . . . . . . . . . . . 125 7.2.2 Diagramas y diagramas propios . . . . . . . . . . . . . . . 126 7.2.3 Diagramas BJ (de B¨hm y Jacopini) . . . . . . . . . . . . 130 o 7.2.4 Equivalencia de diagramas . . . . . . . . . . . . . . . . . . 135 7.2.5 Teoremas de la programaci´n estructurada . . . . . . . . 137 o 7.2.6 Recapitulaci´n . . . . . . . . . . . . . . . . . . . . . . . . 138 o 7.3 Aspectos metodol´gicos . . . . . . . . . . . . . . . . . . . . . . . 139 o 7.3.1 Seudoc´digo . . . . . . . . . . . . . . . . . . . . . . . . . . 139 o 7.3.2 Dise˜o descendente . . . . . . . . . . . . . . . . . . . . . . 141 n 7.4 Refinamiento correcto de programas con instrucciones estructuradas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
  • 6. x ´ Indice 7.4.1 Un ejemplo detallado . . . . . . . . . . . . . . . . . . . . 147 7.4.2 Recapitulaci´n . . . . . . . . . . . . . . . . . . . . . . . . 150 o 7.5 Conclusi´n o . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 7.6 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 7.7 Referencias bibliogr´ficas a . . . . . . . . . . . . . . . . . . . . . . 153 Tema III Subprogramas 155 Cap´ ıtulo 8 Procedimientos y funciones 157 8.1 Introducci´n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158 o 8.2 Subprogramas con par´metros . . . . . . . . . . . . . . . . . . . . 162 a 8.2.1 Descripci´n de un subprograma con par´metros . . . . . . 162 o a 8.2.2 Par´metros formales y reales . . . . . . . . . . . . . . . . 165 a 8.2.3 Mecanismos de paso de par´metros . . . . . . . . . . . . . 165 a 8.2.4 Consistencia entre definici´n y llamada o . . . . . . . . . . 168 8.3 Estructura sint´ctica de un subprograma . . . . . . . . . . . . . . 169 a 8.4 Funcionamiento de una llamada . . . . . . . . . . . . . . . . . . . 170 8.5 ´ Ambito y visibilidad de los identificadores . . . . . . . . . . . . . 174 8.5.1 Tipos de identificadores seg´n su ´mbito . . . . . . . . . . 174 u a 8.5.2 Estructura de bloques . . . . . . . . . . . . . . . . . . . . 175 8.5.3 Criterios de localidad . . . . . . . . . . . . . . . . . . . . 181 8.5.4 Efectos laterales . . . . . . . . . . . . . . . . . . . . . . . 181 8.6 Otras recomendaciones sobre el uso de par´metros . . . . . . . . 183 a 8.6.1 Par´metros por valor y por referencia . . . . . . . . . . . 183 a 8.6.2 Par´metros por referencia y funciones . . . . . . . . . . . 183 a 8.6.3 Funciones con resultados m´ltiples . . . . . . . . . . . . . 184 u 8.7 Desarrollo correcto de subprogramas . . . . . . . . . . . . . . . . 184 8.8 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186 Cap´ ıtulo 9 Aspectos metodol´gicos de la programaci´n con o o subprogramas 189 9.1 Introducci´n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189 o 9.2 Un ejemplo de referencia . . . . . . . . . . . . . . . . . . . . . . . 190 9.3 Metodolog´ de la programaci´n con subprogramas . . . . . . . . 192 ıa o 9.3.1 Dise˜o descendente con subprogramas . . . . . . . . . . . 193 n
  • 7. ´ Indice xi 9.3.2 Programa principal y subprogramas . . . . . . . . . . . . 194 9.3.3 Documentaci´n de los subprogramas . . . . . . . . . . . . 195 o 9.3.4 Tama˜o de los subprogramas . . . . . . . . . . . . . . . . 196 n 9.3.5 Refinamiento con subprogramas y con instrucciones estructuradas . . . . . . . . . . . . . . . . . . . . . . . . . 197 9.4 Estructura jer´rquica de los subprogramas . . . . . . . . . . . . . 199 a 9.5 Ventajas de la programaci´n con subprogramas . . . . . . . . . . 201 o 9.6 Un ejemplo detallado: representaci´n de funciones . . . . . . . . 203 o 9.7 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207 Cap´ ıtulo 10 Introducci´n a la recursi´n o o 211 10.1 Un ejemplo de referencia . . . . . . . . . . . . . . . . . . . . . . . 212 10.2 Conceptos b´sicos . . . . . . . . . . . . . . . . . . . . . . . . . . 213 a 10.3 Otros ejemplos recursivos . . . . . . . . . . . . . . . . . . . . . . 216 10.3.1 La sucesi´n de Fibonacci . . . . . . . . . . . . . . . . . . 216 o 10.3.2 Torres de Hanoi . . . . . . . . . . . . . . . . . . . . . . . 216 10.3.3 Funci´n de Ackermann . . . . . . . . . . . . . . . . . . . . 219 o 10.4 Correcci´n de subprogramas recursivos . . . . . . . . . . . . . . . 219 o 10.4.1 Principios de inducci´n . . . . . . . . . . . . . . . . . . . 220 o 10.5 Recursi´n mutua . . . . . . . . . . . . . . . . . . . . . . . . . . . 222 o 10.6 Recursi´n e iteraci´n . . . . . . . . . . . . . . . . . . . . . . . . . 226 o o 10.7 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227 10.8 Referencias bibliogr´ficas a . . . . . . . . . . . . . . . . . . . . . . 228 Tema IV Tipos de datos definidos por el programador 231 Cap´ ıtulo 11 Tipos de datos simples y compuestos 233 11.1 Tipos ordinales definidos por el programador . . . . . . . . . . . 234 11.1.1 Tipos enumerados . . . . . . . . . . . . . . . . . . . . . . 235 11.1.2 Tipo subrango . . . . . . . . . . . . . . . . . . . . . . . . 238 11.2 Definici´n de tipos . . . . . . . . . . . . . . . . . . . . . . . . . . 240 o 11.2.1 Observaciones sobre la definici´n de tipos . . . . . . . . . 242 o 11.3 Conjuntos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244 11.3.1 Operaciones sobre el tipo conjunto . . . . . . . . . . . . . 245 11.3.2 Observaciones sobre el tipo conjunto . . . . . . . . . . . . 247
  • 8. xii ´ Indice 11.3.3 Un ejemplo de aplicaci´n . . . . . . . . . . . . . . . . . . 248 o 11.4 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250 Cap´ ıtulo 12 Arrays 253 12.1 Descripci´n del tipo de datos array . . . . . . . . . . . . . . . . . 253 o 12.1.1 Operaciones del tipo array y acceso a sus componentes . . 257 12.1.2 Caracter´ ısticas generales de un array . . . . . . . . . . . . 260 12.2 Vectores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261 12.3 Matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263 12.4 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268 ıtulo 13 Registros Cap´ 271 13.1 Descripci´n del tipo de datos registro . . . . . . . . . . . . . . . . 271 o 13.1.1 Manejo de registros: acceso a componentes y operaciones . 273 13.1.2 Registros con variantes . . . . . . . . . . . . . . . . . . . . 276 13.2 Arrays de registros y registros de arrays . . . . . . . . . . . . . . 279 13.3 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282 Cap´ ıtulo 14 Archivos 285 14.1 Descripci´n del tipo de datos archivo . . . . . . . . . . . . . . . . 285 o 14.2 Manejo de archivos en Pascal . . . . . . . . . . . . . . . . . . . . 286 14.2.1 Operaciones con archivos . . . . . . . . . . . . . . . . . . 288 14.3 Archivos de texto . . . . . . . . . . . . . . . . . . . . . . . . . . . 294 14.4 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298 Cap´ ıtulo 15 Algoritmos de b´ squeda y ordenaci´n u o 301 15.1 Algoritmos de b´squeda en arrays . . . . . . . . . . . . . . . . . 301 u 15.1.1 B´squeda secuencial . . . . . . . . . . . . . . . . . . . . . 302 u 15.1.2 B´squeda secuencial ordenada u . . . . . . . . . . . . . . . 304 15.1.3 B´squeda binaria . . . . . . . . . . . . . . . . . . . . . . . 304 u 15.2 Ordenaci´n de arrays . . . . . . . . . . . . . . . . . . . . . . . . . 306 o 15.2.1 Selecci´n directa . . . . . . . . . . . . . . . . . . . . . . . 307 o 15.2.2 Inserci´n directa . . . . . . . . . . . . . . . . . . . . . . . 309 o 15.2.3 Intercambio directo . . . . . . . . . . . . . . . . . . . . . . 310 15.2.4 Ordenaci´n r´pida (Quick Sort) . . . . . . . . . . . . . . 312 o a 15.2.5 Ordenaci´n por mezcla (Merge Sort) . . . . . . . . . . . . 316 o
  • 9. ´ Indice xiii 15.2.6 Vectores paralelos . . . . . . . . . . . . . . . . . . . . . . 318 15.3 Algoritmos de b´squeda en archivos secuenciales . . . . . . . . . 320 u 15.3.1 B´squeda en archivos arbitrarios . . . . . . . . . . . . . . 321 u 15.3.2 B´squeda en archivos ordenados . . . . . . . . . . . . . . 321 u 15.4 Mezcla y ordenaci´n de archivos secuenciales . . . . . . . . . . . 322 o 15.5 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329 15.6 Referencias bibliogr´ficas a . . . . . . . . . . . . . . . . . . . . . . 330 Tema V Memoria din´mica a 333 Cap´ ıtulo 16 Punteros 335 16.1 Introducci´n al uso de punteros . . . . . . . . . . . . . . . . . . . 336 o 16.1.1 Definici´n y declaraci´n de punteros . . . . . . . . . . . . 337 o o 16.1.2 Generaci´n y destrucci´n de variables din´micas . . . . . 338 o o a 16.1.3 Operaciones b´sicas con datos apuntados . . . . . . . . . 339 a 16.1.4 Operaciones b´sicas con punteros . . . . . . . . . . . . . . 341 a 16.1.5 El valor nil . . . . . . . . . . . . . . . . . . . . . . . . . . 343 16.2 Aplicaciones no recursivas de los punteros . . . . . . . . . . . . . 344 16.2.1 Asignaci´n de objetos no simples . . . . . . . . . . . . . . 345 o 16.2.2 Funciones de resultado no simple . . . . . . . . . . . . . . 346 16.3 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348 Cap´ ıtulo 17 Estructuras de datos recursivas 351 17.1 Estructuras recursivas lineales: las listas enlazadas . . . . . . . . 351 17.1.1 Una definici´n del tipo lista . . . . . . . . . . . . . . . . . 352 o 17.1.2 Inserci´n de elementos . . . . . . . . . . . . . . . . . . . . 353 o 17.1.3 Eliminaci´n de elementos . . . . . . . . . . . . . . . . . . 355 o 17.1.4 Algunas funciones recursivas . . . . . . . . . . . . . . . . 355 17.1.5 Otras operaciones sobre listas . . . . . . . . . . . . . . . . 358 17.2 Pilas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362 17.2.1 Definici´n de una pila como lista enlazada . . . . . . . . . 363 o 17.2.2 Operaciones b´sicas sobre las pilas . . . . . . . . . . . . . 363 a 17.2.3 Aplicaciones . . . . . . . . . . . . . . . . . . . . . . . . . . 365 17.3 Colas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370 17.3.1 Definici´n del tipo cola o . . . . . . . . . . . . . . . . . . . 371
  • 10. xiv ´ Indice 17.3.2 Operaciones b´sicas . . . . . . . . . . . . . . . . . . . . . 371 a 17.3.3 Aplicaci´n: gesti´n de la caja de un supermercado . . . . 374 o o ´ 17.4 Arboles binarios . . . . . . . . . . . . . . . . . . . . . . . . . . . 376 17.4.1 Recorrido de un ´rbol binario . . . . . . . . . . . . . . . . 378 a ´ 17.4.2 Arboles de b´squeda . . . . . . . . . . . . . . . . . . . . . 379 u 17.4.3 Aplicaciones . . . . . . . . . . . . . . . . . . . . . . . . . . 383 17.5 Otras estructuras din´micas de datos . . . . . . . . . . . . . . . . 387 a 17.6 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389 17.7 Referencias bibliogr´ficas a . . . . . . . . . . . . . . . . . . . . . . 391 Tema VI Aspectos avanzados de programaci´n o 393 Cap´ ıtulo 18 Complejidad algor´ ıtmica 395 18.1 Conceptos b´sicos . . . . . . . . . . . . . . . . . . . . . . . . . . 396 a 18.2 Medidas del comportamiento asint´tico . . . . . . . . . . . . . . 402 o 18.2.1 Comportamiento asint´tico . . . . . . . . . . . . . . . . . 402 o 18.2.2 Notaci´n O may´scula (una cota superior) o u . . . . . . . . 404 18.2.3 Notaci´n Ω may´scula (una cota inferior) . . . . . . . . . 405 o u 18.2.4 Notaci´n Θ may´scula (orden de una funci´n) . . . . . . 405 o u o 18.2.5 Propiedades de O, Ω y Θ . . . . . . . . . . . . . . . . . . 406 18.2.6 Jerarqu´ de ´rdenes de frecuente aparici´n . . . . . . . . 407 ıa o o 18.3 Reglas pr´cticas para hallar el coste de un programa . . . . . . . 408 a 18.3.1 Tiempo empleado . . . . . . . . . . . . . . . . . . . . . . 408 18.3.2 Ejemplos . . . . . . . . . . . . . . . . . . . . . . . . . . . 411 18.3.3 Espacio de memoria empleado . . . . . . . . . . . . . . . 417 ´ 18.4 Utiles matem´ticos . . . . . . . . . . . . . . . . . . . . . . . . . . 418 a 18.4.1 F´rmulas con sumatorios . . . . . . . . . . . . . . . . . . 419 o 18.4.2 Sucesiones de recurrencia lineales de primer orden . . . . 419 18.4.3 Sucesiones de recurrencia de orden superior . . . . . . . . 421 18.5 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 422 18.6 Referencias bibliogr´ficas a . . . . . . . . . . . . . . . . . . . . . . 425 Cap´ ıtulo 19 Tipos abstractos de datos 427 19.1 Introducci´n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 428 o 19.2 Un ejemplo completo . . . . . . . . . . . . . . . . . . . . . . . . . 429
  • 11. ´ Indice xv 19.2.1 Desarrollo de programas con tipos concretos de datos . . 430 19.2.2 Desarrollo de programas con tipos abstractos de datos . . 431 19.2.3 Desarrollo de tipos abstractos de datos . . . . . . . . . . . 434 19.3 Metodolog´ de la programaci´n de TADs . . . . . . . . . . . . . 440 ıa o 19.3.1 Especificaci´n de tipos abstractos de datos . . . . . . . . 440 o 19.3.2 Implementaci´n de tipos abstractos de datos . . . . . . . 441 o 19.3.3 Correcci´n de tipos abstractos de datos . . . . . . . . . . 443 o 19.4 Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 446 19.5 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 447 19.6 Referencias bibliogr´ficas a . . . . . . . . . . . . . . . . . . . . . . 448 Cap´ ıtulo 20 Esquemas algor´ ıtmicos fundamentales 449 20.1 Algoritmos devoradores . . . . . . . . . . . . . . . . . . . . . . . 450 20.1.1 Descripci´n . . . . . . . . . . . . . . . . . . . . . . . . . . 450 o 20.1.2 Adecuaci´n al problema . . . . . . . . . . . . . . . . . . . 451 o 20.1.3 Otros problemas resueltos vorazmente . . . . . . . . . . . 452 20.2 Divide y vencer´s . . . . . . . . . . . . . . . . . . . . . . . . . . . 453 a 20.2.1 Equilibrado de los subproblemas . . . . . . . . . . . . . . 454 20.3 Programaci´n din´mica . . . . . . . . . . . . . . . . . . . . . . . 455 o a 20.3.1 Problemas de programaci´n din´mica . . . . . . . . . . . 455 o a 20.3.2 Mejora de este esquema . . . . . . . . . . . . . . . . . . . 457 20.3.3 Formulaci´n de problemas de programaci´n din´mica . . 460 o o a 20.4 Vuelta atr´s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462 a 20.4.1 Mejora del esquema de vuelta atr´s a . . . . . . . . . . . . 466 20.5 Anexo: algoritmos probabilistas . . . . . . . . . . . . . . . . . . . 468 20.5.1 B´squeda de una soluci´n aproximada . . . . . . . . . . . 468 u o 20.5.2 B´squeda de una soluci´n probablemente correcta . . . . 469 u o 20.6 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 470 20.7 Referencias bibliogr´ficas a . . . . . . . . . . . . . . . . . . . . . . 473 Ap´ndices e 475 Ap´ndice A Aspectos complementarios de la programaci´n e o 477 A.1 Subprogramas como par´metros . . . . . . . . . . . . . . . . . . . 477 a A.1.1 Ejemplo 1: derivada . . . . . . . . . . . . . . . . . . . . . 479
  • 12. xvi ´ Indice A.1.2 Ejemplo 2: bipartici´n . . . . . . . . . . . . . . . . . . . . 480 o A.1.3 Ejemplo 3: transformaci´n de listas . . . . . . . . . . . . 482 o A.2 Variables aleatorias . . . . . . . . . . . . . . . . . . . . . . . . . . 482 A.2.1 Generaci´n de n´meros aleatorios en Turbo Pascal . . . . 483 o u A.2.2 Simulaci´n de variables aleatorias . . . . . . . . . . . . . . 484 o A.2.3 Ejemplos de aplicaci´n . . . . . . . . . . . . . . . . . . . . 486 o A.3 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 488 A.4 Referencias bibliogr´ficas a . . . . . . . . . . . . . . . . . . . . . . 490 Ap´ndice B El lenguaje Turbo Pascal e 491 B.1 Elementos l´xicos . . . . . . . . . . . . . . . . . . . . . . . . . . . 492 e B.2 Estructura del programa . . . . . . . . . . . . . . . . . . . . . . . 492 B.3 Datos num´ricos enteros . . . . . . . . . . . . . . . . . . . . . . . 492 e B.4 Datos num´ricos reales . . . . . . . . . . . . . . . . . . . . . . . . 493 e B.5 Cadenas de caracteres . . . . . . . . . . . . . . . . . . . . . . . . 494 B.5.1 Declaraci´n de cadenas . . . . . . . . . . . . . . . . . . . 494 o B.5.2 Operadores de cadenas . . . . . . . . . . . . . . . . . . . . 495 B.5.3 Funciones de cadenas . . . . . . . . . . . . . . . . . . . . 496 B.5.4 Procedimientos de cadenas . . . . . . . . . . . . . . . . . 496 B.6 Tipos de datos estructurados . . . . . . . . . . . . . . . . . . . . 498 B.7 Instrucciones estructuradas . . . . . . . . . . . . . . . . . . . . . 498 B.8 Paso de subprogramas como par´metros . . . . . . . . . . . . . . 499 a B.9 Archivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 500 B.10 Memoria din´mica . . . . . . . . . . . . . . . . . . . . . . . . . . 501 a B.11 Unidades . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 501 B.11.1 Unidades predefinidas de Turbo Pascal . . . . . . . . . . . 502 B.11.2 Unidades definidas por el usuario . . . . . . . . . . . . . . 503 B.11.3 Modularidad incompleta de Turbo Pascal . . . . . . . . . 505 Ap´ndice C El entorno integrado de desarrollo e 507 C.1 Descripci´n del entorno . . . . . . . . . . . . . . . . . . . . . . . 507 o C.2 Desarrollo completo de un programa en Turbo Pascal . . . . . . 508 C.2.1 Arranque del entorno . . . . . . . . . . . . . . . . . . . . 508 C.2.2 Edici´n del programa fuente . . . . . . . . . . . . . . . . . 510 o C.2.3 Grabar el programa fuente y seguir editando . . . . . . . 510
  • 13. ´ Indice xvii C.2.4 Compilaci´n o . . . . . . . . . . . . . . . . . . . . . . . . . 512 C.2.5 Ejecuci´n . . . . . . . . . . . . . . . . . . . . . . . . . . . 514 o C.2.6 Depuraci´n . . . . . . . . . . . . . . . . . . . . . . . . . . 514 o C.2.7 Salida de Turbo Pascal . . . . . . . . . . . . . . . . . . . . 516 C.3 Otros men´s y opciones . . . . . . . . . . . . . . . . . . . . . . . 517 u C.3.1 Search (B´squeda) . . . . . . . . . . . . . . . . . . . . . . 517 u C.3.2 Tools (Herramientas) . . . . . . . . . . . . . . . . . . . . . 517 C.3.3 Options (Opciones) . . . . . . . . . . . . . . . . . . . . . . 517 C.3.4 Window (Ventana) . . . . . . . . . . . . . . . . . . . . . . 519 C.3.5 Help (Ayuda) . . . . . . . . . . . . . . . . . . . . . . . . . 519 C.4 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 519 C.5 Referencias bibliogr´ficas a . . . . . . . . . . . . . . . . . . . . . . 520 Bibliograf´ ıa 521 ´ Indice alfab´tico e 527
  • 14.
  • 15. Presentaci´n o Este libro trata sobre m´todos de resoluci´n de problemas mediante el desa- e o rrollo de algoritmos y estructuras de datos, desde el principio y paso a paso, y su materializaci´n en programas de computador. o Desde luego, no es el primer libro sobre este tema; de hecho, ha habido en los ultimos quince a˜os un gran aluvi´n de textos sobre algoritmos y sobre ´ n o programaci´n. La raz´n para ello ha sido sin lugar a dudas doble: por un o o lado, la difusi´n que estos temas han tenido y siguen teniendo, integr´ndose o a en los estudios m´s diversos; por otro, la evoluci´n que est´ experimentando el a o a desarrollo de algoritmos y programas, pasando de ser un arte (reinventado por cada programador a base de t´cnicas personales, estrechamente vinculadas con e su lenguaje de programaci´n) a una actividad m´s cient´ o a ıfica, metodol´gica y o disciplinada. Por consiguiente, resulta necesario aclarar cu´l es el enfoque adoptado en este a libro. Examinando la bibliograf´ existente actualmente sobre programaci´n a ıa o un nivel introductorio permite afirmar las siguientes conclusiones: • Una parte importante de los libros existentes han adoptado un enfoque pr´ctico puro, no metodol´gico, que es el m´s tradicional, y a´n subsiste a o a u en demasiados libros. Se confunde la ense˜anza de la programaci´n con n o la de un lenguaje concreto, ofreciendo muchas veces un mero “manual de referencia” del lenguaje elegido. Bajo el atractivo de los llamativos resultados inmediatos (programas que funcionan), este enfoque ignora la base conceptual y metodol´gica necesaria, y propicia los peores h´bitos de o a programaci´n, que son adem´s dif´ o a ıciles de erradicar. • Otra postura extrema se centra en el an´lisis y desarrollo de soluciones a algor´ıtmicas puras, de forma independiente de cualquier lenguaje de pro- gramaci´n. Esta independencia permite ignorar las peculiaridades de los o lenguajes reales, yendo a los conceptos; sin embargo, esa independencia de los lenguajes de programaci´n es a nuestro entender innecesaria e inconve- o niente en los primeros pasos, ya que obliga al aprendiz de la programaci´n o a estudiar aparte los detalles concretos del lenguaje de programaci´n con o que necesariamente debe desarrollar sus pr´cticas. a
  • 16. xx ´ Presentacion En cambio, encontramos este enfoque interesante en niveles superiores de la ense˜anza de la programaci´n, donde interesa concentrarse en los con- n o ceptos, m´s dif´ a ıciles y donde ya no supone obst´culo alguno expresar las a ideas en cualquier lenguaje de programaci´n. o El enfoque adoptado en este libro recoge ambos aspectos: por un lado, viene a cubrir la necesidad de un enfoque metodol´gico en el aprendizaje y en el ejercicio o de la programaci´n, pero tambi´n la necesidad de experimentar con programas o e concretos, expresarlos en un lenguaje real y hacerlos funcionar con un traduc- tor concreto. En resumen, intentamos compaginar las ventajas de los enfoques anteriores, presentando la base conceptual y metodol´gica necesaria para desa- o rrollar los algoritmos de forma razonada y disciplinada, sin olvidar por ello la conveniencia de expresarlos en un lenguaje de programaci´n, materializ´ndolos o a y experimentando con ellos, y que el lector ha de ser instruido tambi´n en esta e tarea. En relaci´n con el enfoque metodol´gico que se impone actualmente, se con- o o sidera necesario atender a la correcci´n de los programas. El tratamiento que o se le da en la literatura ha llevado nuevamente a dos posturas artificialmente extremas: • Algunos autores ignoran completamente el estudio de la correcci´n, con- o tent´ndose con algunas comprobaciones para deducir que un programa es a correcto. • En cambio, otros adoptan un tratamiento exhaustivo, utilizando t´cnicas e formales de especificaci´n o verificaci´n. o o A nuestro entender, es incuestionable la importancia de garantizar que los programas desarrollados funcionar´n de la forma deseada. Sin embargo, la ve- a rificaci´n formal de los programas de cierto tama˜o es impracticable. Por ello, o n asumimos de nuevo una posici´n intermedia y realista consistente en los siguien- o tes planteamientos: • Plantear el desarrollo de programas correctos con el empleo de t´cnicas e semiformales. • Limitar el estudio de la correcci´n a los elementos que resulten delicados, o bien por su dificultad o por su novedad. • Atender a la correcci´n de los algoritmos durante su desarrollo en lugar de o a posteriori. Esta idea resulta ser una ayuda esencial en el aprendizaje de la programaci´n. o
  • 17. ´ Presentacion xxi En resumidas cuentas, este libro va dirigido a aqu´llos que desean introdu- e cirse en la programaci´n, con una base s´lida, con una buena metodog´ de o o ıa dise˜o y desarrollo de programas correctos y con h´bitos disciplinados desde una n a perspectiva realista y pragm´tica. Se presentan las t´cnicas con un cierto ni- a e vel de abstracci´n para identificar los conceptos esenciales e independientes del o lenguaje de programaci´n empleado, y al mismo tiempo se aterriza expresando o estas t´cnicas en un lenguaje concreto. e El lenguaje escogido para estas implementaciones ha sido Pascal. Esta elec- ci´n se debe a que este lenguaje es simple y tiene una sintaxis sencilla, que o hace que sea f´cil de aprender, y al mismo tiempo es lo bastante completo como a para plasmar las diferentes t´cnicas y m´todos necesarios en programas de com- e e plejidad media-alta. Esto lo hace una herramienta pedag´gica id´nea para el o o aprendizaje de la programaci´n. A todo esto hay que sumar las numerosas im- o plementaciones existentes y su accesibilidad, as´ como su evoluci´n y continua ı o puesta al d´ para permitir t´cnicas de programaci´n actuales (por ejemplo, mo- ıa e o dular u orientada a los objetos) y su gran difusi´n y aceptaci´n en el ambito o o ´ acad´mico. e Organizaci´n del libro o El libro est´ estructurado en siete partes. En cada una de ellas se estudian a las t´cnicas y mecanismos nuevos, conceptualmente primero, detallando luego e su tratamiento en Pascal y, finalmente, compaginando ambas facetas con el as- pecto metodol´gico. Cada tema se ha dividido en varios cap´ o ıtulos para evitar una excesiva fragmentaci´n. En cada cap´ o ıtulo se ha incluido una lista de ejerci- cios propuestos de dificultad aproximadamente creciente. Al final de cada tema se desarrolla un ejemplo completo pensado para mostrar a la vez los aspectos m´s destacados del mismo, as´ como unas pocas referencias comentadas que se a ı sugieren como lecturas complementarias o de consulta. Contenido El contenido se ha seleccionado partiendo de las directrices se˜aladas en n [DCG + 89] y [Tur91]. Incluye los contenidos cursos CS1 y CS2 [GT86, KSW85] salvo los aspectos de organizaci´n de computadores, que se estudian en [PAO94], o de los mismos autores que este libro. En el primer tema se presentan, entre otros, los conceptos esenciales de algo- ritmo, dato y programa. Se introduce el lenguaje Pascal y la estructura de los programas escritos en ´l, as´ como los elementos b´sicos del lenguaje. Se incluyen e ı a
  • 18. xxii ´ Presentacion algunos programas sencillos, y se adelantan la t´cnica descendente de dise˜o de e n programas y algunos apuntes sobre la correcci´n. o El segundo tema se dedica a la programaci´n estructurada. Se pone espe- o cial ´nfasis en el dise˜o descendente o por refinamientos sucesivos partiendo de e n especificaciones escritas en pseudoc´digo, y se muestra c´mo compaginar esta o o t´cnica con la derivaci´n de programas correctos. e o En el tercer tema se estudian los subprogramas. Al igual que en el tema anterior, se detalla c´mo enfocar la correcci´n en el uso de esta t´cnica. Se o o e concluye con un cap´ ıtulo de introducci´n a la recursi´n. o o En la mayor´ de los programas no basta con los tipos de datos b´sicos, sino ıa a que es necesario que el programador defina otros m´s complejos. A ello se dedica a el cuarto tema. El quinto tema estudia las t´cnicas propias de la gesti´n de memoria din´mica. e o a Se justifica su necesidad, y se presenta su principal aplicaci´n, que es la definici´n o o de estructuras de datos recursivas. El sexto tema introduce tres aspectos avanzados: la programaci´n con tipos o abstractos de datos, el coste de los algoritmos y los principales esquemas de dise˜o de algoritmos. Aunque, ciertamente, su estudio en profundidad rebasa un n primer curso, es frecuente introducir –o siquiera mencionar– sus ideas b´sicas. a Por supuesto, siempre es altamente recomendable consultar otras referencias (nosotros mismos las seleccionamos para cada tema), pero tambi´n es cierto e que el alumno se ve obligado con frecuencia a usar varios textos b´sicos para a cubrir diferentes partes de la materia. Justamente, estos ultimos cap´ ´ ıtulos se incluyen para que el lector interesado se pueda asomar a ellos sin verse obligado a consultar los cap´ ıtulos introductorios de otros libros. Finalmente se incluyen tres ap´ndices: en el primero se introducen un par e de aspectos complementarios para un primer curso de programaci´n (el paso o de subprogramas como par´metros y el uso de variables aleatorias); el segundo a es un prontuario de uso del entorno integrado de desarrollo Turbo Pascal; y el tercero indica algunos detalles de Turbo Pascal en que se separa del est´ndar, a pero que son de uso frecuente. Notaci´n empleada o En la lectura de este texto se encontrar´n fragmentos escritos en distintos a lenguajes: • En castellano puro, donde se ha usado este tipo de letra. • En Pascal, para lo que se ha elegido el teletipo, salvo las palabras reser- vadas, que van en negrita.
  • 19. ´ Presentacion xxiii Tambi´n se ha empleado el teletipo para indicar las salidas y entradas de e datos, porque es el tipo de letra m´s parecido al que aparece en el monitor. a • En seudoc´digo, que se expresa con letra cursiva. o • En lenguaje matem´tico, en que se usan los s´ a ımbolos usuales. • Otros s´ ımbolos especiales: El espacio en blanco (v´ase la p´gina 206) e a ; Uno o m´s pasos al evaluar una expresi´n (v´ase la p´gina 30) a o e a • Fin de archivo (v´ase la p´gina 57) e a ← Fin de l´ ınea (v´ase la p´gina 57) e a Advertencia para el alumno No existe un m´todo general para resolver problemas mediante algoritmos; e por ello, es de gran importancia estudiar las t´cnicas de forma gradual, yendo e de lo f´cil a lo dif´ y vincul´ndolas con situaciones ampliamente conocidas. a ıcil a Nosotros pretendemos haber cumplido con este objetivo, proporcionando ejemplos de f´cil comprensi´n y ejercicios a la medida de lo explicado. Y eso es a o lo bueno. Lo malo es que el alumno puede percibir la sensaci´n de comprenderlo o todo a la velocidad que lee. . . y aqu´ reside el peligro. Porque una mera lectura ı del texto, o incluso una lectura atenta, no basta para asimilarlo, adquiriendo las t´cnicas necesarias para resolver otros problemas de dificultad similar a la de los e planteados. Es preciso adoptar una actitud cr´ ıtica durante la lectura, trabajar minuciosamente con los problemas propuestos e incluso tatar de imaginar solu- ciones alternativas a los ejemplos dados. Y cuanto antes se acepte esa realidad, mejor que mejor. Agradecimientos Muchas personas han contribuido de diferentes maneras a que este libro sea lo que es. En primer lugar, debemos a nuestros alumnos de estos a˜os su ayuda, n aun sin saberlo, porque ellos han sido la raz´n de que emprendi´ramos este o e trabajo, y porque sus preguntas y comentarios, d´ a d´ tienen una respuesta ıa ıa, en las p´ginas que siguen. En segundo lugar, debemos a muchos de nuestros a compa˜eros su aliento y apoyo, tan necesario cuando uno se enfrenta a un trabajo n de esta envergadura. Y por ello, lo dedicamos a ambos, alumnos y compa˜eros. n De un modo muy especial, deseamos expresar nuestro agradecimiento a Juan Falgueras Cano, Luis Antonio Gal´n Corroto y Yolanda Ortega y Mall´n por a e su cuidadosa lectura de la primera versi´n completa del manuscrito, y por sus o
  • 20. xxiv ´ Presentacion valiosos comentarios y sugerencias. No podemos olvidar tampoco la ayuda de Manuel Enciso Garc´ ıa-Oliveros en los ultimos retoques, as´ como su proximidad ´ ı y apoyo durante todo el tiempo que nos ha ocupado este trabajo. Por ultimo, deseamos expresar nuestra gratitud y cari˜o a Jos´ Luis Gal´n ´ n e a Garc´ que ha dejado en este libro muchas horas. ıa,
  • 21. Tema I Algoritmos e introducci´n a o Pascal
  • 22.
  • 23. Cap´ ıtulo 1 Problemas, algoritmos y programas 1.1 Soluci´n de problemas mediante programas . . . . . . o 3 1.2 Concepto de algoritmo . . . . . . . . . . . . . . . . . . . 5 1.3 Aspectos de inter´s sobre los algoritmos . . . . . . . . e 11 1.4 Lenguajes algor´ ıtmicos y de programaci´n . . . . . . . o 16 1.5 Desarrollo sistem´tico de programas . . . . . . . . . . a 18 1.6 Conclusi´n . . . . . . . . . . . . . . . . . . . . . . . . . . . o 20 1.7 Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 1.8 Referencias bibliogr´ficas . . . . . . . . . . . . . . . . . . a 21 En este primer cap´ıtulo se trata la resoluci´n de problemas por medio de o un computador. Puesto que ´ste no es m´s que un mero ejecutor de tareas, es e a fundamental conocer un m´todo de resoluci´n del problema en cuesti´n, esto e o o es, un algoritmo. La escritura de este algoritmo como un conjunto de ´rdenes o comprensibles por el computador es lo que se llama programa. 1.1 Soluci´n de problemas mediante programas o Los computadores desempe˜an una gran variedad de tareas, liberando as´ n ı al hombre de tener que realizarlas personalmente. Para ello, es preciso ense˜ar n al computador cu´l es su trabajo y c´mo llevarlo a cabo, esto es, programarlo, a o
  • 24. 4 Cap´ ıtulo 1. Problemas, algoritmos y programas d´ndole instrucciones precisas (programas) en un lenguaje que comprenda (Pas- a cal, Modula-2, C, etc.). Una vez “aprendido” el programa, el computador seguir´ a ciegamente sus instrucciones cuantas veces sea requerido. Precisamente, la tarea de la programaci´n consiste en describir lo que debe o hacer el computador para resolver un problema concreto en un lenguaje de pro- gramaci´n. Sin embargo, el programa es solamente el resultado de una serie de o etapas que no se pueden pasar por alto. Hablando en t´rminos muy amplios, se e identifican de momento las siguientes fases: 1. An´lisis del problema, estableciendo con precisi´n lo que se plantea. a o 2. Soluci´n conceptual del problema, describiendo un m´todo (algoritmo) que o e lo resuelva. 3. Escritura del algoritmo en un lenguaje de programaci´n. o En la primera fase es corriente partir de un problema definido vagamente, y el an´lisis del mismo consiste en precisar el enunciado, identificando los datos a de partida y los resultados que se desean obtener. La descripci´n precisa de un o problema se llama especificaci´n. Con frecuencia, el lenguaje natural no basta o para lograr la precisi´n deseada, por lo que se recurre en mayor o menor medida o a lenguajes formales, como la l´gica o las matem´ticas. Supongamos por ejemplo o a que se plantea el problema de dividir dos n´meros. En primer lugar, se necesita u saber si se trata de la divisi´n entera o de aproximar el resultado con decimales o y, en ese caso, hasta d´nde. Pongamos por caso que interesa la divisi´n eucl´ o o ıdea. Una descripci´n precisa deber´ tener en cuenta que los datos son dos enteros o a (llam´mosles dividendo y divisor, como es usual), de los que el segundo es no e nulo. El resultado es tambi´n un par de enteros (llam´mosles cociente y resto, e e como siempre) tales que dividendo = divisor ∗ cociente + resto Pero eso no es todo: si nos contentamos con ese enunciado, para todo par de enteros (dividendo, divisor), el par (0, dividendo) siempre es una soluci´n. Por o eso, hay que a˜adir que resto debe ser adem´s tal que 0 ≤ resto < divisor. n a Con este peque˜o ejemplo se pretende resaltar la importancia de analizar n bien el problema planteado, definiendo con precisi´n los requisitos que deben o verificar los datos y las condiciones en que deben estar los resultados. Sin embargo, en esta fase s´lo se ha estudiado qu´ se desea obtener, y no o e o ´ c´mo lograrlo. Este es el cometido de la segunda etapa: describir un m´todo e (algoritmo) tal que partiendo de datos apropiados lleve sistem´ticamente a los re- a sultados descritos en la especificaci´n. Del concepto de algoritmo nos ocupamos o
  • 25. 1.2. Concepto de algoritmo 5 1 2 3 ¿Est´ abierto el a Esperar Principio plazo de matr´ıcula? a ma˜ana n →2 s´ → 4 no → 3 ı →2 4 5 6 Comprar impresos Leer instrucciones. Preguntar dudas de matriculaci´n o ¿Tengo alguna duda? en Secretar´ ıa →5 s´ → 6 no → 7 ı →7 7 8 9 Rellenar el sobre Entregar el sobre y pagar en el banco Fin →9 →8 Figura 1.1. en el siguiente apartado. Es evidente que s´lo se puede confiar en un algoritmo o si ha superado con ´xito determinado control de calidad: la primera e inexcusa- e ble exigencia es que sea correcto; esto es, que resuelva el problema especificado. Cuando un problema admita varios algoritmos como soluci´n, convendr´ dispo- o a ner de criterios para escoger; y cuando un problema no tenga soluci´n, no resulta o sensato buscar un algoritmo para resolverlo. Estos aspectos los estudiamos en el apartado 1.3. Finalmente, para que un computador resuelva problemas hay que escribir el algoritmo en un lenguaje de programaci´n; de ello hablaremos en el apartado o 1.4. 1.2 Concepto de algoritmo Los conceptos de algoritmo y de m´todo son parecidos: los m´todos para e e efectuar procesos forman parte de las costumbres o rutinas que el hombre aprende un d´ y luego repite de manera inconsciente, sin reparar ya en las acciones, m´s ıa a sencillas, que integran el proceso (por ejemplo andar, leer o conducir). Por eso el concepto de algoritmo suele compararse a otros como m´todo o rutina de e acciones. La secuencia de pasos de la figura 1.1 describe un m´todo para efectuar la e matr´ ıcula en la universidad. Sin embargo, el t´rmino “algoritmo” tiene connotaciones m´s formales que e a cualquier otro debido a su origen: se trata de una acomodaci´n al castellano del o
  • 26. 6 Cap´ ıtulo 1. Problemas, algoritmos y programas nombre de Muhammad ibn M¯s¯ al-Jw¯r¯ ı, matem´tico persa que populariz´ . ua a ızm¯ a o su descripci´n de las cuatro reglas (algoritmos) de sumar, restar, multiplicar y o dividir. 1.2.1 Una definici´n de algoritmo o Hablando informalmente, un algoritmo es la descripci´n precisa de los pasos o que nos llevan a la soluci´n de un problema planteado. Estos pasos son, en gene- o ral, acciones u operaciones que se efect´an sobre ciertos objetos. La descripci´n u o de un algoritmo afecta a tres partes: entrada (datos), proceso (instrucciones) y salida (resultados).1 En este sentido, un algoritmo se puede comparar a una funci´n matem´tica: o a + : Z ×Z Z Z −→ Z Z (algoritmo) (entrada) (proceso) (salida) Incluso en algoritmos no matem´ticos es f´cil identificar las tres partes: entra- a a da, proceso y salida. As´ ocurre, por ejemplo, en las instrucciones para hacer la ı declaraci´n de la renta. o Caracter´ ısticas de los algoritmos La descripci´n de algoritmo que se ha dado es algo imprecisa. Una caracte- o rizaci´n m´s completa deber´ incluir adem´s los siguientes requisitos: o a ıa a 1. Precisi´n o Un algoritmo debe expresarse de forma no ambigua. La precisi´n afecta o por igual a dos aspectos: (a) Al orden (encadenamiento o concatenaci´n) de los pasos que han de o llevarse a cabo. (b) Al contenido de las mismas, pues cada paso debe “saberse realizar” con toda precisi´n, de forma autom´tica. o a Por lo tanto, una receta de cocina puede ser considerada como un m´todo, e pero carece de la precisi´n que requieren los algoritmos debido al uso de o expresiones como a˜adir una pizca de sal, porque ¿qu´ debe entenderse por n e una pizca? 1 Es habitual llamar “datos” a la entrada y “resultados” a la salida, aunque el concepto de dato es m´s amplio, y abarca a toda la informaci´n que maneja un algoritmo, ya sea inicialmente o a a o su t´rmino, as´ como tambi´n durante el transcurso de su utilizaci´n. e ı e o
  • 27. 1.2. Concepto de algoritmo 7 NO Principio a b a = 0 a ← a-1 b ← b+1 1 2 3 4 5 ´ 6 SI b 7 Fin Figura 1.2. Diagrama de flujo de la “suma lenta”. 2. Determinismo Todo algoritmo debe responder del mismo modo ante las mismas condicio- nes. Por lo tanto, la acci´n de barajar un mazo de cartas no es un algoritmo, o ya que es y debe ser un proceso no determinista. 3. Finitud La descripci´n de un algoritmo debe ser finita. o Un primer ejemplo Consideremos el ejemplo que, expresado gr´ficamente,2 aparece en la fi- a gura 1.2. El algoritmo descrito tiene por objetivo sumar dos cantidades enteras. Si se anotan esas cantidades inicialmente en sendas casillas (a las que llamaremos a y b para abreviar), este m´todo consiste en ir pasando de a a b una unidad e cada vez, de forma que, cuando a = 0, el resultado ser´ el valor de b. a Vemos un ejemplo de su funcionamiento con los datos 2 y 3 en la figura 1.3. (Los n´meros se han incluido para seguir mejor la evoluci´n de los c´lculos.) u o a Se observa que la descripci´n del algoritmo que se ha dado es, en efecto, o precisa (cada paso est´ exento de ambig¨edad, as´ como el orden en que se debe a u ı efectuar) y determinista (el efecto de cada paso es siempre el mismo para unos datos concretos cualesquiera). Estas dos caracter´ ısticas son una consecuencia del lenguaje escogido para expresar el algoritmo. 2 El lenguaje empleado es el de los diagramas de flujo, que estudiaremos en el cap´ ıtulo 7, apartado 7.2.1. Esperamos que, debido a su sencillez, el funcionamiento de este ejemplo resulte comprensible directamente.
  • 28. 8 Cap´ ıtulo 1. Problemas, algoritmos y programas Posici´n o Datos pendientes Resultados emitidos Var a Var b 1 [2, 3] [] ? ? 2 [3] [] 2 ? 3 [] [] 2 3 4 [] [] 2 3 5 [] [] 1 3 3 [] [] 1 4 4 [] [] 1 4 5 [] [] 0 4 3 [] [] 0 5 6 [] [] 0 5 7 [] [5] 0 5 Figura 1.3. Ejecuci´n de la suma lenta con los datos 2 y 3. o En cambio, si bien es cierto que, con los datos del ejemplo, se ha obtenido una soluci´n, si se examina con detenimiento se ver´ que ese “algoritmo” no o a siempre termina para dos cantidades enteras cualesquiera (v. g. − 3 y − 1). De hecho, la terminaci´n es una caracter´ o ıstica escurridiza de la que hablaremos m´s tarde (v´ase el apartado 1.3.1). a e 1.2.2 Una definici´n formal de algoritmo o La caracterizaci´n hecha hasta ahora de los algoritmos es satisfactoria a efec- o tos pr´cticos. M´s concreta a´n resulta a la vista de un lenguaje algor´ a a u ıtmico como el de los diagramas de flujo, que deja entrever dos aspectos: • El mantenimiento de unas variables (a y b) y de unas posiciones (1, . . . , 7), a lo que llamamos estado. Por ejemplo, cada fila de la tabla de la figura 1.3 representa un estado en la evoluci´n del algoritmo 1.2. o • La descripci´n de transiciones entre estados, que vienen dadas por el propio o diagrama. Estos aspectos de los algoritmos est´n ausentes de la primera definici´n, a o por lo que puede resultar a´n algo incompleta; surge pues la necesidad de una u definici´n m´s formal: o a Definici´n: o Un algoritmo es una cu´drupla que comprende los siguientes ele- a mentos: 1. El conjunto de los estados (llam´mosle E) que pueden presentarse en todo e momento durante el c´lculo. a
  • 29. 1.2. Concepto de algoritmo 9 Un estado viene dado por una tupla, incluyendo: • los valores de las variables que entran en juego; • los datos sin leer y los resultados emitidos, y • la marca, identificando la posici´n del algoritmo en la que se da este o estado de los c´lculos. a Es decir, un estado se puede expresar as´ ı: <Datos por leer; Resultados emitidos; Variables; Posici´n> o 2. La identificaci´n de los estados iniciales, I ⊂ E, o estados posibles al o comienzo del algoritmo. 3. La identificaci´n de los estados finales, F ⊂ E, como posibles estados al o terminar el algoritmo. 4. Una funci´n de transici´n entre estados, o o t : E −→ E que describe el efecto de cada paso del c´mputo asociado al algoritmo. o Esta funci´n deber´: o a • Estar definida dentro de E, esto es, para cualquier e ∈ E debemos tener que t(e) ∈ E. As´ las transiciones entre estados son precisas y ı, deterministas. • A partir de cualquier estado inicial, la funci´n de transici´n t debe o o llevar a un estado final en un n´mero finito de pasos, formalmente: u para cualquier e ∈ I existe un k ∈ IN tal que t se aplica k veces t(t(· · · t(e) · · ·)) ∈ F y, adem´s, no tiene efecto alguno sobre los estados finales, es decir: a para cualquier e ∈ F ocurre que t(e) = e. De aqu´ se obtiene la ı caracter´ ıstica de finitud. Siguiendo con el algoritmo del diagrama de flujo de la figura 1.2, identificamos los siguientes estados: E = { < 1 ; [d1 , d2 ] ; [ ] ; — > < 2 ; [d2 ] ; [] ; a ≡ a0 > < p ; [] ; [ ] ; a ≡ a 0 , b ≡ b0 > < 7 ; [] ; [r] ; — > }
  • 30. 10 Cap´ ıtulo 1. Problemas, algoritmos y programas donde d1 , d2 , a, b, r ∈ IN, p ∈ {3, . . . , 6}, y siendo I = {< 1; [d1 , d2 ]; [ ]; — >} y F = {< 7; [ ]; [r]; — >}. La funci´n de transici´n t es la siguiente: o o t(< 1; [d1 , d2 ]; [ ]; — >) = < 2; [d2 ]; [ ]; a ≡ d1 > t(< 2; [d2 ]; [ ]; a ≡ d1 >) = < 3; [ ]; [ ]; a ≡ d1 , b ≡ d2 > < 6; [ ]; [ ]; b ≡ b0 > si a = 0 t(< 3; [ ]; [ ]; a ≡ a0 , b ≡ b0 >) = < 4; [ ]; [ ]; a ≡ a0 , b ≡ b0 > si a = 0 t(< 4; [ ]; [ ]; a ≡ a0 , b ≡ b0 >) = < 5; [ ]; [ ]; a ≡ a0 − 1, b ≡ b0 > t(< 5; [ ]; [ ]; a ≡ a0 , b ≡ b0 >) = < 3; [ ]; [ ]; a ≡ a0 , b ≡ b0 + 1 > t(< 6; [ ]; [ ]; b ≡ b0 >) = < 7; [ ]; [b0 ]; — > t(< 7; [ ]; [r]; — >) = < 7; [ ]; [r]; — > Desde el punto de vista del usuario de un algoritmo, se puede considerar un algoritmo como una caja opaca cuyos detalles internos se ignoran, aflorando s´lo o la lectura de los datos y la escritura de los resultados. Estos aspectos observables desde el exterior se llaman frecuentemente la interfaz externa. No obstante, el mecanismo interno interesa al autor de algoritmos, esto es, al programador. Para atender esta necesidad, algunos entornos de programaci´n permiten “trazar” o programas, con lo que el programador puede ver evolucionar el estado interno durante la marcha de su programa con el grado de detalle que desee (v´anse e los apartados 5.4.1 y C.2.6). Esta posibilidad es interesante para depurar los programas, esto es, para buscar los posibles errores y subsanarlos. Para terminar este apartado, debemos decir que el esquema de funciona- miento descrito a base de transiciones entre estados se conoce con el nombre de modelo de von Neumann (v´ase el apartado 7.2.1 de [PAO94]). Se dice que este e modelo es secuencial, en el sentido de que los pasos se efect´an uno tras otro. De u hecho, no es posible acelerar el proceso efectuando m´s de un paso a un tiempo, a porque cada paso tiene lugar desde el estado dejado por el paso anterior. Este “cuello de botella” es un defecto propio de las m´quinas de von Neumann. a Cualidades deseables de un algoritmo Es muy importante que un algoritmo sea suficientemente general y que se ejecute eficientemente. Veamos con m´s detalle qu´ se entiende por general y a e por eficiente:
  • 31. ´ 1.3. Aspectos de interes sobre los algoritmos 11 1. Generalidad Es deseable que un algoritmo sirva para una clase de problemas lo m´s a amplia posible. Por ejemplo, la clase de problemas “resolver una ecuaci´n o de segundo grado, a + bx + cx2 = 0” es m´s general que la consistente a en “resolver ecuaciones de primer grado, a + bx = 0”. 2. Eficiencia Hablando en t´rminos muy generales, se considera que un algoritmo es e tanto m´s eficiente cuantos menos pasos emplea en llevar a cabo su come- a tido. Por ejemplo, para hallar la suma de dos n´meros naturales, la regla u tradicional que se aprende en ense˜anza primaria es m´s eficiente que el n a rudimentario procedimiento de contar con los dedos, de uno en uno. Este tema se revisar´ en el apartado 1.3.3, y ser´ tratado con mayor detalle en a a el cap´ ıtulo 18. Estas dos cualidades no son siempre conciliables, por lo que frecuentemente hay que optar por una soluci´n en equilibrio entre ambas cuando se dise˜a un o n algoritmo. Por ejemplo, un algoritmo que estudia y resuelve “sistemas de ecua- ciones” es m´s general que uno que resuelve “sistemas de ecuaciones lineales”, y a ´ste a su vez es m´s general que otro que s´lo considera “sistemas de dos ecua- e a o ciones lineales con dos inc´gnitas”. Sin embargo, a mayor generalidad se tiene o tambi´n una mayor complejidad puesto que hay que tratar m´s casos y no se e a pueden aplicar algoritmos espec´ ıficos. Por consiguiente, si un buen n´mero de u situaciones puede resolverse con un algoritmo r´pido aunque poco general, es a preferible adoptar ´ste. e 1.3 Aspectos de inter´s sobre los algoritmos e 1.3.1 Computabilidad Con el aumento de potencia y el abaratamiento de los computadores, cada vez se plantean aplicaciones m´s sorprendentes y de mayor envergadura, capaces de a resolver problemas m´s generales. Da la impresi´n de que cualquier problema que a o se plantee ha de ser computable (esto es, ha de tener una soluci´n algor´ o ıtmica), sin otra limitaci´n que la potencia de la m´quina ejecutora. o a Sin embargo, esto no es as´ Por rotunda que pueda parecer esta afirmaci´n, ı. o se debe aceptar que hay problemas no computables La cuesti´n que se plantea es algo delicada: advi´rtase que, si no se conoce o e algoritmo que resuelva un problema planteado, s´lo se puede asegurar “que no o
  • 32. 12 Cap´ ıtulo 1. Problemas, algoritmos y programas se conoce algoritmo que resuelva ese problema”; en cambio, establecer que un problema “no es computable” requiere demostrar que nunca se podr´ encontrar a ning´n algoritmo para resolver el problema planteado. u Los siguientes son ejemplos de problemas no computables: • D´cimo problema de Hilbert. e Resolver una ecuaci´n diof´ntica con m´s de una inc´gnita. o a a o Esto significa encontrar soluciones enteras de una ecuaci´n de la forma o P (x1 , x2 , . . .) = 0, donde P es un polinomio con coeficientes enteros. • Problema de la parada. Determinar si un algoritmo a finaliza o no cuando opera sobre una entrada de datos d:   S´ı si a(d) ↓ Stop(a, d) =  No si a(d) ↑ donde a(d) ↓ (resp. a(d) ↑) expresa que el algoritmo a, aplicado al dato d, s´ para (resp. no para). ı Examinaremos con m´s atenci´n el problema de la parada, y despu´s veremos a o e cu´n escurridizo puede resultar determinar si un algoritmo particular para o no a considerando un sencillo ejemplo. Claro est´ que esto no demuestra nada salvo, a en todo caso, nuestra incapacidad para analizar este algoritmo en concreto. Por ello, incluimos seguidamente una demostraci´n de que es imposible hallar un o algoritmo capaz de distinguir entre los algoritmos que paran y los que no. Obs´rvese que se plantea aqu´ estudiar “algoritmos que operan sobre algorit- e ı mos, vistos como datos”. Por extra˜o que parezca al principio, en Computaci´n n o se desarrollan frecuentemente programas que manejan otros programas con di- versos fines. El problema de la parada no es computable El problema de la parada, definido m´s arriba, se puede expresar como sigue: a ¿se puede examinar cualquier algoritmo y decidir si para? Demostraremos que no existe, ni puede existir, el algoritmo Stop que distinga si un algoritmo a para cuando se aplica a los datos d. Procederemos por reducci´n al absurdo: Suponiendo que existe ese algoritmo o (descrito m´s arriba como Stop), a partir de ´l es posible construir otro similar, a e Stop’, que averig¨e si un algoritmo a para cuando se aplica “a su propio texto”: u ı S´ si p(p) ↓ Stop’(p) = Stop(p, p) = No si p(p) ↑
  • 33. ´ 1.3. Aspectos de interes sobre los algoritmos 13 Y entonces, tambi´n se puede definir el siguiente algoritmo a partir del an- e terior: ↑ si Stop’(p) = S´ ı ↑ si p(p) ↓ Raro(p) = = No si Stop’(p) = No No si p(p) ↑ Veamos que el algoritmo Raro tiene un comportamiento verdaderamente extra˜o cuando se aplica a s´ mismo: n ı ↑ si Stop’(Raro) = S´ ı Raro(Raro) = No si Stop’(Raro) = No ↑ si Raro(Raro) ↓ = No si Raro(Raro) ↑ lo que resulta obviamente imposible. La contradicci´n a que hemos llegado nos lleva a rechazar la hip´tesis inicial o o (la existencia de un algoritmo para el problema de la parada), como quer´ ıamos demostrar. N´ meros pedrisco u Como ejemplo de la dificultad de examinar un algoritmo y decidir si concluir´ a tarde o temprano, consideremos la siguiente funci´n t: IN → IN: o   3n + 1 si n es impar t(n) =  n/2 si n es par Partiendo de un n´mero natural cualquiera, le aplicamos t cuantas veces sea u necesario, hasta llegar a 1. Por ejemplo, t t t t t t t 3 −→ 10 −→ 5 −→ 16 −→ 8 −→ 4 −→ 2 −→ 1 · · · Esta sencilla sucesi´n genera n´meros que saltan un n´mero de veces impre- o u u decible, t111 27 −→ 1 de manera que cabe preguntarse si todo natural n alcanza el 1 tras una cantidad finita de aplicaciones de t, o por el contrario existe alguno que genera t´rminos e que saltan indefinidamente.3 Se ha comprobado, por medio de computadores, que la sucesi´n llega a 1 si o se comienza con cualquier n´mero natural menor que 2 u 40 10 12 , pero a´ n no se u ha podido demostrar para todo n. 3 Este problema tambi´n se conoce como problema 3n+1. e
  • 34. 14 Cap´ ıtulo 1. Problemas, algoritmos y programas 1.3.2 Correcci´n de algoritmos o El aspecto de la correcci´n es de crucial importancia para quien desarrolla un o algoritmo. Sin embargo, es imposible detectar los posibles errores de una forma sistem´tica. Con frecuencia, la b´squeda de errores (depuraci´n) consiste en la a u o comprobaci´n de un algoritmo para unos pocos juegos de datos. Sin embargo, eso o no garantiza nada m´s que el buen funcionamiento del algoritmo para esos juegos a de datos y no para todos los posibles. Volviendo al algoritmo de la suma lenta, la comprobaci´n con los juegos de datos [2, 3] y [3, -1] ofrecer´ resultados correctos, o ıa y sin embargo el algoritmo unicamente termina cuando el primer sumando es (un ´ entero) positivo. Frente a la comprobaci´n, la verificaci´n consiste en la demostraci´n del buen o o o funcionamiento de un algoritmo con respecto a una especificaci´n. Esto es, la o verificaci´n trata de garantizar que, para todos los datos considerados (descritos o en la especificaci´n), el algoritmo lleva a los resultados (tambi´n descritos en la o e especificaci´n) deseados. Por eso, aunque frecuentemente se habla de correcci´n o o de un algoritmo, sin m´s, en realidad hay que decir correcci´n de un algoritmo a o con respecto a una especificaci´n. o Por lo general, la verificaci´n se basa en establecer aserciones (propiedades) o del estado de la m´quina en cada paso del algoritmo. Se profundizar´ en esta a a idea a lo largo de todo el texto. Por ejemplo, para verificar el funcionamiento del algoritmo de “suma lenta”, consideremos que se hace funcionar sobre dos enteros gen´ricos m y n. Claramente, al llegar a la posici´n 3 por vez primera, a = m y e o b = n. Por otra parte, en la posici´n 3 se tiene invariablemente la propiedad o a+b=m+n independientemente de las vueltas que se den y de las modificaciones que se efect´en sobre a y b,4 ya que cada unidad que se reste a a se le suma a b. Ahora u bien, cuando se pasa de la posici´n 3 a la 6 es por ser a = 0, con lo que se tiene, o simult´neamente, el invariante a + b = m + n y a = 0, es decir: a b=m+n lo que asegura que la salida es correcta. . . cuando ´sta se produzca. Un algoritmo e que ofrece una soluci´n correcta cuando para, pero del que no sepamos si para o o no, se dice parcialmente correcto. Ese es el caso de la suma lenta de n´meros u enteros. Adem´s, si inicialmente a es un n´mero natural, es seguro que el algoritmo a u para, ya que la operaci´n a ← a − 1 lo llevar´ a cero, precisamente en a vueltas o a del bucle. Si se asegura que un algoritmo es parcialmente correcto y que para 4 Por ello, esta propiedad se conoce como invariante.
  • 35. ´ 1.3. Aspectos de interes sobre los algoritmos 15 ´ en un tiempo finito, se dice que el algoritmo es (totalmente) correcto. Ese es el caso de la suma lenta de pares de n´meros, siendo el primero de ellos entero y u positivo. La verificaci´n de algoritmos no es una tarea f´cil. Al contrario, verificar o a completamente un algoritmo involucra el uso de l´gica matem´tica, y con fre- o a cuencia resulta incluso m´s complicado que desarrollarlo. De ah´ el inter´s que a ı e tiene esmerarse, desde el principio, en escribir algoritmos correctos, adquiriendo un buen estilo y esforz´ndose en emplear metodolog´ apropiadas para ello. a ıas 1.3.3 Complejidad de algoritmos Resulta de gran inter´s poder estimar los recursos que un algoritmo necesita e para resolver un problema. En m´quinas secuenciales, estos recursos son el a tiempo y la memoria.5 Muchas veces, un algoritmo tarda tanto en ofrecer el resultado que resulta, en realidad, in´til. Un ejemplo de esta situaci´n se da en sistemas de control u o de procesos, en donde la respuesta a determinadas circunstancias debe disparar mecanismos de seguridad en un tiempo cr´ ıtico (por ejemplo, en centrales nu- cleares). An´logamente para el espacio, es posible que la m´quina en que ha a a de funcionar un programa disponga de una capacidad de memoria limitada y nos veamos obligados a elegir algoritmos que usen poca memoria. Por lo tanto, existen situaciones en las que si disponemos de varios algoritmos para un mismo problema, deberemos decidir cu´l es el m´s r´pido o el que menos cantidad de a a a memoria requiere. En el cap´ ıtulo 18 se ahondar´ en esta idea. a Como el tiempo requerido por los programas depende en gran medida de la potencia de la m´quina ejecutora, es frecuente medir en “pasos” (de coste fijo) a el coste del algoritmo correspondiente. Para concretar un poco, y siguiendo con el ejemplo de la suma lenta, consideremos que cada bloque o caja del diagrama es un paso y, por tanto, cuesta una unidad. Entonces, es f´cil deducir que sumar a los naturales m y n lleva 3m + 4 pasos. En efecto, llamando tm al coste de sumar m y n, se tiene que t0 = 4 pasos tm = tm−1 + 3, si n ≥ 1 pues para sumar 0 y n hay que realizar cuatro pasos (v´ase la figura 1.2) y si e m = 0 hay que realizar tres pasos para reducir m en una unidad; resumiendo t0 = 4 5 En los ultimos a˜os, tambi´n est´ interesando medir el n´mero de procesadores en m´quinas ´ n e a u a de procesamiento en paralelo (v´ase el apartado 3.5 de [PAO94]). e