domingo, 22 de noviembre de 2015

Uso de datos primitivos en codigo c y sus respectivas ejecuciones

Enunciado
Un programa que permita leer 10 numeros enteros obtener suma y calcular el promedio de dichos numeros.codifiquelos en C y C++, ejecútelos y entregue un informe de laboratorio.
C++
#include<iostream>
Usingnamespace std;
main()
{
       int number, w;
       int adicion;
       float promedio;
       sum=0;
       printf("ingrese 10 numeros \n\n");
       for (w=1;w<=10;w++)
       {
              scanf ("%d",&num);
              adicion=adicion+number;
       }
       promedio=adicion/10;
       printf("\n suma =%d, adicion");
       printf("\n promedio = %5.2f,promedio");
       getch();
       }


C
#include<stdio.h>

main()
{
       int number, w;
       int adicion;
       float promedio;
       sum=0;
       printf("ingrese 10 numeros \n\n");
       for (w=1;w<=10;w++)
       {
              scanf ("%d",&num);
              adicion=adicion+number;
       }
       promedio=adicion/10;
       printf("\n suma =%d, adicion");
       printf("\n promedio = %5.2f,promedio");
       getch();

       }

Estructuras de datos fundamentales y sus tipos de estructuras





Tipos de Arreglos

Clasificacion de los arreglos

Un arreglo unidimensional 

Es un tipo de datos estructurado que está formado de una colección finita y ordenada de datos del mismo tipo. Es la estructura natural para modelar listas de elementos iguales. 
El tipo de acceso a los arreglos unidimensionales es el acceso directo, es decir, podemos acceder a cualquier elemento del arreglo sin tener que consultar a elementos anteriores o posteriores, esto mediante el uso de un índice para cada elemento del arreglo que nos da su posición relativa.
Para implementar arreglos unidimensionales se debe reservar espacio en memoria, y se debe proporcionar la dirección base del arreglo, la cota superior y la inferior. 

REPRESENTACION EN MEMORIA 

Los arreglos se representan en memoria de la forma siguiente: x : array[1..5] of integer 
Para establecer el rango del arreglo (número total de elementos) que componen el arreglo se utiliza la siguiente formula: RANGO = Ls - (Li+1)donde: 

ls = Límite superior del arreglo 
li = Límite inferior del arreglo 
Para calcular la dirección de memoria de un elemento dentro de un arreglo se usa la siguiente 

formula: A[i] = base(A) + [(i-li) * w]donde : 
A = Identificador único del arreglo 

i = Indice del elemento 
li = Límite inferior 
w = Número de bytes tipo componente 

Si el arreglo en el cual estamos trabajando tiene un índice numerativo utilizaremos las siguientes fórmulas: RANGO = ord (ls) - (ord (li)+1) A[i] = base (A) + [ord (i) - ord (li) * w] 


Arreglos bidimensionales 

Los arreglos bidimensionales se usan para representar datos que pueden verse como una tabla con filas y columnas. La primera dimensión del arreglo representa las columnas, cada elemento contiene un valor y cada dimensión representa una relación .
La representación en memoria se realiza de dos formas : almacenamiento por columnas o por renglones.
Para determinar el número total de elementos en un arreglo bidimensional usaremos las siguientes fórmulas: 

RANGO DE RENGLONES (R1) = Ls1 - (Li1+1) RANGO DE COLUMNAS (R2) = Ls2 - (Li2+1) No. TOTAL DE COMPONENTES = R1 * R2 

REPRESENTACION EN MEMORIA POR COLUMNAS 
x : array [1..5,1..7] of integer 
Para calcular la dirección de memoria de un elemento se usan la siguiente formula: A[i,j] = base (A) + [((j - li2) R1 + (i + li1))*w] 


Arreglos multidimensionales 

El término dimensión representa el número de índices utilizados para referirse a un elemento particular en el arreglo. Los arreglos de más de una dimensión se llaman arreglos multidimensionales. 
/* 
/ dosDim.cpp 
*/ 
#include 
#define numFilas 4 
#define numColumnas 5 
int main (int argc, char * const argv[]) { 
int despFila, despColumna, desplazamiento, multiplo, 
despCalculados[numFilas][numColumnas]; 

for(despFila=0;despFila
for(despColumna=0;despColumna
desplazamiento=numColumnas-despColumna; 
multiplo=despFila; 
despCalculados[despFila][despColumna]= 
(despFila+1)*despColumna+desplazamiento * multiplo; 
}; 
for(despFila=0;despFila
std::cout<<"Fila actual: "<<despfila<<"\n"; 
std::cout<<"Distancia relativa desde la base: "<<"\n"; 
for(despColumna=0;despColumna
std::cout<<" " 
<
<<" "; 
std::cout<<"\n\n"; 

return 0; 
El programa utiliza dos ciclos for para calcular e inicial cada uno de los elementos del arraglo a su respectiva distancia relativa desde la base. El arreglo creado tiene 4 filas y 5 columnas por fila, haciendo un total de 20 elementos enteros. 
Son almacenados de forma lineal en la memoria de la computadora. Los elementos en los arreglos multidimensionales están agrupados desde el índice más a la derecha hacia el centro. En el ejemplo anterior, fila 1, columna 1 sería el elemento 3 del arreglo almacenado. Aunque el cálculo del desplazamiento aparece un poco difícil, es referenciado fácilmente cada elemento del arreglo. 
La salida del programa anterior es: 
Fila actual: 0 
Distancia relativa desde la base: 
0 1 2 3 4 
Fila actual: 1 
Distancia relativa desde la base: 
5 6 7 8 9 
Fila actual: 2 
Distancia relativa desde la base: 
10 11 12 13 14 
Fila actual: 3 
Distancia relativa desde la base: 
15 16 17 18 19 
dosdim has exited with status 0. </despfila<<"\n";>

Arreglos

Arreglos

Las estructuras de datos que hemos visto hasta ahora (listas, tuplas, diccionarios, conjuntos) permiten manipular datos de manera muy flexible. Combinándolas y anidándolas, es posible organizar información de manera estructurada para representar sistemas del mundo real.
En muchas aplicaciones de Ingeniería, por otra parte, más importante que la organización de los datos es la capacidad de hacer muchas operaciones a la vez sobre grandes conjuntos de datos numéricos de manera eficiente. Algunos ejemplos de problemas que requieren manipular grandes secuencias de números son: la predicción del clima, la construcción de edificios, y el análisis de indicadores financieros entre muchos otros.
La estructura de datos que sirve para almacenar estas grandes secuencias de números (generalmente de tipo float) es el arreglo.
Los arreglos tienen algunas similitudes con las listas:
  • los elementos tienen un orden y se pueden acceder mediante su posición,
  • los elementos se pueden recorrer usando un ciclo for.
Sin embargo, también tienen algunas restricciones:
  • todos los elementos del arreglo deben tener el mismo tipo,
  • en general, el tamaño del arreglo es fijo (no van creciendo dinámicamente como las listas),
  • se ocupan principalmente para almacenar datos numéricos.
A la vez, los arreglos tienen muchas ventajas por sobre las listas, que iremos descubriendo a medida que avancemos en la materia.
Los arreglos son los equivalentes en programación de las matrices y vectores de las matemáticas. Precisamente, una gran motivación para usar arreglos es que hay mucha teoría detrás de ellos que puede ser usada en el diseño de algoritmos para resolver problemas verdaderamente interesantes.

Crear arreglos

El módulo que provee las estructuras de datos y las funciones para trabajar con arreglos se llamaNumPy, y no viene incluído con Python, por lo que hay que instalarlo por separado.
Descargue el instalador apropiado para su versión de Python desde la página de descargas de NumPy. Para ver qué versión de Python tiene instalada, vea la primera línea que aparece al abrir una consola.
Para usar las funciones provistas por NumPy, debemos importarlas al principio del programa:
from numpy import array
Como estaremos usando frecuentemente muchas funciones de este módulo, conviene importarlas todas de una vez usando la siguiente sentencia:
from numpy import *
(Si no recuerda cómo usar el import, puede repasar la materia sobre módulos).
El tipo de datos de los arreglos se llama array. Para crear un arreglo nuevo, se puede usar la funciónarray pasándole como parámetro la lista de valores que deseamos agregar al arreglo:
>>> a = array([6, 1, 3, 9, 8])
>>> a
array([6, 1, 3, 9, 8])
Todos los elementos del arreglo tienen exactamente el mismo tipo. Para crear un arreglo de números reales, basta con que uno de los valores lo sea:
>>> b = array([6.0, 1, 3, 9, 8])
>>> b
array([ 6.,  1.,  3.,  9.,  8.])
Otra opción es convertir el arreglo a otro tipo usando el método astype:
>>> a
array([6, 1, 3, 9, 8])
>>> a.astype(float)
array([ 6.,  1.,  3.,  9.,  8.])
>>> a.astype(complex)
array([ 6.+0.j,  1.+0.j,  3.+0.j,  9.+0.j,  8.+0.j])
Hay muchas formas de arreglos que aparecen a menudo en la práctica, por lo que existen funciones especiales para crearlos:
  • zeros(n) crea un arreglo de n ceros;
  • ones(n) crea un arreglo de n unos;
  • arange(a, b, c) crea un arreglo de forma similar a la función range, con las diferencias que a,b y c pueden ser reales, y que el resultado es un arreglo y no una lista;
  • linspace(a, b, n) crea un arreglo de n valores equiespaciados entre a y b.
>>> zeros(6)
array([ 0.,  0.,  0.,  0.,  0.,  0.])

>>> ones(5)
array([ 1.,  1.,  1.,  1.,  1.])

>>> arange(3.0, 9.0)
array([ 3.,  4.,  5.,  6.,  7.,  8.])

>>> linspace(1, 2, 5)
array([ 1.  ,  1.25,  1.5 ,  1.75,  2.  ])

Operaciones con arreglos

Las limitaciones que tienen los arreglos respecto de las listas son compensadas por la cantidad de operaciones convenientes que permiten realizar sobre ellos.
Las operaciones aritméticas entre arreglos se aplican elemento a elemento:
>>> a = array([55, 21, 19, 11,  9])
>>> b = array([12, -9,  0, 22, -9])

# sumar los dos arreglos elemento a elemento
>>> a + b
array([67, 12, 19, 33,  0])

# multiplicar elemento a elemento
>>> a * b
array([ 660, -189,    0,  242,  -81])

# restar elemento a elemento
>>> a - b
array([ 43,  30,  19, -11,  18])
Las operaciones entre un arreglo y un valor simple funcionan aplicando la operación a todos los elementos del arreglo, usando el valor simple como operando todas las veces:
>>> a
array([55, 21, 19, 11,  9])

# multiplicar por 0.1 todos los elementos
>>> 0.1 * a
array([ 5.5,  2.1,  1.9,  1.1,  0.9])

# restar 9.0 a todos los elementos
>>> a - 9.0
array([ 46.,  12.,  10.,   2.,   0.])
Note que si quisiéramos hacer estas operaciones usando listas, necesitaríamos usar un ciclo para hacer las operaciones elemento a elemento.
Las operaciones relacionales también se aplican elemento a elemento, y retornan un arreglo de valores booleanos:
>>> a = array([5.1, 2.4, 3.8, 3.9])
>>> b = array([4.2, 8.7, 3.9, 0.3])
>>> c = array([5, 2, 4, 4]) + array([1, 4, -2, -1]) / 10.0

>>> a < b
array([False,  True,  True, False], dtype=bool)

>>> a == c
array([ True,  True,  True,  True], dtype=bool)
Para reducir el arreglo de booleanos a un único valor, se puede usar las funciones any y allanyretorna True si al menos uno de los elementos es verdadero, mientras que all retorna True sólo si todos lo son (en inglés, any signfica «alguno», y all significa «todos»):
>>> any(a < b)
True
>>> any(a == b)
False
>>> all(a == c)
True

Funciones sobre arreglos

NumPy provee muchas funciones matemáticas que también operan elemento a elemento. Por ejemplo, podemos obtener el seno de 9 valores equiespaciados entre 0 y π/2 con una sola llamada a la función sin:
>>> from numpy import linspace, pi, sin

>>> x = linspace(0, pi/2, 9)
>>> x
array([ 0.        ,  0.19634954,  0.39269908,
        0.58904862,  0.78539816,  0.9817477 ,
        1.17809725,  1.37444679,  1.57079633])

>>> sin(x)
array([ 0.        ,  0.19509032,  0.38268343,
        0.55557023,  0.70710678,  0.83146961,
        0.92387953,  0.98078528,  1.        ])
Como puede ver, los valores obtenidos crecen desde 0 hasta 1, que es justamente como se comporta la función seno en el intervalo [0, π/2].
Aquí también se hace evidente otra de las ventajas de los arreglos: al mostrarlos en la consola o al imprimirlos, los valores aparecen perfectamente alineados. Con las listas, esto no ocurre:
>>> list(sin(x))
[0.0, 0.19509032201612825, 0.38268343236508978, 0.5555702330
1960218, 0.70710678118654746, 0.83146961230254524, 0.9238795
3251128674, 0.98078528040323043, 1.0]

Arreglos aleatorios

El módulo NumPy contiene a su vez otros módulos que proveen funcionalidad adicional a los arreglos y funciones básicos.
El módulo numpy.random provee funciones para crear números aleatorios (es decir, generados al azar), de las cuales la más usada es la función random, que entrega un arreglo de números al azar distribuidos uniformemente entre 0 y 1:
>>> from numpy.random import random

>>> random(3)
array([ 0.53077263,  0.22039319,  0.81268786])
>>> random(3)
array([ 0.07405763,  0.04083838,  0.72962968])
>>> random(3)
array([ 0.51886706,  0.46220545,  0.95818726])

Obtener elementos de un arreglo

Cada elemento del arreglo tiene un índice, al igual que en las listas. El primer elemento tiene índice 0. Los elementos también pueden numerarse desde el final hasta el principio usando índices negativos. El último elemento tiene índice —1:
>>> a = array([6.2, -2.3, 3.4, 4.7, 9.8])

>>> a[0]
6.2
>>> a[1]
-2.3
>>> a[-2]
4.7
>>> a[3]
4.7
Una seccion del arreglo puede ser obtenida usando el operador de rebanado a[i:j]. Los índices i y jindican el rango de valores que serán entregados:
>>> a
array([ 6.2, -2.3,  3.4,  4.7,  9.8])
>>> a[1:4]
array([-2.3,  3.4,  4.7])
>>> a[2:-2]
array([ 3.4])
Si el primer índice es omitido, el rebanado comienza desde el principio del arreglo. Si el segundo índice es omitido, el rebanado termina al final del arreglo:
>>> a[:2]
array([ 6.2, -2.3])
>>> a[2:]
array([ 3.4,  4.7,  9.8])
Un tercer índice puede indicar cada cuántos elementos serán incluídos en el resultado:
>>> a = linspace(0, 1, 9)
>>> a
array([ 0.   ,  0.125,  0.25 ,  0.375,  0.5  ,  0.625,  0.75 ,  0.875,  1.   ])
>>> a[1:7:2]
array([ 0.125,  0.375,  0.625])
>>> a[::3]
array([ 0.   ,  0.375,  0.75 ])
>>> a[-2::-2]
array([ 0.875,  0.625,  0.375,  0.125])
>>> a[::-1]
array([ 1.   ,  0.875,  0.75 ,  0.625,  0.5  ,  0.375,  0.25 ,  0.125,  0.   ])
Una manera simple de recordar cómo funciona el rebanado es considerar que los índices no se refieren a los elementos, sino a los espacios entre los elementos:
materia/../diagramas/indices.png
>>> b = array([17.41, 2.19, 10.99, -2.29, 3.86, 11.10])
>>> b[2:5]
array([ 10.99,  -2.29,   3.86])
>>> b[:5]
array([ 17.41,   2.19,  10.99,  -2.29,   3.86])
>>> b[1:1]
array([], dtype=float64)
>>> b[1:5:2]
array([ 2.19, -2.29])

Algunos métodos convenientes

Los arreglos proveen algunos métodos útiles que conviene conocer.
Los métodos min y max, entregan respectivamente el mínimo y el máximo de los elementos del arreglo:
>>> a = array([4.1, 2.7, 8.4, pi, -2.5, 3, 5.2])
>>> a.min()
-2.5
>>> a.max()
8.4000000000000004
Los métodos argmin y argmax entregan respectivamente la posición del mínimo y del máximo:
>>> a.argmin()
4
>>> a.argmax()
2
Los métodos sum y prod entregan respectivamente la suma y el producto de los elementos:
>>> a.sum()
24.041592653589795
>>> a.prod()
-11393.086289208301

jueves, 22 de octubre de 2015

Definicion de Pilas y Colas


Definicion de Pilas


Una pila (stack en inglés) es una lista ordenada o estructura de datos en la que el modo de acceso a sus elementos es de tipo LIFO (del inglés Last In First Outúltimo en entrar, primero en salir) que permite almacenar y recuperar datos. Esta estructura se aplica en multitud de ocasiones en el área de informática debido a su simplicidad y ordenación implícita de la propia estructura.

Para el manejo de los datos se cuenta con dos operaciones básicas: apilar (push), que coloca un objeto en la pila, y su operación inversa, retirar (o desapilar, pop), que retira el último elemento apilado.

En cada momento sólo se tiene acceso a la parte superior de la pila, es decir, al último objeto apilado (denominado TOS, Top of Stack en inglés). La operación retirar permite la obtención de este elemento, que es retirado de la pila permitiendo el acceso al siguiente (apilado con anterioridad), que pasa a ser el nuevo TOS.




Definicion de Colas


Una cola es una colección de elementos homogéneos (almacenados en dicha estructura), en la misma se pueden insertar elementos por uno de los extremos, llamado frente, y retirar los mismos por el otro extremo, denominado final.

Es importante aclarar que, tanto el frente como el final de la cola, son los únicos indicados para retirar e insertar elementos, respectivamente. Esto nos indica que no podemos acceder directamente a cualquier elemento de la cola, sino solo al primero, o sea el que está o se encuentra en el frente, y no se pueden insertar elementos en cualquier posición sino solo por el final, así el elemento insertado queda como último.

Por esta razón la cola es denominada una estructura F.I.F.O., o simplemente una lista F.I.F.O., esto representa el acrónimo de las palabras inglesas “first in, first out” (primero en entrar, primero en salir).

Gráficamente podemos representarla como:


Torres de Hanoi

Las Torres de Hanói es un rompecabezas o juego matemático inventado en 1883 por el matemático francés Édouard Lucas.Este juego de mesa solitario se trata de un juego de ocho discos de radio creciente que se apilan insertándose en una de las tres estacas de un tablero. El objetivo del juego es crear la pila en otra de las estacas siguiendo ciertas reglas. El problema es muy conocido en la ciencia de la computación y aparece en muchos libros de texto como introducción a la teoría de algoritmos.

Algoritmo



Entrada: Tres pilas de números origenauxiliardestino, con la pila origen ordenada
Salida: La pila destino
  1. si origen \scriptstyle == \{1\} entonces
    1. mover el disco 1 de pila origen a la pila destino (insertarlo arriba de la pila destino)
    2. terminar
  2. si no
    1. hanoi(\scriptstyle \{1, \dots , n-1 \},origen,destinoauxiliar)     //mover todas las fichas menos la más grande (n) a la varilla auxiliar
  3. mover disco n a destino                //mover la ficha grande hasta la varilla final
  4. hanoi (auxiliarorigendestino)          //mover todas las fichas restantes, 1...n–1, encima de la ficha grande (n)
  5. terminar





Ejemplos de Manejo de Funciones


Ejemplos de Manejo de Funciones



A continuacion podran ver algunos ejemplos sobre el manejo de funciones y como funcionan las funciones en el lenguaje C.


/* Inclusión de archivos */
#include <stdio.h>

void holamundo(void) /* Función donde se ejecuta la lógica del programa */
{
  printf("Hola Mundo\n"); /* imprime la cadena */
 return; /* sale de la función */
}
 
int main(void) /* Función principal del programa */
{
 holamundo(); /* llamada a la función holamundo */
 return 0; /* sale del programa con código 0 (correcto) */
}


Este código es en todo equivalente al "Hola Mundo" original, sólo que nos muestra cómo escribir y cómo utilizar una función. Y además nos muestra un principio de buena programación: meter las sentencias que "hacen el trabajo" en otras funciones específicas para sacarlas de main(), dejando en ésta tan sólo un guión general de lo que hace el programa, no las órdenes específicas. De esta manera se facilita la comprensión del programa, y por tanto el futuro trabajo de modificarlo.


#include <stdio.h>

int main(void)
{
 int suma = sumar(5, 3); /* ERROR, sumar no ha sido declarada aún */
 printf("La suma es: %d ", suma);
 return 0;
}

int sumar(int numero1, int numero2)
{
 return numero1 + numero2;
}


En este caso el programa es erróneo y no compila, ya que en la línea donde se llama a la función sumar, el compilador aún no conoce ninguna función con ese nombre, y cuáles son sus argumentos y valor de retorno.

Una posible solución es declarar el prototipo de la función al principio, para informar al compilador que existe, y luego definir el cuerpo de la misma en cualquier lugar del programa:


#include <stdio.h>

/* Declaración */
int sumar(int numero1, int numero2);

int main(void)
{
 int suma = sumar(5, 3);
 printf("La suma es: %d ", suma);
 return 0;
}

/* Definición */
int sumar(int numero1, int numero2)
{
 return numero1 + numero2;
}


Y un ejemplo de Funcion Recursiva =).


#include <stdio.h>

void funcionA(char c); /* se declara el prototipo de la función para que el llamado */
void funcionB(char c); /* a la misma en la función no sea implícita */

int main(void)
{

 funcionA('z'); /* llamado a funcionA */

 return 0;
}

void funcionA(char c)
{
 if (c > 'a') /* caso base mientras c no sea menor que A */
  funcionB(c); /* llamado a la funcionB */

 printf("%c ", c); /* imprimimos el valor de c */
*la variable es un parametro no utilizado para este proceso
}

void funcionB(char c)
{
 funcionA(--c); /* llamado a la funcionA decrementando el valor de 'z' */
}