viernes, 31 de diciembre de 2010

Multiplicacion de Matrices en C

Como escribí en la primera entrada de este blog: Propósito mi intención es subir programas y ejercicios resueltos de los libros de Deitel Como Programar en Java y C++, asi como los del libro El lenguaje de programacion C de Kernighan y Ritchie, y algunos de Algoritmos de Sedgewick. Sin embargo, el algoritmo clásico de la multiplicación de dos matrices es bastante común y me parece que no esta fuera de lugar colocar aquí el código en C. He hecho el programa pensando en que sea útil, más que en poner el algoritmo simplemente. Ustedes pueden definir el tamaño de las matrices así como las entradas y también pueden ver desplegadas las matrices en la pantalla ( si los resultados son lo bastante chicos como para entrar en la pantalla de su computadora ). Este problema también aparece resuelto para el lenguaje C++ en la entrada Multiplicación de Matrices en C++ de enero de 2011, en un programa menos complicado que éste.

#include <stdio.h>
#define M 2
#define N 3
#define P 4

Multiplicacion_Matrices(void)

// Todo el problema se resuelve en esta funcion, la funcion main
// solo sirve para llamar a esta
// Es necesario hacer esta funcion mas pequenia

{ // Abre la funcion Multiplicacion_Matrices

int i; // Estos tres indices controlaran tres ciclos en el algoritmo
int j; // principal del programa, aunque se usaran fuera de este para
int k; // controlar otros ciclos sin ninguna ambiguedad

// se define una matriz de N filas por M columnas
// esta va a ser la primera matriz, es importante el orden porque
// en general la multiplicacion de matrices es no conmutativa

int Matriz1[M][N] = { {0}};
// con esto todas las entradas se inicializan a cero

// Aqui se reciben las entradas de la primera matriz
// Este programa contiene mas cosas de las que se pide normalmente
// en este problema clasico, una de ellas es pedir las entradas de las
// matrices una por una, en lugar de ponerlas al definir las matrices
// esto lo hace bastante mas comodo y practico de usar, en lugar de solo
// ser un algoritmo

printf("\nESTE PROGRAMA MULTIPLICA DOS MATRICES, LA PRIMERA DE : %d POR %d", M, N);
printf(" Y LA SEGUNDA DE %d POR %d. SI QUIERE MODIFICAR RENGLONES Y ", N, P);
printf(" COLUMNAS, CAMBIE LAS VARIABLES SIMBOLICAS M, N & P EN EL CODIGO.\n");
printf("\nAQUI SE RECIBEN LOS ELEMENTOS DE LA PRIMERA MATRIZ.\n");

for ( i = 0; i < M; i++)
{ // Abre primer for
for ( j = 0; j < N; j++)
{ // abre segundo for

printf("\nIntroduzca la entrada (%d,%2d) para la primera matriz \n", i, j);
scanf("%d", &Matriz1[i][j]);

} // Cierra segundo for
} // Cierra primer for

// Se define una matriz de N filas por P columnas
// La segunda matriz no es totalmente arbitraria. Se requiere que tenga tantos
// renglones como columnas tiene la primera

int Matriz2[N][P] = {{ 5}};

printf("\nAQUI SE RECIBEN LOS ELEMENTOS DE LA SEGUNDA MATRIZ:\n");

for ( i = 0; i < N; i++)
{ // Abre primer for
for ( j = 0; j < P; j++)
{ // abre segundo for

printf("\nIntroduzca la entrada (%d,%2d) para la segunda matriz \n", i, j);
scanf("%d", &Matriz2[i][j]);

} // Cierra segundo for
} // Cierra primer for

//Se define una matriz de M filas por P columnas
// La matriz producto es de el mismo numero de renglones que la primera
// y del mismo numero de filas que la segunda

int Matriz_Producto[M][P] = {{0}};

// EL ALGORITMO PRINCIPAL, NUCLEO DEL PROBLEMA
// Esta es la esencia del problema, lo demas es recibir e imprimir los
// resultados, lo cual no deja de ser laborioso. Esto es todo lo que se pide.
// Recuerdo que alguna vez en mi primer curso de programacion me pusieron
// este ejercicio en un examen. La clave consiste en hacer las cosas simples
// al principio. Se puede empezar por escribir el producto punto o interno
// de un par de vectores, uno fila y otro columna, eso incluye un ciclo for
// corriendo sobre M, el numero de columnas de la primera matriz y de
// filas de la segunda. Posteriormente hay que escribir el producto de un
// vector renglon por una matriz de N por P, con P arbitrario, esto incluye
// un par de ciclos for. Y por ultimo hay que dejar que en vez de un vector
// fila la multiplicacion sea de una matriz con M vectores fila de N entradas
// eso incluye un tercer ciclo for.
// La compejidad del programa debe valorarse por el numero de instrucciones
// aqui. La complejidad es O(MNP), lo cual es aproximadamente de O(n3)
// Desde luego, el programa sera mucho mas lento con la impresion y la
// recepcion de los numeros.



for ( k = 0; k < M; k++)
{ // abre primer ciclo for
for ( j = 0; j < P; j++)
{ // abre el segundo ciclo for

for ( i = 0; i < N; i++ )
Matriz_Producto[ k ][j ] += Matriz1[k][i]*Matriz2[i][j];

} // Cierra el segundo ciclo for
} // cierra primer ciclo for

// FIN DEL ALGORITMO PRINCIPAL

// Aqui se imprimen la dos matrices y la matriz producto

printf("\n\nAQUI SE IMPRIMEN LAS DOS MATRICES Y EL PRODUCTO: \n\n");
for ( i = 0; i < M; i++ )
{ // abre for que controla numero de renglones

// Este ciclo imprime la primera matriz
// No hay ningun problema para imprimir la primera matriz, ya que se
// trata de un par de ciclos for. Sin embargo se quiere imprimir las
// tres matrices, lo cual hace un poquito mas complicado el asunto.
// De todas formas la primera se imprime renglon por renglon
// solo que antes de pasar al siguiente renglon, se escriben las entradas
// correspondientes de la segunda y tercera matrices.

for ( k = 0; k < N; k++)
{ // Abre ciclo for
printf("%3d", Matriz1[i][k]);
// Se imprime el renglon i de la matriz 1
} //Cierra ciclo for

printf("\t\t"); // Esta instruccion separa una matriz de otra

// Este ciclo imprime la segunda matriz

for ( j = 0; j < P; j++)

{ // abre for

if ( i <= (N - 1)) // El numero de columnas de la segunda matriz puede ser
// menor o mayor que el numero de filas de la primera
// Si es mayor no pasa nada, pero si es menor se estara
// haciendo referencia a un elemento inexistente en el arreglo
// El caso en el que N > M se trata fuera del ciclo controlado por i
// El -1 es debido a que i empieza a correr en cero

printf("%3d", Matriz2[i][j]); // se imprime el renglon i de la matriz 2

else // De lo contrario solo se imprimen 3 espacios en blanco
     // correspondientes con 3d

printf(" ");

} // Cierra for

printf ("\t\t"); // Esta instruccion separa la matriz 2 de la matriz
                 // producto

// Este es el ciclo que imprime la matriz producto

for ( j = 0; j < P; j++ )
{ // abre for
printf("%3d", Matriz_Producto[i][j]);
// se imprime el renglon i de la matriz producto
} // Cierra for

printf("\n");

// Aqui se cambia de renglon

} // Cierra for que controla numero de renglones


// Es probable que N > M, por lo cual en el ciclo anterior no se
// imprimiria la segunda matriz en su totalidad
// Con el siguiente bloque se imprime lo que falta

if ( N > M)
{ // Abre if

int l = M;

while ( l < N )
{ // Abre while

for ( i = 0; i < N; i++)
printf(" ");

printf("\t\t\t");      

for ( j = 0; j < P; j++ )
printf("%3d", Matriz2[l][j]);

printf("\n"); // Aqui se cambia de linea
l++; // Se incrementa el numero de linea

} // Cierra while

} // Cierra if

} // Cierra la funcion Multiplicacion_Matrices


//////////////////////////////////////////////////////////
// MAIN
/////////////////////////////////////////////////////////

int main()

{

Multiplicacion_Matrices();

return 0;
}


/* Defectos en el programa: Como se menciono, la funcion Multiplicacion esta
muy llema de bloques, seria preferible reescribir su contenido en varias
funciones menores.
A la hora de imprimir se ha supuesto que el numero de entradas es chico
comparado con el tamanio de la pantalla. Si se trabaja con matrices en las
que N, M y P sean muy grandes, en realidad no saldra nada util en la pantalla.
De la misma manera si se toman numeros chicos pero con entradas de tres o
cuatro cifras*/

domingo, 31 de octubre de 2010

Deitel_C++_4.21 ¿Qué hace el siguiente programa?


// QUE HACE EL SIGUIENTE PROGRAMA?    
         
#include <iostream>        
using namespace::std;        
         
void Alguna_Funcion ( char b[], int Tamano )  
{         
if ( Tamano > 0 )    
{         
Alguna_Funcion ( &b[1], Tamano - 1 );   
cout << b[0] << " ";    
}         
}         
         
         
int main()        
{         
const int Tamano_Arreglo = 4;     
char A[Tamano_Arreglo] = {'H', 'O', 'L', 'A' };  
         
cout <<"\n\nLos valores en el arreglo son: " << endl;
         
Alguna_Funcion(A, Tamano_Arreglo);        
         
cout << endl;       
         
return 0;        
}         

La ejecución del programa produce:

Los valores en el arreglo son: 
A L O H 


Deitel_C++_4.20 (Reservación de una Aerolínea en C++)


// ESTE ES UN SISTEMA DE RESERVACION DE UNA AEROLINEA      
               
#include <iostream>              
using namespace::std;              
               
#include <iomanip>              
               
int Asignar(int b[], int r);           
               
int main()              
{ // ABRE MAIN            
               
int Fumar[6] = {0};            
int No_Fumar[6] = {0};            
int respuesta, n = 0, s = 1, evaluacion;       
int Contador_Fumar = 0;            
int Contador_No_Fumar = 0;            
               
while ( (Contador_Fumar + Contador_No_Fumar) < 10 )        
{ // ABRE WHILE            
               
if ( 5 == Contador_Fumar )          
{ // ABRE IF            
cout <<"\nDesea Area de No Fumar? ( 1 para si, 0 para no) " << endl;
cin >> respuesta;             
               
if ( 1 == respuesta )          
{               
evaluacion = Asignar( No_Fumar, n ); // SI EL CLIENTE DESEA NO FUMAR SE ENVIA N
if ( 0 == evaluacion )          
Contador_No_Fumar++;               
else               
Contador_Fumar++;               
               
} // CONTADOR NO_FUMAR            
               
else               
cout <<"\nEl proximo vuelo parte en tres horas. " << endl;     
               
} // CIERRA IF            
               
else               
{ // ABRE ELSE            
cout <<"\nDesea area de fumar? (1 para si, 0 para no) "<<endl;    
cin >> respuesta;             
               
if ( 1 == respuesta )          
{               
evaluacion = Asignar( Fumar, s ); // SE ENVIA S PARA INCREMENTAR CONTADOR_FUMAR   
if (0 == evaluacion)            
Contador_No_Fumar++;               
else               
Contador_Fumar++;               
}               
else               
{ // ABRE ELSE            
cout <<"\nDesea Area de No Fumar? ( 1 para si, 0 para no ) " <<endl;
cin >> respuesta;             
if ( 1 == respuesta )          
{               
evaluacion = Asignar(No_Fumar, n );           
if ( 0 == evaluacion )          
Contador_No_Fumar++;               
else               
Contador_Fumar++;               
}               
               
else               
cout <<"\nEl proximo vuelo sale en tres horas. " << endl;     
               
} // CIERRA ELSE            
} // CIERRA ELSE            
               
} // CIERRA WHILE            
               
return 0;              
               
} // CIERRA MAIN            
               

////////////////////////////////////////////////////
// ASIGNAR
//////////////////////////////////////////////////// 
               
int Asignar( int b[], int r )         
{ // ABRE ASIGNAR            
int c, No_Fumar = 0, Fumar = 1;;        
               
for ( c = 1; 5 >= c; c++ )      
{ // ABRE FOR            
               
if ( 0 == b[c] )          
{ // ABRE IF            
cout << "\nAsiento " << c << endl;        
b[c] = 1;             
               
if ( 0 == r )          
return No_Fumar;              
               
else               
return Fumar;              
} // CIERRA IF            
} // CIERRA FOR            
               
} // CIERRA ASIGNAR            

Deitel_C++_4.18 (Programa Incógnita en C++)


// QUE HACE ESTE PROGRAMA?        
            
#include <iostream>           
using namespace::std;           
            
int Que_Es_Esto(int[], int); // FUNCION INCOGNITA       
            
int main()           
            
{            
const int Tamano_Arreglo = 10;        
int A[Tamano_Arreglo] = {1,2,3,4,5,6,7,8,9,10};         
int resultado = Que_Es_Esto(A, Tamano_Arreglo);        
            
cout <<"\nEl resultado es: " << resultado << endl;    
            
return 0;           
}            
            
            
int Que_Es_Esto(int b[], int size)        
{            
if ( size == 1 )       
return b[0];           

else            
return b[ size - 1 ] + Que_Es_Esto( b, size - 1 );
}            


El resultado al ejecutar este programa es la siguiente línea:


El resultado es: 55

Deitel_C++_4.17 (Lanzamiento de Dados en C++)

Lanzamiento de Dados en C++
Escriba un programa que simule el tiro de dos dados. El programa debe utilizar rand para tirar el primer dado y debe utilizar rand de nuevo para tirar el segundo dado. Entonces, se debe calcular la suma de los dos valores. Su programa debe lanzar los dedos 36000 veces. Utilice un arreglo con un sólo subíndice para registrar el número de veces que aparece cada suma posible. Despliegue los resultados en formato tabular. Además, determine si los totales son razonables (es decir, existen 6 maneras de tirar un 7, de manera que aproximadamente un sexto de todos los tiros debe ser 7).


// ESTE PROGRAMA SIMULA 3600 LANZAMIENTOS DE UN DADO

    #include <iostream>
    using namespace::std;
    #include <ctime>                                      
   // CONTIENE EL PROTOTIPO DE LA FUNCION TIME
    #include <cstdlib>                                   
   // CONTIENE EL PROTOTIPO DE LA FUNCION RAND Y SRAND

   int main()


   {                   // ABRE MAIN
    srand( time( 0 ) ); 
    // USA LA HORA ACTUAL COMO SEMILLA PARA PRODUCIR NUMEROS ALEATORIOS 
    // DISTINTOS EN CADA LLAMADA A RAND

    cout <<"\n\nLanzamiento de 3600 jugadas: " << endl;
    int lanzamiento;
    int Frecuencia[13] = {0};                         
    // SE LANZAN DOS DADOS Y SE EVITA EL ELEMENTO 0 DEL ARREGLO

    for ( int i = 1; i <= 3600; i++ )
      {                                                 // ABRE FOR
       lanzamiento = ( 1 + rand() % 6 ) + (1 + rand() % 6 );  
       // AQUI SE SIMULA EL LANZAMIENTO DE LOS DADOS 
       Frecuencia[lanzamiento]++;  
       // SE INCREMENTA EN 1 LA FRECUENCIA DEL NUMERO QUE CAYO

      }                  // CIERRA FOR  

    for ( int n = 2; 12 >= n; n++ ) 
    // ESTE CICLO FOR IMPRIME LAS FRECUENCAS
    cout <<"\nLa frecuencia de " << n << " es: " << Frecuencia[n];
    cout << endl;
    return 0;

   }         

Deitel_C++_4.11 (Ordenamiento Burbuja Mejorado)

Programa que mejora el ordenamiento burbuja.
     //    ESTE PROGRAMA ES UNA MEJORA AL ORDENAMIENTO LINEAL.

 
     #include <iostream>

     using namespace::std;

  

     #include <iomanip>   //PARA PODER USAR setw

 
   int main()


   {

   // AQUI VAN LAS DECLARACIONES DE VARIABLES.



   const int Tamano_Arreglo = 10;

   int A[10] = { 2, 6, 4, 8, 10, 12, 89, 68, 45, 37};  
   //NO SE PUEDE INICIALIZAR SI SE PONE UNA CONSTANTE COMO TAMANO DEL ARREGLO.
   int i, hold, pass, j;

   // TERMINAN LAS DEFINICIONES DE VARIABLES.

    cout << "\n\nESTE PROGRAMA ES UNA MEJORA AL ORDENAMIENTO LINEAL. " << endl;
    cout << "Aqui estan los datos del arreglo en el orden original. " << endl;

  // ESTE CICLO FOR ES PARA IMPRIMIR LOS DATOS DEL ARREGLO A[].


    for ( i = 0; i < Tamano_Arreglo; i++ )

      cout << setw(4) << A[i];

  // TERMINA EL CICLO PARA IMPRIMIR DATOS.

  // ESTOS CICLOS ANIDADOS ORDENAN EL ARREGLO.


    for ( pass = 0; pass < Tamano_Arreglo - 1; pass++ )

      for ( i = 0, j = Tamano_Arreglo -1; i < j; i++, j-- )

      if ( A[i] > A[i+1])

      {

       hold = A[i];

       A[i] = A[i +1];
       A[i + 1] = hold;

      }

  // AQUI TERMINA EL ORDENAMIENTO DEL ARREGLO

  // EN LA ULTIMA PARTE DEL PROGRAMA SE IMPRIMEN LOS DATOS ORDENADOS.

   cout << "\nLos datos en orden ascendente: " <<endl;


   for ( i = 0; i < Tamano_Arreglo; i++ )
     cout << setw(4) << A[i];

   return 0;

  }             

Deitel_C++_4.10 (Comisión por ventas)

4.10 Utilice un arreglo con un sólo subíndice para resolver el siguiente problema. Una empresa paga a su personal de ventas en base a una comisión. El personal de ventas recibe $200 por semana, más 9 por ciento de sus ventas totales semanales. Por ejemplo, un vendedor que suma $5000 en ventas semanales recibe $200 más el 9 por ciento de $5000, o un total de $650. Escriba un programa (mediante el uso de contadores de arreglos) que determine cuántos de los vendedores reciben salarios en cada uno de los siguientes rangos ( suponga que el salario de cada vendedor se trunca para obtener un monto entero):
a) de $200 a $299
b) de $300 a $399
c) de $400 a $499
d) de $500 a $599
e) de $600 a $699
f) de $700 a $799
g) de $800 a $899
h) de $900 a $999
i) de $1000 o más

Solución:
// ESTE PROGRAMA CALCULA LOS SALARIOS DE 10 TRABAJADORES QUE GANAN UN SUELDO BASE DE 200 MAS 9 % DE SUS VENTAS SEMANALES.
#include <iostream>
    using namespace::std;
    int Tamano_Arreglo = 10;

   int main()

   {  // Abre main

    float A[Tamano_Arreglo + 1];
    int B[Tamano_Arreglo + 1], C[11] = {0};
    int i, j, k;
    float ventas;

    cout << "\n\nEste programa calcula los rangos en los que estan los salarios de los " << Tamano_Arreglo <<" empleados. "<< endl;
    for ( i = 1; i <= Tamano_Arreglo; i++ )
      {
       cout << endl << endl << endl <<"Introduzca las ventas del empleado numero " << i << endl;
       cin >> ventas;
       A[i] = (static_cast<float>(9)/100)*ventas + 200.00;
       cout << "El salario del empleado " << i << " es: " <<  A[i] << endl;
       B[i] =  static_cast< int >( A[i] )/100;
      }

    for ( k = 1; k <= Tamano_Arreglo; k++ )
      {
       if ( B[k] < 10)
       C[B[k]]++;
       else
       C[Tamano_Arreglo]++;
      }
 
   for ( j = 2; j < Tamano_Arreglo; j++ )

     {
      cout << endl << "Hay " << C[j] <<" empleados que cobran entre "  << (j * 100) << " y ";
      cout << (( j + 1 ) * 100 ) - 1 << " pesos " <<endl;
     }

   cout <<endl<<"Hay " << C[(Tamano_Arreglo)] << " empleados que cobran 1000 o mas."<<endl <<endl << endl;
   return 0;
   }  // Cierra main

Deitel_C++_3.59 (el mayor de tres enteros usando plantilla)

Este programa utiliza una plantilla para determinar el mayor de unos argumentos.
    # include <iostream>
   using namespace std;

   template < class Si >
   Si  maximo (Si valor1, Si  valor2, Si  valor3)
   {
   Si max = valor1;
   if (valor2 > max)
   max = valor2;

   if (valor3 > max )
   max = valor3;

   return max;
   }

   ////////////////////////////////////////////////
   //MAIN
   ////////////////////////////////////////////////
   int main()
   {
    int entero1, entero2, entero3;
    
    cout<<"\n\nIntroduzca tres valores enteros y sabra cual es el mayor: " << endl;
    cin >> entero1 >> entero2 >> entero3;
    cout <<"\nEl mayor entero es: " << maximo(entero1, entero2, entero3) << endl;

    double doble1, doble2, doble3;

    cout <<"\nIntroduzca tres valores double y sabra cual es el mayor: " << endl;
    cin >> doble1 >> doble2 >> doble3;
    cout <<"\nEl mayor valor doble es: " << maximo(doble1, doble2, doble3) << endl;

    return 0;

   }

Deitel_C++_3.58 (El mínimo de tres números mediante el uso de plantilla en C++)


// QUE HACE ESTE PROGRAMA?        
            
#include <iostream>           
using namespace::std;           
            
int Que_Es_Esto(int[], int); // FUNCION INCOGNITA       
            
int main()           
            
{            
const int Tamano_Arreglo = 10;        
int A[Tamano_Arreglo] = {1,2,3,4,5,6,7,8,9,10};         
int resultado = Que_Es_Esto(A, Tamano_Arreglo);        
            
cout <<"\nEl resultado es: " << resultado << endl;    
            
return 0;           
}            
            
            
int Que_Es_Esto(int b[], int size)        
{            
if ( size == 1 )       
return b[0];           

else            
return b[ size - 1 ] + Que_Es_Esto( b, size - 1 );
}            

Deitel_C++_3.55 (Calcular el Área de un Círculo en C++)

3.55 Escriba un programa en C++ que utilice una función inline CircleArea que pida al usuario el radio del círculo, y que calcule y despliegue el área de ése círculo.


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++
 * PROGRAMA QUE CALCULA EL AREA DE UN CIRCULO         *
 *                                                    *
 * LO QUE RECIBE: EL RADIO DEL CIRCULO                *
 *                                                    *
 * LO QUE REGRESA: EL AREA DEL CIRCULO                *
 *                                                    *
 * ****************************************************/

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 *                                                                             *
 *                                ALGORITMO:                                   *
 *                                                                             *
 * PEDIR EL RADIO DEL CIRCULO AL USUARIO                                       *
 * RECIBIR EL RADIO DEL CIRCULO                                                *
 *                                                                             *
 * CALCULAR EL AREA DEL CIRCULO USANDO A = PI*R*R                              *
 *                                                                             *
 * DESPLEGAR EL AREA DEL CIRCULO                                               *
 * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
               
//Introduce inline.              
               
# include <iostream>             
#include <iomanip>              
               
using namespace std;             
               
///////////////////////////////////////
// FUNCION INLINE CIRCLEAREA
///////////////////////////////////////

inline float CircleArea (const float r){return 3.1416 * r * r; }    

///////////////////////////////////////
// FUNCION MAIN
///////////////////////////////////////               

int main()              
               
{   /* Abre main */               
               
float radio;              
               
cout<<"\n\nEste programa calcula el area de un circulo. " << endl;     
cout<<"Teclee el radio. "<<endl;            
cin >> radio;             
cout<<"El area del circulo con radio" << radio << " es " << CircleArea(radio) <<endl; 
               
return 0;              
}   /* Cierra main */            

Deitel_C++_3.52 (Prueba de Funciones Matemáticas de C++)

3.52 Escriba un programa que pruebe tantas de las funciones matemáticas de la librería como pueda. Ejercite cada una de estas funciones haciendo que su programa imprima tablas de valores devueltos para una variedad de valores de argumentos.

// Probando funciones de <cmath>
#include <iostream> #include <iomanip> #include <cmath> using namespace std; // Requiere de <iostream> using std::setw; // Requiere de <iomanip> int main() { long double x, y; cout <<"\n\nEste programa prueba algunas funciones de el encabezado <cmath>."<<endl; cout <<"Introduzca un numero. " <<endl; cin >> x; cout<<"\nLa funcion ceil(x ) redondea x al entero mas pequenio no menor que x. " << setw (10) << ceil(x) <<endl; cout<<"La funcion cos(x) da el coseno de x. " <<setw(10) <<cos(x) << endl; cout<<"La funcion exp(x) da el valor e elevado a la x. " <<setw(10)<< exp(x) <<endl; cout<<"La funcion fabs(x) da el valor absoluto de x. " << setw(3) << fabs(x) <<endl; cout<<"La funcion floor(x) redondea x al entero mas grande no mayor que x. " <<setw(3) << floor(x) <<endl; cout<<"La funcion log(x) da el logaritmo base 10 de x. " << setw(3)<< log(x) << endl; cout<<"La funcion sin(x) da el seno de x. " << setw(3) << sin(x) << endl; cout<<"La funcion sqrt(x) da la raiz cuadrada de x. " << setw(3) << sqrt(x) <<endl; cout<<"La funcion sin(x) da el seno de x. " << setw(3) << sin(x) << endl; cout<<"La funcion sqrt(x) da la raiz cuadrada de x. " << setw(3) << sqrt(x) <<endl; cout<<"La funcion tan(x) da la tangente de x. " << setw(3) << sqrt(x) <<endl; cout<<"Introduzca otro numero. " <<endl; cin >> y; cout<<"La funcion fmod(x,y) da el residuo de x/y como un numero de punto flotante. " << setw (5) << fmod(x,y) <<endl; cout<<"La funcion pow(x,y) da el valor de x elevado a la y. " <<setw(3) << pow(x,y) << endl; return 0; }

Deitel_C++_3.48 (Distancia entre dos puntos en C++ con el teorema de Pitágoras)

_____________________________________________________________________________________
3.48 Escriba una función distancia que calcule la distancia entre dos puntos (x1,y1) y (x2,y2). Todos los números y los valores devueltos deben ser del tipo double.
_____________________________________________________________________________________
Para este problema es útil la siguiente figura que presenta un triángulo rectángulo. En ella se identifican los lados del triángulo (a, b y c) El lado más grande es llamada hipotenusa, y los otros son llamados catetos. El matemático griego Pitágoras demostró que la relación entre los lados de un triángulo rectángulo es la siguiente: c² = a² + b²





/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    *                                                                    *
    *     PROGRAMA QUE CALCULA LA DISTANCIA ENTRE DOS PUNTOS             *
    *                                                                    *
    *  LO QUE RECIBE: LAS COORDENADAS DE LOS DOS PUNTOS                  *
    *  LO QUE DEVUELVE: LA DISTANCIA ENTRE LOS DOS PUNTOS                *
    *                                                                    *
    * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
   
   /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    *                                                                                            *
    *                                         ALGORITMO:                                         *
    *                                                                                            *
    *  Pide las coordenadas del primer punto                                                     *
    *     Recibe las coordenadas                                                                 *
    *  Pide las coordenadas del segundo punto                                                    *
    *     Recibe las coordenadas                                                                 *
    *                                                                                            * 
    *  Calcular la distancia entre los dos puntos usando el teorema de Pitagoras                 *
    *  Presentar esa distancia en pantalla                                                       *
    *                                                                                            *
    * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
   

   # include <iostream>
   # include <cmath>
   # include <iomanip>
 
   using namespace std;
   using std::setw;
   
   //////////////////////////////////////////////////////////////////////////////
   // PROTOTIPO DE FUNCION DISTANCIA
   //////////////////////////////////////////////////////////////////////////////
   
   float distance(float, float, float, float);
 
   //////////////////////////////////////////////////////////////////////////////
   //FUNCION MAIN
   //////////////////////////////////////////////////////////////////////////////
   
   int main()
   {              /* Abre main */

   float x1, x2, y1, y2, distancia;
   
   cout <<"\n\nEste programa calcula la distancia entre dos puntos en el plano cartesiano. "<<endl;
   cout <<"\n\nIntroduzca las coordenadas del primer punto: "<<endl;
   cin >> x1 >>  x2;

   cout <<"\nIntroduzca las coordenadas del segundo punto: " <<endl;
   cin >> y1 >>  y2;

   distancia = sqrt((x1 - y1)*(x1 - y1 ) + (x2 - y2)*(x2 - y2));

   cout <<"\nLa distancia entre los puntos es: " << setw(10) <<distancia << endl;

   return 0;
   
   }            /* Cierra main */

Deitel_C++_3.47 (Educación Asistida por Computadora, Aprendiendo las Tablas de Multiplicar)


                
// Programa para multiplicar dos numeros.           
                
#include <iostream>               
#include <cstdlib>               
#include <ctime>               
#include <cmath>               
                
using namespace std;              
                
int Generador(int);               
void Incorrectas(void);               
void Correctas(void);               
                
int main()               
{                
int number1, number2, digito;             
int respuesta, correctas = 0;            
int incorrectas = 0;             
int GeneralCounter = 0;             
int centinela = 1;             
                
srand (time (NULL));              
cout <<"\n\nEste programa le ayudara a aprender a multiplicar proponiendole ejercicios."<<endl;      
                
while (1 == centinela)             
{                
cout <<"Introduzca el numero de cifras que tendran sus numeros: " << endl;    
cin >> digito;              

number1 = Generador(digito);              
number2 = Generador(digito);              
                
cout <<"\nCuanto es "<<number1 <<" x " <<number2 << " ? "<<endl;     
cin >> respuesta;              
                
incorrectas = 0;              
                
while ( number1 * number2 != respuesta )         
{                
Incorrectas();                
cin >> respuesta;              
incorrectas++;                
GeneralCounter++;                
                
if ( 10 <= incorrectas )           
{                
cout <<"\nPide ayuda a tu maestro."<<endl;           
return 0;               
}                
                
}                
                
if ( 10 <= GeneralCounter)            
if (.25 * GeneralCounter >= correctas)           
{                
cout <<"\nPide ayuda a tu maestro." << endl;         
return 0;               
}                
                
Correctas();                
correctas++;                
GeneralCounter++;                
                
cout<<"\nSi quiere seguir introduzca 1, si no cualquier otro numero." << endl << endl;   
cin >> centinela;              
                
}                
                
return 0;               
}                
                

//Esta es la funcion Generador            
int Generador(int x )             
{                
                
int numero = rand () % 10;          
int multiplicador;               
                
if ( 0 < x )           
{                
if ( 1 < x )           
{                
for ( int n = 1; n <= x; n++ )      
{                
multiplicador = 1;              
for ( int m = 1; m < n; m++ )      
multiplicador *= 10;              
numero += ( rand() % 10 ) * multiplicador;        
}                
                
return numero;               
}                
                
else                
return rand() % 10;             
}                
                
else                
{                
return 0;               
}                
                
}                
                
//Definicion de la funcion Incorrectas.            
                
void Incorrectas(void)               
{                
int n = 1 + rand () % 4;        
                
switch(n)                
{                
case 1:               
cout <<"\nNo. Por favor trata de nuevo. " <<endl;        
break;                
case 2:               
cout <<"\nIncorrecto. Trata una vez mas. \n";          
break;                
case 3:               
cout <<"No te rindas."<<endl;             
break;                
case 4:               
cout <<"\nNo. Trata de nuevo." <<endl;           
break;                
default :               
cout <<"\nESTE PROGRAMA ESTA MAL! NO DEBERIA VER ESTE MENSAJE!"<<endl<<endl;       
break;                
}                
return;                
}                
                
// Aqui se define la funcion Correctas.          
void Correctas(void)               
{                
int n = 1 + rand() % 4;         

switch(n)                
{                
case 1:               
cout <<"\n Muy bien!"<<endl;             
break;                
case 2:               
cout <<"\nExcelente!"<<endl;               
break;                
case 3:               
cout <<"\nBuen trabajo!."<<endl;              
break;                
case 4:               
cout <<"\nSigue haciendolo bien!."<<endl;             
break;                
default:                
cout <<"\nSU PROGRAMA ESTA MAL! NO DEBERIA VER ESTE MENSAJE!"<<endl<<endl;       
break;                
}                
                
return;                
}                


Deitel_C++_3.46 (Llamada Recursiva a main)

Este programa crea un ciclo infinito.

          
/*+++++++++++++++++++++++++++++++++++++++++++++++++
 *                                                 +
 *  ESTE PROGRAMA LLAMA RECURSIVAMENTE A MAIN      *
 *                                                 *
 *+++++++++++++++++++++++++++++++++++++++++++++++++*/    
          
#include <iostream>         
using namespace::std;        

///////////////////////////////////////////////////////////////
// FUNCION MAIN
///////////////////////////////////////////////////////////////

int main()                             
{          
static int counter = 1;      
cout <<"\n\nUn valor de counter: " << counter++ << endl; 

/*Se llama a la funcion main dentreo de main */
main();          
          
return 0;                   
}          
          

Deitel_C++_3.45 (Maximo Comun Divisor en forma recursiva)

_____________________________________________________________________________________
3.45 (Recursividad para el Máximo Común Divisor) El máximo común divisor de los enteros x y y es el entero más grande que divide tanto a x como a y. Escriba una función reursiva mcd que devuelva el máximo común divisor de x y y, la cual está definida recursivamente de la siguiente manera: se y es igual a 0, entonces, mcd(x, y) es x; de otro modo, mcd(y, x%y), donde % es el operador módulo.
_____________________________________________________________________________________
El programa es bastante simple, y la función gcd está definida exactamente como se especifica en el enunciado del problema. El programa en sí mismo es bastante fácil de leer y seguir. Cópielo, ejecútelo y modifíquelo para mejorarlo si quiere.


////////////////////////////////////////////////////////////
//                                                        //
// Este programa recibe un par de enteros positivos y     //
// calcula el maximo comun divisor mediante la recursion  //
////////////////////////////////////////////////////////////
   
#include <iostream>
using namespace std;
int gcd (int, int);

int main()

{       /*Abre main*/
unsigned int a, b, max;

cout <<"\n\nSe calcula el maximo comun divisor de dos numeros."<<endl;
cout <<"Introduzca dos numeros enteros no negativos: "<<endl;
cin >> a >> b;

if ( a >= b )
max = gcd (a,b);
else
max = gcd (b,a);
cout <<"\nEl maximo comun divisor de los numeros es: "
<<max << endl;
 
return 0;
}     /*Cierra main*/

//////////////////////////////////////////////////////////////////////
// FUNCION GCD
//////////////////////////////////////////////////////////////////////

int gcd (int x, int y)

{            /*Abre gcd*/
if (0 == y)
return x;
else
return gcd (y, x%y);
}           /*Cierra gcd*/

Una ejecución de éste programa es la siguiente

[hernandez@localhost Programas]$ ./a.out 
Se calcula el maximo comun divisor de dos numeros.
Introduzca dos numeros enteros no negativos: 

568
456

El maximo comun divisor de los numeros es: 8

Deitel_C++_3.44 (Visualización de la Recursión en C++ con Factorial de 10)

_____________________________________________________________________________________
3.44 (Visualización de la recursividad) Es interesante observar a la recursividad en "acción". Modifique la función factorial de la figura 3.14 para que despliegue su variable local y el parámetro de llamada recursiva. Por cada llamada recursiva, despliegue los resultados en una línea diferente y agregue un nivel de sangrado. Haga su mayor esfuerzo para que sus resultados sean claros, interesantes y útiles. Su objetivo aquí es diseñar e implementar un formato para los resultados que ayude a una persona a comprender mejor la recursividad. Tal vez desee agregar dichas capacidades de despliegue a los muchos otros ejemplos y ejercicios sobre recursividad que contiene el libro.
_____________________________________________________________________________________
Solución:
// Calculo de factoriales.
    #include <iostream>
     #include <iomanip>
     using namespace std;
     using std::setw;
    unsigned long factorial (unsigned long);
 
   int main()

    {
    cout <<endl<<endl<<"Se presentan los factoriales de los primeros";
    cout <<" 10 enteros."<<endl;
    for ( int i = 0; i <= 10; i++)
       cout << setw(2) << i << "! = " <<factorial(i) << endl;

    return 0;

  }

  ////////////////////////////////////////////////////
  // FACTORIAL
  ////////////////////////////////////////////////////
    unsigned long factorial (unsigned long number)

   {
    if ( number <= 1 )
    return 1;
    else

    {
    cout <<number <<" Llamada recursiva a factorial de: "
         << number - 1<< endl;
    return number * factorial(number-1);

    }
   }

la ejecución del programa produce la siguiente salida:


Se presentan los factoriales de los primeros 10 enteros.
 0! = 1
 1! = 1
2 Llamada recursiva a factorial de: 1
 2! = 2
3 Llamada recursiva a factorial de: 2
2 Llamada recursiva a factorial de: 1
 3! = 6
4 Llamada recursiva a factorial de: 3
3 Llamada recursiva a factorial de: 2
2 Llamada recursiva a factorial de: 1
 4! = 24
5 Llamada recursiva a factorial de: 4
4 Llamada recursiva a factorial de: 3
3 Llamada recursiva a factorial de: 2
2 Llamada recursiva a factorial de: 1
 5! = 120
6 Llamada recursiva a factorial de: 5
5 Llamada recursiva a factorial de: 4
4 Llamada recursiva a factorial de: 3
3 Llamada recursiva a factorial de: 2
2 Llamada recursiva a factorial de: 1
 6! = 720
7 Llamada recursiva a factorial de: 6
6 Llamada recursiva a factorial de: 5
5 Llamada recursiva a factorial de: 4
4 Llamada recursiva a factorial de: 3
3 Llamada recursiva a factorial de: 2
2 Llamada recursiva a factorial de: 1
 7! = 5040
8 Llamada recursiva a factorial de: 7
7 Llamada recursiva a factorial de: 6
6 Llamada recursiva a factorial de: 5
5 Llamada recursiva a factorial de: 4
4 Llamada recursiva a factorial de: 3
3 Llamada recursiva a factorial de: 2
2 Llamada recursiva a factorial de: 1
 8! = 40320
9 Llamada recursiva a factorial de: 8
8 Llamada recursiva a factorial de: 7
7 Llamada recursiva a factorial de: 6
6 Llamada recursiva a factorial de: 5
5 Llamada recursiva a factorial de: 4
4 Llamada recursiva a factorial de: 3
3 Llamada recursiva a factorial de: 2
2 Llamada recursiva a factorial de: 1
 9! = 362880
10 Llamada recursiva a factorial de: 9
9 Llamada recursiva a factorial de: 8
8 Llamada recursiva a factorial de: 7
7 Llamada recursiva a factorial de: 6
6 Llamada recursiva a factorial de: 5
5 Llamada recursiva a factorial de: 4
4 Llamada recursiva a factorial de: 3
3 Llamada recursiva a factorial de: 2
2 Llamada recursiva a factorial de: 1
10! = 3628800

Deitel_C++_3.42 (Torres de Hanoi en C++, Version Recursiva)

_____________________________________________________________________________________
3.42 (Las Torres de Hanoi) Cada científico de la computación en ciernes debe batallar con ciertos problemas clásicos. Las Torres de Hanoi representan uno de los más famosos. La leyenda cuenta que en un templo del lejano oriente, unos sacerdotes intentan mover una pila de discos de una pila a otra. La pila inicial tiene 64 discos y están acomodados de abajo hacia arriba en orden de tamaño decreciente. Los sacerdotes intentan mover la pila de esta pila hacia una segunda, con las restricciones de mover sólo un disco a la vez, y que ningún disco más grande debe colocarse en encima de uno más pequeño. Una tercera pila está disponible para alojar temporalmente los discos. Se supone que el mundo terminará cuando los sacerdotes completen su tarea, por lo cual no hay ningún incentivo para facilitarles la tarea.
_____________________________________________________________________________________

Antes de intentar resolver este problema es bueno conseguirse un juego de torres de hanoi por ahi, los he visto en puestos callejeros de ajedrez, cartas, etc.; o improvisar uno, como hacen en las ferias de ciencias; tal vez la primera impresion sea que es complicado, sin embargo no tardaran en darse cuenta de que una vez que logran agarrar la idea, la solucion es bastante aburrida, solo hay que repetir una y otra vez el mismo procedimiento. Es por eso que este problema es tan susceptible de ser resuelto mediante la recursion. Se daran cuenta de que hay que solucionarlo de abajo para arriba. Tienen que mover el disco que esta en el fondo hacia la espiga de destino, para hacer esto tienen que mover una torre un poco menor (de solo N-1 discos) hacia la espiga destino. Este ultimo paso es crucial. Es muydiscos) hacia la espiga intermedia y entonces si mover el disco mas grande a su destino. Ahora lo que falta es mover la torre de N - 1 discos que esta en la importante darse cuenta de que la torre con N - 1 discos se mueve DOS VECES, la primera hacia la espiga intermedia y la segunda hacia la espiga de destino despues de haber movido el disco de abajo. Si logran comprender esto entonces ya resolvieron el problema, solo hagan lo mismo con todas las torres hasta que lleguen a tener una torre con un solo disco. En ese caso limite ya no necesitan usar una espiga intermedia, pueden pasar directamente el disco del origen al destino.


# include <iostream>

using namespace::std;

////////////////////////////////////////////////////////////////////

// FUNCION MOVER_TORRES

////////////////////////////////////////////////////////////////////

void Mover_Torres(int N, int Origen, int Intermedio, int Destino)

{ // Abre funcion Mover_Torres

if ( N > 1 )

{ // Abre if
Mover_Torres( N - 1, Origen, Destino, Intermedio);

/* Se mueve una torre de N - 1 discos desde la espiga origen
pero hacia la espiga intermedia ( para dejar la destino libre)
usando la espiga destino como intermedia cout << "\nMueve disco "
<< N << " de " << Origen << " a " << Destino <<endl;
con esta instruccion mueven el disco de la base hacia su destino
Como comento arriba, ahora hay que mover nuevamente la torre de
N - 1 discos hacia el destino original ( en donde se ha puesto el
disco mayor ) Esto implica una segunda llamada recursiva. Ahora
el origen es la espiga intermedia a la que se movio la torre y
el destino es el destino primitivo,lo que originalmente era el
origen se usa ahora como espiga intermedia */

cout <<"\nMueve el disco " <<  N  << " de " << Origen << " a " <<  Destino << endl;
Mover_Torres( N - 1, Intermedio, Origen, Destino);
} // Cierra if

// El caso limite mas sencillo se resuelve directamente

if ( 1 == N )
cout << "\nMueve el disco 1 de " << Origen << " a " << Destino << endl;

} // Cierra funcion Mover_Torres

int main()

{ // Abre funcion main
int Discos;
cout << "\nEste programa resuelve el problema clasico de las Torres de Hanoi";
cout <<" mediante la recursion." << endl;
cout << "\nPor favor introduzca el numero de discos que quiere mover ";
cout << " de la pila 1 a la pila 3" << endl;
cin >> Discos;

Mover_Torres( Discos, 1, 2, 3);

cout << endl << endl;

return 0;

} // Cierra funcion main


Como nota final se daran cuenta de que para pasar N discos de una torre a otra se requieren (2^N) - 1 movimientos. Asi que si los monjes de marras inician con una torre de 64 discos necesitaran hacer (2 ^ 64) - 1 ( = 18446744073709551616) movimientos para terminar. Suponiendo que hacen un movimiento por segundo entonces necesitarian 584942417355 años para terminar el trabajo. Pero como esto supera, y con mucho, la edad del universo, entonces no hay por que preocuparse de los avances de los monjes ni del fin del mundo.

Deitel_C++_3.41 (Números de Fibonacci en C++)

_____________________________________________________________________________________
Ejercicio 3.41 (La Serie de Fibonacci) La serie de Fibonacci 0, 1, 1, 2, 3, 5, 8, 13, 21, .... empieza con los números 0 y 1, y tiene la propiedad de que cada término sucesivo es la suma de los dos términos anteriores. a) Escriba una función no recursiva llamada fibonacci(n) que calcule el enésimo número de Fibonacci. b) Determine el número más grande de Fibonacci que puede desplegar su sistema. c) Modifique la parte a) del programa para que utilice double en lugar de int para que calcule y devuelva números de Fibonacci, y utilice este programa modificado para repetir la parte b)
_____________________________________________________________________________________
Solución:
La serie es una clásica de las ciencias de la complejidad, pensada, en un principio, como un modelo de crecimiento de una población de conejos. Para mayor información, revise un algo acerca de la sucesión de Fibonacci en Ésta página.
//Calcula la serie de Fibonacci

   #include <iostream>
   using namespace std;
   
   
   /*Prototipo de la funcion fibonacci*/
   int fibonacci (int);
   
   ///////////////////////////////////////////////////////////////////
   // MAIN
   ///////////////////////////////////////////////////////////////////
   int main()
 
   {

    int number, respuesta;
    cout <<endl<<endl<< "Este programa calcula el numero de Fibonacci."<<endl;
    cout <<"Introduzca un numero: " <<endl;
    cin >> number;

    if (0 == number || 1 == number )
    cout <<"Fibonacci de: " << number<<" es " << number << endl;
    else
      {

      respuesta = fibonacci (number);
      cout<<"Fibonacci de " << number << " es " << respuesta << endl;

      }
    return 0;

   }

  /////////////////////////////////////////////////////////////////////
  // FUNCION FIBONACCI
  /////////////////////////////////////////////////////////////////////
  
   int fibonacci (int number)

   {
   int fib1 = 0, fib2 = 1, fibn = 0, temp;

   for ( int n = 2; n <= number; ++n )
   {
   fibn = fib2 + fib1;
   temp = fib2;
   fib2 = temp + fib1;
   fib1 = temp;
   }

   return fibn;
   }

Deitel_C++_3.38 (Adivinar un Número en C++)

_____________________________________________________________________________________
3.38 Escriba un programa que juegue a "adivina un número", de la siguiente forma: Su programa elige el número que debe adivinarse, seleccionando un entero al azar en el rango de 1 a 2000. Si la opción del jugador es incorrecta, su programa debe repetirse hasta que el jugador obtenga el número correcto. Su programa debe continuar diciendo al jugador "Demasiado alto" o "Demasiado Bajo", para ayudar al jugador a acertar en la respuesta.
_____________________________________________________________________________________


//Programa adivine un numero.

   #include <iostream>
   using namespace::std;
   #include <ctime>
   #include <cstdlib>

   int incognita;
   int juego(int);

   int main()
   {
    int respuesta = 1;
    srand (time (NULL));
    while (1 ==  respuesta)
     {
       incognita = 1 + rand() % 1000;
       respuesta = juego(incognita);
     }

    return 0;

   }

 ////////////////////////////////////////////////////
 // FUNCION JUEGO
 ////////////////////////////////////////////////////
 
   int juego(int incognita1)

  {
   int intento, respuesta;
   cout<<endl<<endl<<"Tengo un numero entre 1 y 1000." << endl;
   cout<<"Puede adivinar el numero?"<<endl;
   cout<<"Por favor introduzca su primer intento." <<endl;
   cin>> intento;

   while (incognita1 != intento)
     {
      if ( intento < incognita1 )
      {
      cout << "Muy bajo. Intente de nuevo." <<endl;
      cin >> intento;

      }

      else
      cout <<"Muy alto. Intente de nuevo." <<endl;
      cin >> intento;
     }

   cout <<"Excelente!. Adivino el numero!"<< endl;
   cout <<"Deseas jugar otra vez? (1 para continuar, otro numero para continuar)"<<endl;
   cin>>respuesta;
   return (respuesta);
  }
 
Related Posts Plugin for WordPress, Blogger...