Beruflich Dokumente
Kultur Dokumente
Y
ESTRUCTURAS DE DATOS
EN
LENGUAJE C/C++
Humberto Mazuera Prraga
Segunda Parte
Tercera Parte
PRIMERA PARTE
PILAS Y COLAS EN ARREGLOS.
RECURSIN.
PUNTEROS.
PASO POR REFERENCIA.
CADENAS.
REFUERZO REGISTROS Y ARCHIVOS.
Algoritmos de Ordenamiento.
Primera Parte
Segunda Parte
Tercera Parte
Pila en Arreglo
Introduccin
Una pila, a un nivel lgico, es una estructura de datos lineal compuesta de
elementos del mismo tipo, en la cual cada uno de ellos solo puede ser insertado y
eliminado por su parte final. La posicin final la llamamos cima o tambin cabeza
de la pila; para darnos una mejor representacin (abstraccin) de ella su
representacin grfica en el papel la hacemos en forma vertical, con la cima en
la parte de arriba. De esta forma cuando aadamos un nuevo elemento solo podr
ser colocado en la parte superior, piense en una pila de platos de cocina o en
una pila de libros, los cuales coloque en orden uno encima de otro. Debido a esto
ltimo las pilas tambin son llamadas listas en las cuales "el ltimo elemento en
entrar es el primero en salir", en ingls el acrnimo LIFO(Last Input, First
Out).
La pila se considera un grupo ordenado de elementos porque estos estn
clasificados de acuerdo al tiempo en que estn residiendo en la pila, el elemento
que se elimina de la cabeza es siempre el que lleve menos tiempo en ella. En
resumen una pila es una lista en la cual los elementos solo pueden ser insertados
y eliminados por un extremo de ella, este extremo es llamado la cima. De esta
forma los elementos son eliminados en forma contraria a como fueron insertados.
Las operaciones bsicas de insertar y eliminar las llamaremos Meter() y
Sacar() respectivamente, y sern implementadas sobre la estructura de datos
arreglo unidimensional en el presente captulo.
Una Pila es una estructura de datos que almacena elementos de un tipo
determinado, que sigue la poltica de que el primer elemento que se extrae (se
desapila) es el ltimo que se introdujo (se apil) -primero en salir, ultimo
en entrar (LIFO)-.
//PILACHAR.CPP
<iostream.h>
<stdio.h>
<ctype.h>
<string.h>
do{
EscribirValoresEnPila();
cout << "\nPuede introducir en la Pila un mximo de "
<< MaxPila << " elementos\n";
cout << "Meter Sacar Terminar: digite M, S o T: ";
cin >> opcion;
switch (toupper(opcion)) {
case 'M' : meter(); break;
case 'S' : sacar(); break;
}
} while (opcion != 'T');
}
La siguiente es una prueba de ejecucin manual del programa PILACHAR.CPP anterior
y el cual maneja una pila de cadenas de caracteres:
Inicialmente se definen las siguientes constantes y variables:
const
const
const
char
int MaxPila = 5;
int LargoCadena = 10;
int PilaVaca = -1;
Pila[MaxPila][LargoCadena];
4
3
2
1
0
Cima=PilaVacia;
-1
Cali
4
3
Cima
2
1
0
Pila
Cali
Palmira
4
3
Cima
2
1
0
Pila
Palmira
Cali
Zarzl
4
3
Cima
2
1
0
queda
Pila
Zarzl
Palmira
Cali
Toro
4
3
Cima
Pila
Toro
2
1
0
Zarzl
Palmira
Cali
Jamund
4
3
Cima
2
1
0
Pila
Jamund
Toro
Zarzl
Palmira
Cali
Se invoca meter():
con este caso if (Cima==MaxPila-1)
es verdadero,
aparecer en pantalla: "Desbordamiento. Digite una tecla" y volver a la funcin
main() del programa.
Si invocamos a continuacin la funcin sacar():
void sacar(){
char item[LargoCadena];
if (Cima == PilaVacia)
cout << "\n\nSubdesbordamiento. digite una tecla";
else {
strcpy(item, Pila[Cima]);
cout << "Sacado de la pila: " << item;
Cima--;
}
}
Inicialmente intruccin if (Cima == PilaVaca) es falsa por esto seguir el
algoritmo en el else; en la variable item se asigna el valor que est en la Cima
de la Pila por medio de strcpy (item, Pila[Cima]) y a continuacin se decrementa
Cima en 1, quedando la pila as:
item
Jamund
Pila
3
Toro
Cima
2
Zarzl
1
Palmira
0
Cali
Toro
4
3
Cima
2
1
0
Pila
Zarzl
Palmira
Cali
Invocamos sacar():
item
Zarzal
4
3
Cima
2
1
0
Pila
Palmira
Cali
Invocamos sacar():
item
Palmira
Cima
de nuevo
item
Cali
Pila
0
Cali
invoquemos sacar():
4
3
Cima
-1
2
1
0
Pila
if (Cima == PilaVaca)
-1
-1
El if anterior
"subdesbordamiento.
continuacin.
<iostream.h>
<conio.h>
<iomanip.h>
<ctype.h>
<stdlib.h>
10
11
Una cola es una lnea de espera como las que se forman en las casillas de los
bancos o en las entradas a cine. Desde el punto de vista de las estructuras de
datos una cola es una estructura de lineal, en la cual sus elementos solo pueden
ser insertados por un extremo y eliminados por el otro. La palabra cola viene del
poder simular con esta estructura la situacin real de las colas que hay que
efectuar para entrar a algn lugar o para poder recibir algn servicio, por
ejemplo: bancos, espectculos pblicos, transportes colectivos, etc.
En general en una cola, de la vida diaria, el primero que llega ser
atendido primero, pasando a continuacin el segundo de la cola al frente; y cada
que llega un nuevo elemento este se colocar al final de la cola. De aqu que el
extremo por donde se insertan los elementos se llamar "final" y por donde se
retiran "frente". Debido a esto ltimo las colas tambien son llamadas listas en
las cuales el primer elemento en entrar es el primero en salir, en ingles
FIFO(First Input, First Out). Para las colas que trabajaremos se sobreentender,
a menos de decir lo contrario, que la regla es que siempre el primero se atiende
primero.
Una Cola es una estructura de datos la cual almacena elementos de un tipo
determinado, que sigue la poltica de que el primer elemento que se extrae (se
desencola) es el primero que se introdujo (se encol)
-primero en salir,
primero en entrar (FIFO)-.
Implementacin
frente
final
12
0
1
2
3
4
nulo
nulo
Cuando una cola est vaca el primer elemento que llegue, lgicamente que
llegar al frente, supongamos ese elemento es 15:
cola
15
0
1
2
3
4
frente
final
15 18
0
1
2
3
4
frente
final
Vemos que el final se ha movido hacia la derecha, el cdigo que podra hacer
esto, sera:
final++;
cout << "\n\nElemento a insertar: ";
cin >> cola[final];
Este ser el "caso general", empero hay varios casos particulares, los cuales
trataremos a continuacin. Supongamos que siguen llegando elementos a la cola,
as:
cola
15 18 -4
0
1
2
3
4
frente
final
cola
15 18 -4 0
0
1
2
3
4
frente
final
cola
15 18 -4 0 65
0
1
2
3
4
frente
final
13
18 -4 0 65
0
1
2
3
4
frente
final
-4 0 65
0
1
2
3
4
frente
final
0 65
0
1
2
3
4
frente
final
57
0 65
0
1
2
3
4
frente
final
0 final pasa de 4 a 0
14
65
57
57 14
0 65
0
1
2
3
4
frente
final
La cola para el usuario estara en este orden: 0, 65, 57, 14. Insertemos
ahora otro elemento, por ejemplo 81:
cola
57 14 81 0 65
0
1
2
3
4
frente
final
La cola para el usuario estara como: 0, 65, 57, 14, 81. Llegados a este
punto no podramos seguir insertando elementos, ya que esta la cola est llena.
Verifique nuestro algoritmo y se dar cuenta que fracasar, permitiendo insertar
otro y de esta forma borrando el valor que tenemos en el frente, por ello
recodificamos, teniendo en cuenta que si el final est una posicin menos que el
frente, la cola est, tambin llena:
if ( (final+1 == MaxCola && frente == 0) || (final+1 == frente) )
cout << "cola llena ";
else {
final++;
if (final == MaxCola) // se da "la vuelta al inicio"
final = 0;
cout << "\n\nElemento a insertar: ";
cin >> cola[final];
}
A continuacin insertmosle al anterior cdigo, el caso inicial, cuando la
cola estaba vaca y tendramos finalmente:
if ( (final+1 == MaxCola && frente == 0) || (final+1 == frente) )
cout << "cola llena ";
else
if (frente == nulo){ //la cola estaba vaca
frente = final = 0;
cout << "\n\nElemento a insertar: ";
15
57 14 81
0
1
2
3
4
frente
final
elementos
cola
14 81
0
1
2
3
4
frente
final
cola
81
0
1
2
3
4
frente
final
en
cola
nulo
nulo
0
1
2
3
4
Para esto se debe modificar nuevamente el cdigo para Atender:
16
17
final++;
if (final == MaxCola) // se da "la vuelta al inicio"
final = 0;
cout << "\n\nElemento a insertar: ";
cin >> cola[final];
}
}
void Atender(){
if (frente == nulo)
cout << "\nCola vacia\a";
else {
cout << "\nAtendido: " << cola[frente];
if (frente == final) // cola qued vaca
frente = final = nulo;
else{
frente++;
if (frente == MaxCola)
frente = 0;
}
}
}
void Listar(){
int i;
if (frente==nulo)
cout << "\nCola vacia \a\n";
else
if (frente <= final)
for (i=frente; i <= final; i++)
cout << setw(4) << cola[i];
else {
for (i=frente; i < MaxCola; i++)
cout << setw(4) << cola[i];
for (i=0; i <= final; i++)
cout << setw(4) << cola[i];
}
}
void main(){
char opcion;
do{
clrscr();
Listar();
cout << "\n\nInsertar Atender Salir \n";
switch (opcion=getch()){
case 'I':; case 'i': Insertar(); break;
case 'A':; case 'a': Atender(); break;
}
} while (opcion != 'S' && opcion != 's');
}
Estudie el siguiente programa, el cual tiene un pequeo cambio, en relacin al
anterior:
18
Cola de Registros:
#include
#include
#include
#include
<iostream.h>
<iomanip.h>
<conio.h>
<stdio.h>
<< "
"
19
<< Cola[frente].alto;
if (frente == final) // cola qued vaca
frente = final = nulo;
else {
frente++;
if (frente == MaxCola)
frente = 0;
}
}
getch();
}
void listar(){
int i;
clrscr();
if (frente==nulo)
cout << "Cola vacia \a\n";
else
if (frente <= final)
for (i = frente; i <= final; i++)
cout
<< "\n" << Cola[i].nombre << " "
<< Cola[i].edad
<< " "
<< Cola[i].alto;
else {
for (i=frente; i<MaxCola; i++)
cout << "\n" << Cola[i].nombre << " "
<< Cola[i].edad << " " << Cola[i].alto;
for (i=0; i <= final; i++)
cout << "\n" << Cola[i].nombre << " " << Cola[i].edad
<< " " << Cola[i].alto << endl;
}
}
void main(){
char opcion;
do {
listar(); cout << "\n\nInsertar Atender
opcion = getch();
switch (opcion){
case 'I':;
case 'i': Insertar(); break;
case 'A':;
case 'a': Atender(); break;
}
} while (opcion != 'S' && opcion != 's');
Salir ";
20
VECTOR CIMAS
0
1
2
3
VECTOR NOMBRES
nombre_1
nombre_2
nombre_3
nombre_4
0
1
2
3
21
-1
-1
recuerde que Vacia=-1
0
1
2
22
23
RECURSIN
1. INTRODUCCIN
La recursin consiste en la invocacin de una funcin a si misma, es decir que en
el mbito de ella se efecta una llamada con el mismo identificador con el que
est definida.
En cada invocacin de una funcin, el compilador le asigna una direccin base
de memoria a partir de la cual "trabajar" esta funcin, por esto en cada nueva
invocacin recursiva, el compilador asignar nuevas direcciones de memoria, de
esta forma y eventualmente la memoria podra llegar a llenarse. En cada
invocacin se haran copias de los parmetros que se estn pasando y de las
variables locales en ella definidas.
Para evitar el llenar la memoria del computador, toda funcin recursiva debe
estar construida de tal suerte que bajo alguna condicin no se siga invocando
ms, esto es lo que se conoce como el criterio base de la funcin recursiva.
Explicaremos el mecanismo de invocaciones
clculo del factorial de un nmero.
recursivas
con
el
ejemplo
del
.... * N
Factorial(N) = N * Factorial(N-1)
Veamos el siguiente ejemplo:
Fac(5) = 5 * Fac(5-1) = 5 * Fac(4)
Fac(4) = 4 * Fac(4-1) = 4 * Fac(3)
Fac(3) = 3 * Fac(3-1) = 3 * Fac(2)
Fac(2) = 2 * Fac(2-1) = 2 * Fac(1)
Fac(1) = 1 * Fac(1-1) = 1 * Fac(0)
Fac(0) = 1
sabemos que factorial de cero es igual a uno, tomaremos este hecho como el
"criterio base" y a partir de aqu nos "devolvemos" reemplazando en las
expresiones anteriormente obtenidas, hasta llegar al resultado deseado:
Fac(1) = 1 * Fac(0) = 1 * 1 = 1
Fac(2) = 2 * Fac(1) = 2 * 1 = 2
Fac(3) = 3 * Fac(2) = 3 * 2 = 6
Fac(4) = 4 * Fac(3) = 4 * 6 = 24
Fac(5) = 5 * Fac(4) = 5 * 24 = 120
A partir de esto codificaremos la siguiente funcin recursiva:
float factorial(int n){
float fac;
if (n == 0)
return (1);
24
fac = n * factorial(n-1);
return(fac);
}
Supongamos que al efectuar su invocacin inicial, ver el programa
RECURSI.CPP siguiente, se le est pasando por valor el entero 5: el compilador le
asignar a la funcin un "espacio" en la memoria para realizar su trabajo,
representemos ese espacio como un rectngulo y de esta forma tener una mejor
abstraccin de lo que ocurre, as:
factorial(5)
Con el valor de n=3 se produce una segunda invocacin recursiva, tercera para
la funcin, en memoria se gestionar un nuevo "espacio" as:
factorial(3)
25
factorial(2)
INVOCADA
26
1
fac
fac = n * factorial(n-1);
= 1 * factorial(1-1);
= 1 * factorial(0);
el 1 retornado "llega" a factorial(0)
y de este modo se sigue:
fac = 1 * factorial(0) = 1*1 = 1
continuando en return(fac)
return(2) y termina esta invocacin
2
fac
fac = n * factorial(n-1);
= 2 * factorial(2-1);
= 2 * factorial(1);
el 1 retornado "llega" a factorial(1)
y de este modo se sigue:
fac = 2 * factorial(1) = 2*1 = 2
continuando en return(fac)
return(2) y termina esta invocacin
3
fac
fac = n * factorial(n-1);
= 3 * factorial(3-1);
= 3 * factorial(2);
el 2 retornado "llega" a factorial(2)
y de este modo se sigue:
fac = 3 * factorial(2) = 3*2 = 6
continuando en return(fac)
return(6) y termina esta invocacin
fac = n * factorial(n-1);
27
4
fac
24
= 4 * factorial(4-1);
= 4 * factorial(3);
el 6 retornado "llega" a factorial(3)
y de este modo se sigue:
fac = 4 * factorial(3) = 4*6 = 24
continuando en return(fac)
return(24) y termina esta invocacin
5
fac
120
fac = n * factorial(n-1);
= 5 * factorial(5-1);
= 5 * factorial(4);
el 24 retornado "llega" a factorial(4)
y de este modo se sigue:
fac = 5 * factorial(4) = 5*24 =120
continuando en return(fac)
return(120) y termina esta invocacin
28
29
(a+b)_ =
#include <iostream.h>
#include <conio.h>
//RTPASCAL.CPP
float factorial(int);
main(){
int N=10, n, i, coeficiente, espacio;
clrscr();
cout << "\t\tTRIANGULO DE PASCAL DE COEFICIENTES BINOMIALES\n\n";
for(n = 0; n <= N; n++) {
for(espacio=1; espacio <= (80/2-6)-n*3; espacio++)
cout << " ";
for(i = 0; i <= n; i++){
coeficiente = factorial(n)/(factorial(i)*factorial(n-i));
cout.width(6); cout << coeficiente;
}
cout << endl;
}
getch();
}
float factorial(int n){
float f;
if ((n == 1) || (n == 0))
return(1);
f = n * factorial(n-1);
return(f);
}
Tabla: Tringulo de Pascal de coeficientes binomiales.
1
1
1
1
1
1
3
6
10
1
4
10
1
15
20
15
6
1
1
7
21
35
35
21
7
1
1
8
28
56
70
56
28
8
9
36
84
126
126
84
36
9
10
45
120
210
252
210
120
45
1
3
4
1
2
1
1
10
30
}
Veamos una prueba para el anterior algoritmo:
Multiplicar(2,4)= Multiplicar(2,4-1)+ 2 = Multiplicar(2,3) + 2
Multiplicar(2,3)= Multiplicar(2,3-1)+ 2 = Multiplicar(2,2) + 2
Multiplicar(2,2)= Multiplicar(2,2-1)+ 2 = Multiplicar(2,1) + 2
Multiplicar(2,1) = 2
Multiplicar(2,2)= Multiplicar(2,1) + 2 = 2 + 2 = 4
Multiplicar(2,3)= Multiplicar(2,2) + 2 = 4 + 2 = 6
Multiplicar(2,4)= Multiplicar(2,3) + 2 = 6 + 2 = 8
6. Eleve el nmero 10 a diferentes potencias utilizando una funcin recursiva.
//RECURS_3.CPP
#include <IOSTREAM.H>
#include <CONIO.H>
float potencia (int, int);
main(){
int x = 10;
int y = 0;
clrscr();
do{
cout << "\n10 elevado a la " << y << " = " << potencia(x, y);
y++;
}while ( y<11 );
}
float potencia (int base, int exponente){
if ( exponente < 0 )
return(-1);
else
if (exponente == 0)
return(1); /* criterio base */
else
return (base * potencia (base, exponente-1));
}
31
void main(){
int dec;
clrscr();
cout << "Digite un entero: ";
cin >> dec;
cout << "\nEn binario es = ";
DecimalABinario(dec);
}
8. Presenta las tablas de multiplicar desde un valor t1 a uno t2. Utilizando
recursin. Efecte prueba de ejecucin manual. Explique en palabras lo que hace;
muestre lo ms grficamente que pueda cada una de las invocaciones recursivas;
mencione los criterios base para cada una de las funciones, escriba como se
"devuelven" las invocaciones recursivas; de los correspondientes valores a las
variables en cada invocacin.
#include <conio.h>
#include <dos.h>
#include <iostream.h>
//R_TABLAM.CPP
void Tabla(int a, int b){
if(b>1)
Tabla(a, b-1);
cout << a << " x " << b << " = " << a*b << endl;
}
void Tablas(int del, int al){
if(del < al)
Tablas(del, al-1);
clrscr();
Tabla(al,10);
delay(500);
}
void main(){
int t1,t2;
clrscr();
cout << "Nmero de la tabla inicial: ";
32
t2
del
al
33
55
10
89
11
//RFIBONAC.CPP
#include <iostream.h>
#include <conio.h>
int fibonacci(int n){
if (n <= 1)
return (n);
return(fibonacci(n-2) + fibonacci(n-1));
}
main(){
int N=11;
clrscr();
cout <<"El " <<N <<" trmino de la serie de Fibonacci es " << fibonacci(N);
getch(); return 0;
}
si n = 1
si n > 1
RLOG2_N.CPP
#include <iostream.h>
#include <conio.h>
int Log2(int n){
if (n < 1)
return -1;
if (n == 1)
return 0;
return ( 1 + Log2(n/2) ) ;
}
void main(){
int N, L;
clrscr(); cout << "Digite un Entero: ";
cin >> N;
L = Log2(N);
if ( L<0 )
cout << "Error \a";
else
cout << "Parte entera del Logaritmo en base 2 de " << N << " = " << L;
}
34
11. Implementacin del Algoritmo de Euclides para el clculo del Mximo Comn
Divisor:
Sean A y B enteros no negativos. Suponga que una funcin MCD se define
recursivamente como sigue:
MCD(A,B) = MCD(B,A)
MCD(A,B) = A
MCD(A,B) = MCD(B, A % B)
si A < B
si B = 0
de otro modo
#include <iostream.h>
#include <conio.h>
//REUCLIDES.CPP
int MCD(int A, int B){
if (A<B)
return(MCD(B,A));
else
if (!B)
return A;
else
return(MCD(B, A%B));
}
void main(){
int a = 13, b = 130;
clrscr();
cout << "Mximo Comn Divisor de " << a << " y " << b << " es " << MCD(a,b);
getch();
}
35
36
}
cout << "\n\nDigite nmero a buscar en el vector: "; cin >> item;
i = BusquedaBinaria(Min, Max-1);
if ( (i>=Min) && (i<Max) )
cout << "\n\n" << v[i] << " est en la posicin " << i;
else
cout << "\n\n" << item << " no se encuentra";
}
16. TORRES DE HANOI: El objeto de este juego es mover de un poste inicial N
discos de diferente tamao, colocados de mayor a menor tamao uno encima de otro,
hasta un poste final y utilizando un poste auxiliar. Solo se puede mover un disco
cada vez, de poste a poste. Nunca puede haber un disco mayor sobre un disco
menor.
//TORHANOI.CPP
#include <iostream.h>
#include <conio.h>
void torres(int N, int inicio, int aux, int final);
void main(){
int anillos=0;
const int poste1=1, poste2=2, poste3=3;
clrscr();
cout << "Nmero de anillos con que quiere jugar: ";
torres(anillos, poste1, poste2, poste3);
}
void torres(int N, int inicio, int aux, int final){
if (N == 1)
cout << "Mover torre " << inicio << " a torre " << final << endl;
else{
torres(N-1,inicio,final, aux);//N-1 discos del poste inicial al auxiliar
cout << "Mover torre " << inicio << " a torre " << final << endl;
torres(N-1, aux, inicio, final);//N-1 discos del poste auxiliar al final
}
}
Para 3 anillos:
Mover
Mover
Mover
Mover
Mover
Mover
Mover
Torre
Torre
Torre
Torre
Torre
Torre
Torre
Para 4 anillos:
1
1
3
1
2
2
1
a
a
a
a
a
a
a
Torre
Torre
Torre
Torre
Torre
Torre
Torre
3
2
2
3
1
3
3
37
38
Quicksort
de
izqder 0
1
2
3
4
5
6
7
8
9 10 11 12 PosPivPivote
0 12 43 2 90 50 87100-10 68 13 7 21 45 50 0
43
Pivote
<
En este caso la posicon ms a la izquierda es 0, la ms a la derecha es 12,
se escoge como "pivote" el primer trmino de la lista, es decir la posicin ms a
la izquierda, tal como est escrito en la tabla anterior.
Se procede a comparar el pivote, 43, con el valor ms a la derecha, posicin
12 cuyo valor es 50. Se verifica que 43 y 50 estn en posiciones relativas,
ascendentemente, adecuadas, por esto comenzamos a movernos a la izquierda,
decrementando der, as:
izqder 0
1
2
3
4
5
6
7
8
9 10 11 12 PosPivPivote
0 11 43 2 90 50 87100-10 68 13 7 21 45 50 0
43
Pivote
<
Se compara ahora el pivote 43, en posicin cero, con el nmero en posicin
der=11, es decir 45, nuevamente estan en posiciones relativas adecuadas a nuestro
ordenamiento ascendente, por esto se decrementa derecha (Der--):
izqder 0
1
2
3
4
5
6
7
8
9 10 11 12 PosPivPivote
0 10 43 2 90 50 87100-10 68 13 7 21 45 50 0
43
Pivote
<
Se compara ahora 43 con 21 de la posicin der=10, no estn en posiciones
relativas ordenadas, se proceder entonces a su intercambio, quedando el vector,
paso a paso as:
izqder 0
1
2
3
4
5
6
7
8
9 10 11 12 PosPivPivote
0 10 21 2 90 50 87100-10 68 13 7 21 45 50 0
43
21 2 90 50 87100-10 68 13 7 43 45 50 10
39
>
Pivote
izqder 0
1
2
3
4
5
6
7
8
9 10 11 12 PosPivPivote
1 10 21 2 90 50 87100-10 68 13 7 43 45 50 10 43
>
Pivote
por esto se incrementa izquierda y se compara el 43 con el 2, igualmente estn
en orden ascendente relativo; se incrementa izquierda nuevamente llegando a donde
est el nmero 90 en la posicin 2 del vector:
izqder 0
1
2
3
4
5
6
7
8
9 10 11 12 PosPivPivote
2 10 21 2 90 50 87100-10 68 13 7 43 45 50 10 43
>
Pivote
El 90 al compararlo con el pivote 43 es mayor,
intercambiados, y actualizada la posicin del pivote:
por
esto
debern
ser
izqder 0
1
2
3
4
5
6
7
8
9 10 11 12 PosPivPivote
2 10 21 2 90 50 87100-10 68 13 7 90 45 50 10 43
21 2 43 50 87100-10 68 13 7 90 45 50
2
Pivote
<
Siguiendo este proceso se obtiene la siguiente secuencia de posiciones:
izqder 0
1
2
3
4
5
6
7
8
9 10 11 12 PosPivPivote
2 9 21 2 43 50 87100-10 68 13 7 90 45 50 2
43
Pivote
<
izqder 0
1
2
3
4
5
6
7
8
9 10 11 12 PosPivPivote
2 9 21 2 7 50 87100-10 68 13 7 90 45 50
2 43
21 2 7 50 87100-10 68 13 43 90 45 50
9
>
Pivote
40
izqder 0
1
2
3
4
5
6
7
8
9 10 11 12 PosPivPivote
3 9 21 2 7 50 87100-10 68 13 43 90 45 50
9 43
>
Pivote
izqder 0
1
2
3
4
5
6
7
8
9 10 11 12 PosPivPivote
3 9 21 2 7 50 87100-10 68 13 50 90 45 50
9 43
21 2 7 43 87100-10 68 13 50 90 45 50
3
Pivote
<
izqder 0
1
2
3
4
5
6
7
8
9 10 11 12 PosPivPivote
3 8 21 2 7 43 87100-10 68 13 50 90 45 50
3 43
Pivote
<
izqder 0
1
2
3
4
5
6
7
8
9 10 11 12 PosPivPivote
3 8 21 2 7 13 87100-10 68 13 50 90 45 50
3 43
21 2 7 13 87100-10 68 43 50 90 45 50
8
>
Pivote
izqder 0
1
2
3
4
5
6
7
8
9 10 11 12 PosPivPivote
4 8 21 2 7 13 87100-10 68 43 50 90 45 50
8 43
>
Pivote
izqder 0
1
2
3
4
5
6
7
8
9 10 11 12 PosPivPivote
4 8 21 2 7 13 87100-10 68 87 50 90 45 50
8 43
21 2 7 13 43100-10 68 87 50 90 45 50
4 43
Pivote
<
izqder 0
1
2
3
4
5
6
7
8
9 10 11 12 PosPivPivote
4 7 21 2 7 13 43100-10 68 87 50 90 45 50
4 43
Pivote
<
41
izqder 0
1
2
3
4
5
6
7
8
9 10 11 12 PosPivPivote
4 6 21 2 7 13 43100-10 68 87 50 90 45 50
4 43
Pivote <
izqder 0
1
2
3
4
5
6
7
8
9 10 11 12 PosPivPivote
4 6 21 2 7 13-10100-10 68 87 50 90 45 50
4 43
21 2 7 13-10100 43 68 87 50 90 45 50
6
> Pivote
izqder 0
1
2
3
4
5
6
7
8
9 10 11 12 PosPivPivote
5 6 21 2 7 13-10100 43 68 87 50 90 45 50
6 43
>Pivote
izqder 0
1
2
3
4
5
6
7
8
9 10 11 12 PosPivPivote
5 6 21 2 7 13-10100100 68 87 50 90 45 50
6 43
21 2 7 13-10 43100 68 87 50 90 45 50
5
Pivote<
Al avanzar desde la derecha hacia la izquierda, la variable der se encuentra
con la posicin donde est el pivote, e izq ya estaba en el mismo valor, es decir
las tres variables "se encuentran en el mismo sitio", asi:
izqder 0
1
2
3
4
5
6
7
8
9 10 11 12 PosPivPivote
5 5 21 2 7 13-10 43100 68 87 50 90 45 50
5 43
Pivote
Se observa que el valor del pivote, 43, est en el sitio que le corresponde
en ordenamiento ascendente, y que a su izquierda se forma una sublista,
desordenada, desde la posicin 0 a la 4, con todos sus elementos menores; y una
sublista a la derecha, desde la posicin 6 hasta la 12, en desorden y con todos
mayores que el pivote. A partir de este punto se procede con el mismo
procedimiento sequido para la lista completa, en cada una de las sublistas y por
separado. El correspondiente programa, QUICKPIL.CPP, se presenta a continuacin:
2. Ejemplo de aplicacin de la estructura pila en el ordenamiento por el
algoritmo del QuickSort. El profesor explicar en clase magistral las reglas de
juego del algoritmo, usted deber efectuar prueba de ejecucin manual y entender
su abstraccin.
//QUICKPIL.CPP
#include <iostream.h>
42
#include <iomanip.h>
# include <stdlib.h>
#include <conio.h>
#include <values.h>
const int N=100;
int QuickSort(int *a, int izq, int der){
int PosPiv=izq, pivote=a[PosPiv];
do {
while ((pivote <= a[der]) && (PosPiv != der))
der --;
if (PosPiv != der) {
if (pivote > a[der]) {
a[PosPiv] = a[der];
a[der] = pivote;
}
PosPiv = der;
while ((a[izq] <= pivote) && (izq != PosPiv))
izq++;
if (PosPiv != izq){
if (a[izq] > pivote){
a[PosPiv] = a[izq];
a[izq] = pivote;
}
PosPiv = izq;
}
}
} while ( (PosPiv != der) || (PosPiv != izq) );
return(PosPiv);
}
void Ordenar(int *arreglo){ /* Clasificacin rpida */
int cima = -1, com, fin, PosPiv, menor[N], mayor[N];
cima++;
menor[cima] = 0;
mayor[cima] = N-1;
while (cima > -1) {
com = menor[cima];
fin = mayor[cima];
cima--;
PosPiv = QuickSort(arreglo, com, fin);
if ( com < PosPiv - 1) {
cima++;
menor[cima] = com;
mayor[cima] = PosPiv - 1;
}
if (PosPiv + 1 < fin){
cima++;
menor[cima] = PosPiv + 1;
mayor[cima] = fin;
}
43
}
}
void main(){
int i;
int vector[N];
clrscr();
cout << N << " Nmeros generados al azar:\n";
randomize();
for (i = 0; i < N; i++) {
vector[i] = random(MAXINT);
cout << setw(8) << vector[i];
}
Ordenar(vector);
cout << "\n\nOrdenados son:\n";
for (i = 0; i < N; i++)
cout << setw(8) << vector[i];
}
44
45
de
caracteres(matriz),
con
el
#include <iostream.h>
#include <conio.h>
#include <string.h>
//RQUICKCAD.CPP
const int N=5;
const int LargoCadena=20;
char Cadena[N][LargoCadena]; //Variable global
void QuickSort(int izq, int der) /* Funcin recursiva QuickSort */
{
register int i=izq, d=der;
char mitad[LargoCadena], aux[LargoCadena];
strcpy(mitad, Cadena[(izq+der)/2]);
do{
while (strcmp(Cadena[i], mitad) < 0)
i++;
while (strcmp(mitad, Cadena[d]) < 0)
d--;
if(i <= d) {
strcpy(aux, Cadena[i]);
strcpy(Cadena[i], Cadena[d]);
strcpy(Cadena[d], aux);
i++;
d--;
}
} while(i <= d);
if(izq < d)
QuickSort(izq, d);
if(i < der)
QuickSort(i, der);
}
void main(){
int i=0;
clrscr();
cout << "Digite " << N << " palabras\n";
while (i < N)
cin >> Cadena[i++];
QuickSort(0, N-1);
cout << "\n\tLas palabras ordenadas son:\n\n";
for (i = 0; i < N; i++)
cout << Cadena[i] << endl;
}
46
PUNTEROS O APUNTADORES
1. INTRODUCCIN
Los punteros son variables las cuales guardan direcciones de memoria RAM.
memoria un puntero ocupa 2 bytes. La direccin de memoria RAM la cual almacena
puntero(p) corresponder a la direccin base de otra variable(var) que est
memoria, decimos entonces que el puntero "apunta" a esta variable, de
siguiente forma:
P
1000
VAR
1000
En
un
en
la
2. PUNTERO A ENTERO
El siguiente es un ejemplo con un puntero que apuntar a un entero(recuerde
que un entero ocupa 2 bytes en memoria):
int *p, entero=13;
p
entero
1 3
1500 1501
47
1500
entero
1 3
1500 1501
1500
entero
2 1
1500 1501
real
4.67
48
pf = ℜ
se lee esta instruccin as: "la direccin(&) de la variable real se asigna a
la variable puntero pf"; en memoria nos no imaginaremos as:
pf
2500
real
4.67
Para mostrar el valor de la variable real por medio puntero pf, escribiremos
la siguiente instruccin:
cout << *pf;
Mostrar el valor de 4.67 en pantalla; *pf debe ser ledo como: "el valor al
cual apunta pf", y para saber cual es el valor al cual apunta pf, debemos "saber"
la direccin que tiene almacenada pf y a qu tipo de datos apunta, en este caso p
sabemos ha sido definido como un puntero a un float.
A travs del puntero podemos modificar el valor de la variable a la cual est
apuntando:
*pf = -23.56;
se leer "al valor al que apunta pf se le asigna -23.56", otra vez, para
saber cual es el valor al que apunta pf, debemos conocer la direccin que
almacena, de esta forma en memoria las variables quedarn as:
pf
2500
real
-23.56
4. PUNTERO A UN VECTOR
Supongamos tenemos la siguiente declaracin de variables:
int *pv, vector[5] = {17,2,-6,3,28};
la cual corresponde a la siguiente abstraccin:
vector
pv
0
1
2
3
4
<---ndices
17
2
-6
28
direcciones---> 500 501 502 503 504 505 506 507 508 509
Para hacer que el puntero, pv, tome la direccin base del vector se debe
49
500
17
2
-6
28
direcciones---> 500 501 502 503 504 505 506 507 508 509
Los arreglos tienen gran relacin con los punteros y deben ser vistos como
punteros a los cuales no se les puede cambiar la direccin(la direccin base que
almacenan) es decir como punteros constantes. En este caso la variable vector
tiene una direccin base de 500 y un desplazamiento de 2bytes*5=10 bytes, desde
la direccin 500 hasta 509. El anterior arreglo, vector, se puede recorrer con el
puntero, segn el siguiente fragmento:
for(i=0; i<5; i++)
cout << setw(4) << pv[i];
que nos mostrar en pantalla los valores: 17
2 -6
3 28. Es decir que
el puntero, pv, se puede indexar de igual forma que se hace con los
identificadores de los arreglos. Al ejecutar el fragmento anterior el valor en
memoria de pv es de 500, es decir apunta todo el tiempo a la direccin base, el
ndice es el que "avanza" en el arreglo.
Diferente ser si queremos avanzar en el vector, cambiando la direccin del
puntero, es decir que de 500 pase a 502, 504, 506, 508 las cuales son las
posiciones base de cada uno de los elementos enteros del vector: vector[0],
vector[1], vector[2], vector[3] y vector[4], esto se codificar as:
pv = vector;
while (*pv && i<5){
cout << setw(4) << *pv;
pv++;
i++;
}
En pantalla el efecto sera idntico que en el caso anterior, aparecern: 17
2 -6 3 28. En memoria sera muy diferente, la variable pv cada que se le "suma
uno" se incrementar segn el tipo de datos al que apunta, al ser un entero se
desplazar en dos bytes, para entenderlo, veamos prueba de ejecucin manual del
anterior fragmento en el siguiente tabulado:
pv
*pv while(*pv) cout<<setw(4)<<*pv
pv++
500 17
verdad
17
502
502 2
verdad
2
504
504 -6
verdad
-6
506
506 3
verdad
3
508
508 28
verdad
28
510
510 ???
???
La abstraccin de lo que ocurre en memoria, despus de esto, quedara as:
vector
50
pv
0
1
2
3
4
<---ndices
510
17
2
-6
28 ???
direcciones-> 500 501 502 503 504 505 506 507 508 509 510
El puntero pv apuntara a un valor de "basura", mostrado como ???, y por esto
mostrara, eventualmente, en pantalla, algo inesperado, si no se coloca la
instruccin i<5 para que termine.
5. Esta es una demostracin del manejo de un puntero a un nmero real.
#include <iostream.h>
#include <conio.h>
//PUNTERO1.CPP
void main(){
float N=5, *p;
clrscr();
cout << "N = " << N;
p = &N;
cout << "\nA la variable p se le asign el valor: " << p;
cout << "\nN = " << *p;
cout << "\nDigite un valor para la variable N: ";
cin >> *p;
cout << "\nN = " << N;
cout <<"\n\nVariable N est en la direccin de memoria: " <<p;
cout <<"\n\nVariable N est en la direccin de memoria: "<<&N;
cout <<"\n\nPuntero p est en la direccin de memoria: " <<&p;
}
6. Esta es una demostracin del manejo de los punteros.
#include <iostream.h>
#include <conio.h>
#include <stdio.h>
//PUNTERO2.CPP
main(){
int *pE, i, j,
entero=234,
vectorE[] = {3,45,23,67,9},
matrizE[][3] = {4, 7, 8,
9, 2, 0,
6, 2, 9};
char *pC = "Esta es una demostracin\n\n",
caracter
= '',
Cadena[] = {'C','a','l','i','\0'},
*Cad[] = {'\0'},
*Cadenas[] = {"Palmira ", "Valle
","Colombia" };
float *pR,
real = 7.5,
vectorR[] = {3.2, 4.5, -5.7, 0, 0.2},
matrizR[][3] = {4.3, 6.5, 7.8,
51
VALOR
DIRECCION\n\n";
pR = vectorR;
for (i=0; i<5; i++) {
cout <<"\nvectorR[" << i << "]\t" << *pR << "\t" << pR;
pR++;
}
cout << "\n";
pR = (float *) matrizR;
for (i=0; i<3; i++)
for (j=0; j<3; j++){
cout <<"\nmatrizR[" <<i <<"][" <<j <<"]\t" <<*pR <<"\t"<<pR;
pR++;
}
getch();
clrscr();
cout <<"VARIABLE
VALOR
DIRECCION\n\n";
pC = &caracter;
cout <<"caracter\t"<<*pC<<"\t"<<pC<<"\n\n";//No d la direccin
cout <<"Cadena
*Cad = Cadena;
cout <<"*Cad\t"<< *Cad<< "\t"<<Cad<<"\n\n";//No d la direccin
pC = Cadena;
i=0;
while (*pC) {
cout<<"\nCadena["<<i<<"]\t"<<*pC <<"\t"<<pC;//No d direccin
pC++;
52
i++;
}
cout <<"\n";
for (i=0; i<3; i++)
cout<<"\n*Cadenas["<<i<<"]\t"<<Cadenas[i]<<"\t"<<&Cadenas[i];
getch();
return 0;
}
7. Invierte una cadena de caracteres.
#include <iostream.h>
#include <stdio.h>
//RCADINVE.CPP
void invierte(char *C){
if (*C) {
invierte(++C);
putchar(*(--C));
}
}
void main(){
char cadena[10];
clrscr();
cout << "Digite cadena: ";
gets(cadena);
cout << "\n
";
invierte(cadena);
getch(); return;
}
Prueba de ejecucin manual se efecta a continuacin: en la funcin principal de
pide se digite una cadena, supongamos la palabra CALI, recuerde que es colocado,
por la instruccin de lectura gets, un terminador nulo '\0' despus del ltimo
caracter vlido, imaginemos la situacin as:
Pantalla
CADENA (en RAM)
0 1 2 3 4 5 6 7 8 9
Digite cadena: CALI
C A L I \0
1000
53
1000
1001
Invierte(1001)
1001
1000
1001
1001
1002
Invierte(1002)
1002
1000
1001
1002
1003
1001
1002
1003
Invierte(1004)
1000
1001
1002
1003
1004
1001
1002
1003
1004
1003
1004
1003
1001
1002
1003
1000
1001
1001
1002
1002
1003
54
IL
1000
1001
1001
1002
Invierte(1002)
1002
1003
1002
ILA
1000
1001
Invierte(1001)
1001
1002
1001
ILAC
Invierte(1000)
1000
1001
1000
la
que
fu
llamada
55
return (0);
}
void main(){
char palabra[30];
cout << "Digite Una cadena: ";
gets(palabra);
cout << "Longitud: " << Longitud(palabra);
}
9. El siguiente es un ejemplo en el cual un puntero "apunta" a un
registro(struct). Ver el siguiente captulo para la definicin de este tipo de
datos estructurado.
//PUNTERO3.CPP
#include <iostream.h>
#include <stdio.h>
typedef struct persona PERSONA;
struct persona{
char nombre[20];
int edad;
float alto;
}
void main(){
PERSONA amigo, *p;
p = &amigo;
cout << "Nombre: "; gets(p->nombre);
cout << "Edad: "; cin >> p->edad;
cout << "Altura: "; cin >> p->alto;
cout << p->nombre << " " << p->edad << " " << p->alto;
}
10. El siguiente algoritmo presenta el intercambio del valor de dos variables en
la memoria RAM del computador, por medio de una invocacin de una funcin por
referencia al estilo del C.
//FUNCION8.CPP
#include <iostream.h>
#include <conio.h>
IntercambioEnMemoria(int *a, int *b){
int *aux;
//variable local
*aux= *a;
*a
= *b;
*b
= *aux;
}
main(){
int a,b;
clrscr();
cout << "Digite un real para almacenar en variable A: ";
cout << "Digite un real para almacenar en variable B: ";
cin >> a;
cin >> b;
56
IntercambioEnMemoria(&a, &b);
cout <<"\nDespus de intercambiadas, A ahora es igual a "<<a;
cout << "\ny la variable B ahora es igual a " << b;
}
57
58
59
14.
#include <iostream.h>
#include <conio.h>
int leer(){
int N;
clrscr();
cout << "Digite un entero para convertirlo a binario: ";
cin >> N;
return (N);
}
void CalcularBinario(int N, int *r){
int c;
c = N >> 1;
*r = N % 2;
while(c){
r++;
*r = c % 2;
c >>= 1;
}
r++;
*r = 2; //se utiliza el dos como terminador
}
void main(){
int b=0, j, decimal, binario[20];
decimal = leer();
CalcularBinario(decimal, binario);
cout << "\n\nbinario = " ;
while(binario[b]==1 || binario[b]==0)
b++;
for(j=b-1; j>=0; j--)
cout << binario[j];
60
<< X;
}
Inicialmente, en la funcin main del programa anterior, se pide ser digitados
los valores de las variables X y Y, supongamos, que despus de esto, la memoria
RAM se encuentra as:
RAM
main()
X
Y
13.1
7.4
61
1000
1002
main()
IntercambioEnMemoria()
X
Y
a
b
aux
13.1
7.4 1000 1002
1000
1002
main()
IntercambioEnMemoria()
X
Y
a
b
aux
13.1
7.4 1000 1002 13.1
1000
1002
Contina:
*a = *b;
la cual debe ser leda como: "a la direccin a la que apunta la variable a
se le asigna el valor al que apunta la variable b", es decir que la direccin
1000 de la variable X tomar el valor de la direccin 1002 que es 7.4, veamos:
RAM
main()
IntercambioEnMemoria()
X
Y
a
b
aux
7.4
7.4 1000 1002 13.1
1000
1002
Finalmente, la instruccin:
*b = aux;
62
main()
IntercambioEnMemoria()
X
Y
a
b
aux
7.4
13.1 1000 1002 13.1
1000
1002
X
Y
7.4
13.1
1000
1002
Y por lo tanto, estos son los valores para cada una de las variables, X y Y,
que mostrar en pantalla.
1.2 Convierte un decimal a binario. Se presenta ejemplo de paso de parmetro por
referencia.
#include <iostream.h>
#include <conio.h>
//PUNTERO6.CPP
int leer(){
int N;
clrscr();
cout << "Digite un entero para convertirlo a binario: ";
cin >> N;
return (N);
}
CalcularBinario(int N, int *p){
int c,r;
c = N >> 1;
*p = N % 2;
cout <<"\n
Leer desde abajo hacia arriba" << *p;
while(c){
p++;
*p = c % 2;
cout << "\n" << *p;
c >>= 1;
}
return 0;
}
main(){
63
Ordenar(int *i){
int *j, aux ;
while(*i) {
j = i+1;
while(*j) {
if (*i > *j){
aux = *i;
*i = *j;
*j = aux;
}
j++;
}
i++;
}
}
Escribir(int *v){
cout <<"\n\tLos nmeros ordenados son:\n\n";
while(*v){
cout.width(4);
cout << *v++;
}
}
void main(){
int vector[N];
clrscr();
Leer(vector);
Ordenar(vector);
Escribir(vector);
while (!kbhit()); return 0;
}
64
Escribir(int *v){
int i;
cout << "\n\tLos nmeros ordenados son:\n\n";
for (i = 0; i < N; i++)
cout << setw(5) << v[i];
}
}
void main(){
int numeros[N];
clrscr();
Leer(numeros);
Ordenar(numeros);
Escribir(numeros);
while (!kbhit());
}
el
C++,
adicionalmente,
se
puede
pasar
por
referencia
el
parmetro
65
aux = a;
a
= b;
b
= aux;
}
void main(){
float X, Y;
clrscr();
cout << "Digite un real para almacenar en variable X: ";
cin >> X;
cout << "Digite un real para almacenar en variable Y: ";
cin >> Y;
IntercambioEnMemoria(X, Y);
cout << "\nDespus de intercambiadas, X ahora es igual a "
cout << "\ny la variable Y ahora es igual a " << Y;
<< X;
}
Inicialmente, en la funcin main() del programa anterior, se pide ser
digitados los valores de las variables X y Y, supongamos, que despus de esto, la
memoria RAM se encuentra as:
X
Y
13.1
7.4
1000
1002
66
main()
IntercambioEnMemoria()
(a)
(b)
X
Y
aux
13.1
7.4
1000
1002
Se define tambien la variable local aux. Las tres instrucciones del cuerpo de
la funcin IntercambioEnMemoria() realizan lo siguiente:
aux = a;
el efecto en memoria RAM es:
main()
IntercambioEnMemoria()
(a)
(b)
X
Y
aux
13.1
7.4
13.1
1000
1002
Contina:
a = b;
main()
IntercambioEnMemoria()
(a)
(b)
X
Y
aux
7.4
7.4
13.1
1000
1002
Finalmente, la instruccin:
b = aux;
RAM
main()
IntercambioEnMemoria()
(a)
(b)
X
Y
aux
7.4
13.1
13.1
1000
1002
X
Y
7.4
13.1
67
1000
1002
Y por lo tanto, estos son los valores para cada una de las variables, X y Y,
que mostrar en pantalla.
al
nuevo
estilo
del
C++.
#include <iostream.h>
#include <conio.h>
//REFEREN2.CPP
leer(int &N){
clrscr();
cout << "Digite: ";
cin >> N; //observe que N al ser puntero se coloca sin &
}
CalcularBinario(int &N){
int c,r;
c = N >> 1;
// divide entre dos
r = N % 2;
cout << "\n" << r << " Leer de abajo hacia arriba";
while(c){
r = c % 2;
c >>= 1;
cout << "\n" << r;
}
}
void main(){
int decimal;
leer(decimal); //invocacin por referencia
CalcularBinario(decimal); //invocacin por valor
}
2.3 Ejemplo de paso de parmetro por referencia
Convierte un nmero en base 10 a base binaria
al
nuevo
estilo
del
C++.
#include <iostream.h>
#include <conio.h>
//REFEREN2.CPP
leer(int &N){
cout << "Digite: "; cin >> N;//observe que N al ser puntero se coloca sin &
}
CalcularBinario(int &N){
int c, r;
c = N >> 1;
// divide entre dos
r = N % 2;
cout << "\n" << r << " Leer de abajo hacia arriba";
while(c){
r = c % 2;
68
c >>= 1;
cout << "\n" << r;
}
}
void main(){
int decimal;
leer(decimal); //invocacin por referencia
CalcularBinario(decimal); //invocacin por valor
}
69
70
int t;
float Promedio=0, *P;
P = Datos;
for(t = 0; t < N; ++t){
Promedio += *P;
// Promedio = Promedio + *P; es lo mismo
P++;
}
Promedio /= N;
return Promedio;
}
float CalcularPromedio(float Datos[], int N){ //PRUEBA ESCRITORIO
int t;
float Promedio=0, *P;
P = Datos;
for(t = 0; t < N; ++t){
Promedio += *P;
// Promedio = Promedio + *P; es lo mismo
P++;
}
Promedio /= N;
return Promedio;
}
float CalcularMediana(float Datos[], unsigned int N){ //PRUEBA ESCRITORIO
register int t;
float temporal[MaxArreglo];
for (t=0; t<N; ++t)
temporal[t] = Datos[t]; /* copiar Datos*/
ClasificarMuestraAscendentemente(temporal, N);
return (temporal[(N-1)/2]);
}
void IntercambiarValoresDosVariables(float *a, float *b){
float aux;
aux = *a;
*a = *b;
*b = aux;
}
void ClasificarMuestraAscendentemente(float *Datos, unsigned int N){
//PRUEBA ESCRITORIO cuando sea invocada desde la funcion CalcularMediana()
int i,j;
float aux;
for (i = 0; i < N; i++)
for (j = i; j < N; j++)
if (Datos[i] > Datos[j])
IntercambiarValoresDosVariables(&Datos[i], &Datos[j]);
}
float EncontrarModa(float *Datos, int N){ //PRUEBA ESCRITORIO
register int t, w;
71
72
Datos
Porcentajes \n\n";
73
char OpcionMenu(){
char entrada;
clrscr();
do {
gotoxy(
gotoxy(
gotoxy(
gotoxy(
gotoxy(
gotoxy(
gotoxy(
gotoxy(
gotoxy(
gotoxy(
3, 1);
3, 2);
3, 3);
3, 4);
3, 5);
3, 6);
3, 7);
3, 8);
3, 9);
3,13);
cout
cout
cout
cout
cout
cout
cout
cout
cout
cout
<<
<<
<<
<<
<<
<<
<<
<<
<<
<<
"MENU PRINCIPAL";
"==============";
"Capturar Datos";
"Estadsticas b sicas";
"Ordenar de menor a mayor";
"Mostrar Datos";
"Graficar en barras";
"Imprimir en papel";
"Terminar";
"Elija letra inicial (C E O M G I T): ";
74
75
}
}
PROGRAMA A REALIZAR COMO EJERCICIO
Utilizando datos obtenidos en algn laboratorio de los realizados aqu en la
universidad, y claro que dentro de otras asignaturas, estudie y utilice el
programa ESTADIST.CPP anterior para efectuar clculos estadsticos bsicos.
Presente dibujo en pantalla representativo del experimento en cuestin, discuta
esto primero con el profesor. El programa debe presentar men diseado por usted
mismo a partir de la primera clase y todo en forma grfica. Para la lectura de
los correspondientes valores reales(float) utilice la funcin LeerFloat(...) la
cual encontrar en el archivo IO_Graph.CPP.
76
<ConIO.h>
<IOStream.h>
<ConStream.h>
<Math.h>
<CType.h>
<DOS.h>
constream Escribir;
void main(){
int I, J, K, Tecla[71], tempo=60, ModoVideo;
Tecla[0]=0;
Tecla[39]= 5; Tecla[40]= 7; Tecla[41]= 8; Tecla[42]= 9;
Tecla[44]=11; Tecla[45]=13; Tecla[46]=14; Tecla[47]=15;
Tecla[49]=17; Tecla[50]=18; Tecla[51]=19; Tecla[52]=21;
Tecla[54]=23; Tecla[55]=24; Tecla[56]=25; Tecla[57]=27;
Tecla[59]=29; Tecla[60]=30; Tecla[61]=31; Tecla[62]=32;
Tecla[64]=35; Tecla[65]=36; Tecla[66]=37; Tecla[67]=38;
Tecla[69]=40; Tecla[70]=42;
int Nota[88];
char C[2], opcion, *p;
char Sinfonia40[]
55,2, 54,2,
62,2, 61,2,
54,2, 52,2,
61,2, 59,2,
62,2, 61,2,
62,2, 61,2,
55,2, 54,4,
0,4, 64,8,
64,4, 65,4,
= {
//Mozart
54,4, 55,2, 54,2,
59,4, 59,2, 57,2,
52,4, 54,2, 52,2,
58,4, 58,2, 55,2,
61,4, 64,4, 58,4,
61,4, 64,4, 58,4,
46,4, 47,4, 49,4,
65,2, 0,6, 64,8,
-1,-1};
54,4,
55,4,
52,4,
54,4,
61,4,
61,4,
50,4,
65,2,
55,2,
55,2,
54,2,
54,2,
59,4,
59,4,
52,2,
0,6,
54,2,
54,2,
52,2,
52,2,
54,4,
62,4,
50,2,
64,8,
Tecla[43]=10;
Tecla[48]=16;
Tecla[53]=22;
Tecla[58]=28;
Tecla[63]=33;
Tecla[68]=39;
54,4,
52,4,
52,4,
50,4,
0,4,
61,2,
49,4,
65,4,
62,4,
52,4,
61,4,
50,4,
0,4,
0,4,
0,4,
0,4,
59,2, 57,2,
47,4, 54,4,
64,4, 65,4,
77
78
VGA
50-lineas \n";
cout << "\nNOTA: Para un tipo dado de monitor de video no todos
funcionarn como se espera\n";
cout <<"Ensaye cada uno para su monitor de video, y determine los que ""le
sirven""\n";
cout<<"\n\nDigite Valor del modo de texto deseado: ";
cin >> ModoVideo;
textmode(ModoVideo);
Escribir.window(1,1,80,25); textbackground(BLUE); Escribir.clrscr();
textcolor(MAGENTA);
gotoxy(12,5); Escribir << "PROGRAMA";
gotoxy(12,7); Escribir << "DEMOSTRACION";
textcolor(LIGHTGREEN); gotoxy(9,10); Escribir<<(char)213;
for(i=1; i<=21; i++)
Escribir << (char)205;
Escribir<<(char)184;
gotoxy(9,11);Escribir<<(char)179<<"
gotoxy(9,12);Escribir<<(char)179;
TECLADO
"<<(char)179;
MUSICAL
"<<(char)179;
79
gotoxy(9,14);Escribir<<(char)212;
for(i=1; i<=21; i++)
Escribir << (char)205;
Escribir<<(char)190;
textcolor(YELLOW); gotoxy(7,23);
Escribir << "CUALQUIER TECLA PARA SEGUIR";
getch();
textcolor(WHITE); Escribir.clrscr();
gotoxy(3,15);Escribir << "------------ CANCIONES -------------";
gotoxy(3,16);Escribir << "A-Marcha
E-Humoresca
I-Japonesa";
gotoxy(3,17);Escribir << "B-Stars
F-La Cucaracha J-Pop
";
gotoxy(3,18);Escribir << "C-Mozart
G-Danubio Azul K-Escalas ";
gotoxy(3,19);Escribir << "D-Mejicana H-Dandy
ESC- Salir";
textcolor(WHITE); textbackground(BLACK);
for( I=0; I<=17; I++)
// Dibuja teclas blancas
for(J=0; J<=8; J++){
gotoxy(2+I*2,5+J); Escribir << (char)219<<(char)221;
}
for( I=0; I<=15; I++)
//Dibuja teclas negras
for( J=0; J<=4; J++){
if( I==2 || I==6 || I==9 || I==13 )
continue;
gotoxy(5+I*2, 5+J);
Escribir<< (char)32<<(char)222;
}
for( J=0; J<=9; J++){ //Dibuja el borde del teclado
gotoxy(1,4+J); textcolor(RED); textbackground(BLACK);
Escribir <<(char)221;
gotoxy(37, 4+J); textcolor(WHITE); Escribir <<(char)221;
textcolor(RED); textbackground(BLUE);Escribir << (char)221;
}
textcolor(RED); textbackground(BLUE); gotoxy(1,4);
for( I=0; I<=36; I++)
Escribir<< (char)219;
Escribir<< (char)(221); gotoxy(1, 13);
for( I=0;I<=36;I++)
Escribir<< (char)219;;
Escribir<< (char)(221);
for(;;){
textcolor(MAGENTA); textbackground(LIGHTGRAY);
gotoxy(2,21); Escribir<< "
gotoxy(2,21); Escribir<<"Digite letra ====>";
";
80
case
case
case
case
case
case
case
case
case
case
case
'B': Escribir<<"Stars";
p=StarsAndStripesForever;
break;
'C': Escribir<<"Cuarenta";
p=Sinfonia40;
break;
'D': Escribir<<"Mejicana";
p=PopularMejicana;
break;
'E': Escribir<<"Humoresca";
p=Humoresque;
break;
'F': Escribir<<"La Cucaracha";
p=LaCucaracha;
break;
'G': Escribir<<"Azul";
p=ElDanubioAzul;
break;
'H': Escribir<<"Dandy ";
p=YankeeDoodle;
break;
'I': Escribir<<"Sakura";
p=Sakura;
break;
'J': Escribir<<"Pop";
p=PopGoesTheWeasle;
break;
'K': Escribir<<"Escalas ";
p=Escalas;
break;
27: return;
}
_setcursortype(_NOCURSOR);
if(opcion>='A' && opcion<='K'){
while(*p!=-1 && !kbhit()){
J=*p;
K=*(p+1);
int Q = Tecla[J]-3;
if( J>=39 && J<=68 ){
gettext(Q,5,Q,5, C);
if (C[0]!=32){
textcolor(BLACK);
textbackground(LIGHTGRAY);
gotoxy(Q,11); Escribir<<(char)14;
textcolor(WHITE); textbackground(BLACK);
}
else{
textcolor(WHITE); textbackground(BLACK);
gotoxy(Q,7); Escribir<< (char)14;
textcolor(BLACK);
textbackground(LIGHTGRAY);
}
}
sound(Nota[J]);
delay(K*tempo);
81
82
<graphics.h>
<conio.h>
<stdlib.h>
<dos.h>
83
setfillstyle(1,BLUE);
bar3d(x+15,y+10,x+30,y+22,7,1);
line(x+22,y+27,x+27,y+27); line(x+10,y+33,x+30,y+33);
line(x+6,y+38,x+26,y+38);
line(x+10,y+33,x+6,y+38); line(x+30,y+33,x+26,y+38);
line(x+27,y+30,x+25,y+33);
setcolor(RED);line(x+26,y+29,x+28,y+29);
setcolor(LIGHTGRAY);line(x+31,y+16,x+36,y+16);
settextstyle(SMALL_FONT, HORIZ_DIR, 4);
settextjustify(CENTER_TEXT, TOP_TEXT);
setcolor(MAGENTA);outtextxy(x+AnchoIcono/2, y+AltoIcono, "Computo");
}
void Icono3(int x, int y){
setcolor(DARKGRAY); setfillstyle(1,LIGHTMAGENTA);
fillellipse(x+25, y+10, 5, 5);
bar(x+15,y+22,x+35,y+30);
setfillstyle(1,WHITE); bar(x+15, y+16, x+35, y+21);
setfillstyle(1,BLUE);
bar(x+20, y+20, x+30, y+45);
setfillstyle(1,RED);
bar(x+19, y+46, x+31, y+48);
setcolor(DARKGRAY);
line(x+25,y+30, x+25,y+48); line(x+20,y+10, x+32,y+10);
setcolor(BLUE);
line(x+22,y+15, x+22,y+20); line(x+29,y+15, x+29,y+20);
setcolor(LIGHTGRAY);
line(x+18,y+14, x+11,y+19);
line(133,364,137,369);
setfillstyle(1,GREEN); setcolor(DARKGRAY);
bar3d(x+31,y+31, x+36,y+36,3,0);
settextstyle(SMALL_FONT, HORIZ_DIR, 4);
settextjustify(CENTER_TEXT, TOP_TEXT);
setcolor(MAGENTA);outtextxy(x+AnchoIcono/2, y+AltoIcono,"Personal");
}
void Icono4(int x, int y){
setcolor(WHITE); line(x+30,y+10,x+10,y+30); line(x+10,y+30, x+20,y+40);
line(x+20,y+40, x+40,y+20); line(x+40,y+20, x+30,y+10);
line(x+10,y+30, x+10,y+35); line(x+10,y+35, x+20,y+45);
line(x+20,y+40, x+20,y+45); line(x+20,y+45, x+40,y+25);
line(x+40,y+25, x+40,y+20); line(x+12,y+28,x+7,y+23);
line(x+7,y+23, x+20,y+10); line(x+20,y+10, x+25,y+15);
line(x+22,y+12, x+24,y+10); line(x+24,y+10, x+27,y+13);
setcolor(DARKGRAY);
line(x+38,y+29, x+26,y+41);
line(x+39,y+30,x+27,y+42);
line(x+40,y+31, x+28,y+43); line(x+41,y+32, x+29,y+44);
setcolor(BLUE); line(x+20,y+14, x+11,y+23); line(x+20,y+16, x+12,y+24);
setcolor(RED); line(x+35,y+20, x+32,y+23);
settextstyle(SMALL_FONT, HORIZ_DIR, 4);
settextjustify(CENTER_TEXT, TOP_TEXT);
setcolor(MAGENTA);outtextxy(x+AnchoIcono/2, y+AltoIcono,"Impresin");
}
void Icono5(int x, int y){
setcolor(DARKGRAY); setfillstyle(1,YELLOW); fillellipse(x+10, y+10, 8, 8);
line(x+10,y+7,x+10,y+11); line(x+12,y+10,x+6,y+10);
line(x+10,y+5,x+10,y+3);
setcolor(WHITE); line(x+10,y+25,x+30,y+5); line(x+30,y+5,x+40,y+15);
line(x+40,y+15,x+20,y+35);
line(x+10,y+25,x+25,y+20);
line(x+25,y+20,x+30,y+5);
line(x+40,y+15,x+27,y+13);
setcolor(RED); line(x+29,y+19,x+33,y+15);
line(x+30,y+20,x+34,y+16);line(x+31,y+21,x+35,y+17);
setcolor(DARKGRAY);
line(x+5,y+30,x+18,y+22);
line(x+18,y+22,x+22,y+30); line(x+22,y+30,x+17,y+34);
84
setfillstyle(1,LIGHTGREEN); bar3d(x+5,y+30,x+20,y+47,1,0);
setfillstyle(1,WHITE); bar3d(x+7,y+32,x+18,y+35,1,0);
circle(x+29,y+35,3); circle(x+36,y+35,3);
line(x+27,y+35,x+35,y+28);
line(x+38,y+36,x+44,y+28);
line(x+35,y+28,x+35,y+31); line(x+44,y+28,x+44,y+31);
setfillstyle(1,YELLOW); bar3d(x+45,y+10,x+47,y+28,1,0);
settextstyle(SMALL_FONT, HORIZ_DIR, 4);
settextjustify(CENTER_TEXT, TOP_TEXT);
setcolor(MAGENTA);outtextxy(x+AnchoIcono/2, y+AltoIcono,"Gerencia");
}
void Icono6(int x, int y){
setcolor(RED); setfillstyle(1,WHITE); bar3d(x+20,y+5,x+40,y+30,1,0);
bar3d(x+15,y+10,x+35,y+35,1,0); bar3d(x+10,y+15,x+30,y+40,1,0);
line(x+12,y+20,x+28,y+20); line(x+12,y+25,x+28,y+25);
line(x+12,y+30,x+28,y+30);line(x+12,y+35,x+28,y+35);
line(x+12,y+40,x+28,y+40);
settextstyle(SMALL_FONT, HORIZ_DIR, 4);
settextjustify(CENTER_TEXT, TOP_TEXT);
setcolor(MAGENTA);outtextxy(x+AnchoIcono/2, y+AltoIcono,"Listados");
}
void Icono7(int x, int y){
setfillstyle(1, DARKGRAY);
bar(x+10,y+10,x+40,y+40);
setfillstyle(1, YELLOW);
bar(x+15,y+25,x+35,y+39);
setcolor(WHITE);line(x+12,y+37,x+12,y+39);line(x+38,y+37,x+38,y+39);
line(x+15,y+10,x+15,y+20); line(x+15,y+20,x+35,y+20);
setfillstyle(1,WHITE); bar(x+20,y+10,x+35,y+20);
setfillstyle(1,DARKGRAY);
bar(x+18,y+11,x+32,y+19);
setcolor(LIGHTGRAY);line(x+38,y+17,x+42,y+13);
settextstyle(SMALL_FONT, HORIZ_DIR, 4);
settextjustify(CENTER_TEXT, TOP_TEXT);
setcolor(MAGENTA);outtextxy(x+AnchoIcono/2, y+AltoIcono,"Archivos");
}
void Icono8(int x, int y){
setfillstyle(1,YELLOW); bar3d(x+5,y+15,x+30,y+45,10,1);
bar3d(x+7,y+17,x+27,y+28,1,0); bar3d(x+7,y+32,x+27,y+43,1,0);
setcolor(DARKGRAY);
line(x+13,y+24,x+22,y+24);
line(x+13,y+37,x+22,y+37);
line(x+13,y+23,x+13,y+24); line(x+22,y+23,x+22,y+24);
line(x+13,y+36,x+13,y+37); line(x+22,y+36,x+22,y+37);
settextstyle(SMALL_FONT, HORIZ_DIR, 4);
settextjustify(CENTER_TEXT, TOP_TEXT);
setcolor(MAGENTA);outtextxy(x+AnchoIcono/2, y+AltoIcono,"Almacen");
}
void Icono9(int x, int y){
setcolor(DARKGRAY);
arc(x+10,y+10,630,370,20);
line(x+30,y+5,x+10,y+30); line (x+25,y+10,x+15,y+10);
line(x+15,y+10,x+15,y+22); line (x+20,y+15,x+12,y+7);
line(x+20,y+27,x+20,y+40); line(x+28,y+19,x+35,y+40);
fillellipse(x+12,y+7,1,1);
settextstyle(SMALL_FONT, HORIZ_DIR, 4);
settextjustify(CENTER_TEXT, TOP_TEXT);
setcolor(MAGENTA);outtextxy(x+AnchoIcono/2, y+AltoIcono,"Par bola");
}
void Icono10(int x, int y){
85
}
void Icono12(int x, int y){
static char pica[] = {20,21,
15,28, 15,29, 14,30, 13,31, 13,32,
11,39, 12,40, 13,41, 14,42, 15,42,
19,44, 19,45, 18,46, 18,47, 17,48,
23,49, 24,49, 24,48, 23,47, 23,46,
24,42, 25,42, 26,42, 27,42, 28,41,
30,34, 29,33, 28,32, 28,31, 27,30,
22,23, 21,22,21,21};
int i;
20,22,
12,33,
16,42,
17,49,
22,45,
29,40,
26,29,
19,23,
11,34,
17,42,
18,49,
22,44,
30,39,
26,28,
18,24,
11,35,
18,42,
19,49,
21,43,
30,38,
25,27,
17,25,
11,36,
19,41,
20,49,
21,42,
30,37,
24,26,
17,26,
11,37,
20,42,
21,49,
22,41,
30,36,
24,25,
16,27,
11,38,
20,43,
22,49,
23,42,
30,35,
23,24,
86
setfillstyle(SOLID_FILL, DARKGRAY);
floodfill(x+20, y+30, DARKGRAY);
floodfill(x+20, y+46, DARKGRAY);
}
void Icono13(int x,int y){
static char corazon[]={20,25, 19,24, 19,23, 19,22, 18,21, 17,21, 16,21,
15,21, 14,21, 13,22, 12,23, 12,24, 11,25, 11,26, 11,27, 11,28, 11,29, 11,30,
11,31, 12,32, 12,33, 13,34, 13,35, 14,36, 14,37, 15,38, 16,39, 17,40, 17,41,
18,42, 18,43, 19,44, 19,45, 19,46, 20,47, 20,48, 21,48, 21,47, 22,46, 22,45,
22,44, 23,43, 23,42, 24,41, 24,40, 25,39, 26,38, 27,37, 27,36, 28,35, 28,34,
29,33, 29,32, 30,31, 30,30, 30,29, 30,28, 30,27, 30,26, 30,25, 29,24, 29,23,
28,22, 27,21, 26,21, 25,21, 24,21, 23,21, 22,22, 22,23, 22,24, 21,25};
int i;
settextstyle(SMALL_FONT, HORIZ_DIR, 4);
settextjustify(CENTER_TEXT, TOP_TEXT);
setcolor(MAGENTA);outtextxy(x+AnchoIcono/2, y+AltoIcono,"Corazn");
x+=5; y-=10;
for(i=0; i<sizeof(corazon); i+=2)
//
putpixel(x+corazon[i], y+corazon[i+1], RED);
setfillstyle(SOLID_FILL, RED);
}
void Icono14(int x,int y){
static char trebol[] ={20,21, 19,21, 18,22, 17,23, 16,24, 16,25, 16,26,
17,27, 17,28, 18,29, 19,30, 18,31, 17,31, 16,30, 15,30, 14,30, 14,31, 15,31,
16,31, 13,31, 12,32, 11,33,
11,34, 11,35, 11,36, 12,37, 12,38, 13,38, 14,39,
15,39, 16,39, 17,39, 18,38,
18,37, 19,36, 20,37, 20,38, 20,39, 20,40, 19,41,
19,42, 19,43, 19,44, 18,45,
18,46, 18,47, 18,48, 17,49, 17,50, 18,50, 19,50,
20,50, 21,50, 22,50, 23,50, 24,50, 24,49, 23,48, 23,47, 23,46, 23,45,
22,44,
22,43, 22,42, 22,41, 21,40, 21,39, 21,38, 21,37, 22,36, 23,37, 23,38,
24,39,
25,39, 26,39, 27,39, 28,38, 29,38, 29,37, 30,36, 30,35, 30,34, 30,33,
29,32,
28,31, 27,30, 26,30, 25,30, 25,31, 26,31, 27,31, 24,31, 23,31, 22,30,
23,29,
24,28,24,27, 25,26, 25,25, 25,24, 24,23, 23,22, 22,21, 21,21}; //98 puntos
int i;
settextstyle(SMALL_FONT, HORIZ_DIR, 4);
settextjustify(CENTER_TEXT, TOP_TEXT);
setcolor(MAGENTA);outtextxy(x+AnchoIcono/2, y+AltoIcono,"Trbol");
x+=5; y-=10;
for(i=0; i<sizeof(trebol); i+=2)
//
putpixel(x+trebol[i], y+trebol[i+1], DARKGRAY);
setfillstyle(SOLID_FILL, DARKGRAY);
floodfill(x+20, y+30, DARKGRAY);
floodfill(x+20, y+45, DARKGRAY);
}
void Icono15(int x, int y){
static char uva[]={ 37,25, 38,25, 39,25,
39,26, 40,26, 41,26, 37,27, 38,27, 39,27,
39,28, 40,28, 41,28, 42,28, 43,28, 44,28,
39,29, 40,29, 41,29, 47,29, 37,30, 38,30,
37,31, 38,31, 39,31, 40,31, 41,31, 47,31,
41,32, 42,32, 43,32, 44,32, 45,32, 46,32,
41,33, 37,34, 38,34, 39,34, 40,34, 41,34,
41,35 };
settextstyle(SMALL_FONT, HORIZ_DIR, 4);
settextjustify(CENTER_TEXT, TOP_TEXT);
40,25,
40,27,
45,28,
39,30,
37,32,
37,33,
37,35,
41,25,
41,27,
46,28,
40,30,
38,32,
38,33,
38,35,
37,26,
37,28,
37,29,
41,30,
39,32,
39,33,
39,35,
38,26,
38,28,
38,29,
48,30,
40,32,
40,33,
40,35,
87
setcolor(MAGENTA);outtextxy(x+AnchoIcono/2, y+AltoIcono,"Uva");
x-=15; y-=25;
setcolor(MAGENTA);
circle(x+28,y+40,6);circle(x+40,y+40,6);circle(x+52,y+40,6);
circle(x+34,y+50,6);circle(x+46,y+50,6);circle(x+40,y+60,6);
setfillstyle(SOLID_FILL, MAGENTA); floodfill(x+29, y+39,MAGENTA);
floodfill(x+41, y+39, MAGENTA);
floodfill(x+53, y+39, MAGENTA);
floodfill(x+35, y+49, MAGENTA);
floodfill(x+47, y+49, MAGENTA);
floodfill(x+41, y+59, MAGENTA);
int i;
for(i=0; i<sizeof(uva); i+=2)
putpixel(x+uva[i]+12, y+uva[i+1]+20, BROWN);
}
void Icono16(int x, int y){
static char manzana[] = {16,16, 17,16, 18,16, 19,16, 20,16, 21,16, 22,16,
36,16, 37,16, 38,16, 39,16, 40,16, 41,16, 42,16, 15,17, 23,17, 35,17,
43,17, 14,18, 24,18, 34,18, 44,18, 13,19, 25,19, 33,19, 45,19, 12,20,
26,20, 32,20, 46,20, 11,21, 27,21, 31,21, 47,21, 10,22, 28,22, 30,22,
48,22, 10,23, 29,23, 49,23, 10,24, 50,24, 9,25, 50,25, 8,26, 50,26,
8,27, 50,27, 8,28, 50,28, 8,29, 50,29, 8,30, 50,30, 8,31, 50,31,
8,32, 50,32, 8,33, 50,33, 8,34, 50,34, 8,35, 50,35, 8,36, 50,36,
8,37, 50,37, 8,38, 50,38, 9,39, 49,39, 10,40, 48,40, 10,41, 48,41,
10,42, 48,42, 11,43, 47,43, 12,44, 46,44, 13,45, 45,45, 14,46, 44,46,
15,47, 43,47, 16,48, 42,48, 17,49, 41,49, 18,50, 19,50, 20,50, 21,50,
22,50, 23,50, 24,50, 25,50, 26,50, 27,50, 28,50, 29,50, 30,50, 31,50,
32,50, 33,50, 34,50, 35,50, 36,50, 37,50, 38,50, 39,50, 40,50
};
int i;
settextstyle(SMALL_FONT, HORIZ_DIR, 4);
settextjustify(CENTER_TEXT, TOP_TEXT);
setcolor(MAGENTA);outtextxy(x+AnchoIcono/2, y+AltoIcono,"Manzana");
x-=15; y-=25;
for(i=0; i<sizeof(manzana); i+=2)
putpixel(x+manzana[i]+12, y+manzana[i+1]+20, LIGHTRED);
setfillstyle(SOLID_FILL, RED);
floodfill(x+41, y+52, LIGHTRED);
static char palo[] = { 28, 8, 29, 8, 30, 8, 28, 9, 30, 9, 24,10, 25,10,
26,10, 27,10, 28,10, 30,10, 31,10, 32,10, 33,10, 34,10, 23,11, 35,11,
36,12, 23,13, 35,13, 24,14, 25,14, 26,14, 27,14, 28,14, 30,14, 31,14,
33,14, 34,14, 28,15, 30,15, 28,16, 30,16, 28,17, 30,17, 28,18,
28,19, 30,19, 28,20, 30,20, 28,21, 30,21, 29,22 };
for(i=0; i<sizeof(palo); i+=2)
//45*2 = 90
putpixel(x+palo[i]+12, y+palo[i+1]+20, GREEN);
setfillstyle(SOLID_FILL, GREEN);
floodfill(x+42, y+31, GREEN);
26,10,
22,12,
32,14,
30,18,
}
void Icono17(int x, int y){
static char naranja[]={ 37,25, 38,25, 39,25, 40,25, 41,25, 37,26, 38,26,
39,26, 40,26, 41,26, 37,27, 38,27, 39,27, 40,27, 41,27, 37,28, 38,28,
39,28, 40,28, 41,28, 42,28, 43,28, 44,28, 45,28, 46,28, 37,29, 38,29,
39,29, 40,29, 41,29, 47,29, 37,30, 38,30, 39,30, 40,30, 41,30, 48,30,
37,31, 38,31, 39,31, 40,31, 41,31, 47,31, 37,32, 38,32, 39,32, 40,32,
41,32, 42,32, 43,32, 44,32, 45,32, 46,32, 37,33, 38,33, 39,33, 40,33,
41,33, 37,34, 38,34, 39,34, 40,34, 41,34, 37,35, 38,35, 39,35, 40,35,
41,35 };
int i;
settextstyle(SMALL_FONT, HORIZ_DIR, 4);
88
settextjustify(CENTER_TEXT, TOP_TEXT);
setcolor(MAGENTA);outtextxy(x+AnchoIcono/2, y+AltoIcono,"Naranja");
x-=15; y-=20;
setcolor(YELLOW); circle(x+39,y+50,14);
for(i=0; i<sizeof(naranja); i+=2)
putpixel(x+naranja[i], y+naranja[i+1], GREEN);
setfillstyle(SOLID_FILL, GREEN);
floodfill(x+45, y+30, GREEN);
setfillstyle(SOLID_FILL, YELLOW);
floodfill(x+40, y+51, YELLOW);
}
void Icono18(int x, int y){
settextstyle(SMALL_FONT, HORIZ_DIR, 4);
settextjustify(CENTER_TEXT, TOP_TEXT);
setcolor(MAGENTA);outtextxy(x+AnchoIcono/2, y+AltoIcono,"Banano");
x-=10; y-=20;
setcolor(YELLOW); setfillstyle(SOLID_FILL,YELLOW);
fillellipse(x+38,y+45,20,20);
setcolor(LIGHTGRAY);
setfillstyle(SOLID_FILL,LIGHTGRAY);
fillellipse(x+30,y+41,18,18);
setcolor(DARKGRAY);
setfillstyle(SOLID_FILL,DARKGRAY);
fillellipse(x+24,y+60,2,2);
fillellipse(x+41,y+26,2,2);
}
void Icono19(int x, int y){
settextstyle(TRIPLEX_FONT, HORIZ_DIR, 5);
settextjustify(CENTER_TEXT, CENTER_TEXT);
setcolor(YELLOW); outtextxy(x+25, y+20,"");
settextstyle(SMALL_FONT, HORIZ_DIR, 4);
settextjustify(CENTER_TEXT, TOP_TEXT);
setcolor(MAGENTA);outtextxy(x+AnchoIcono/2, y+AltoIcono,"");
}
void Icono20(int x, int y){
static char cereza[] = {
42,25, 43,25, 42,26, 43,26, 42,27, 43,27,
42,28, 43,28, 42,29, 43,29, 42,30, 43,30, 42,31, 43,31, 42,32,
43,32, 42,33, 43,33, 42,34, 43,34, 42,35, 43,35, 42,36, 43,36,
42,37, 43,37, 42,38, 43,38, 42,39, 43,39, 42,40, 43,40, 42,41,
43,41, 42,42, 43,42, 42,43, 43,43, 42,44, 43,44, 42,45, 43,45,
42,46, 43,46, 42,47, 43,47, 42,48, 43,48, 42,49, 43,49, 42,50,
43,50, 42,51, 43,51, 42,52, 43,52, 33,37, 34,37, 34,36, 35,36,
35,35, 36,35, 36,34, 37,34, 37,33, 38,33, 38,32, 39,32, 39,31,
40,31, 40,30, 41,30, 41,29, 42,29, 43,29, 44,29, 45,29, 45,30,
46,30, 46,31, 47,31, 47,32, 48,32, 48,33, 49,33, 49,34, 50,34,
50,35, 51,35, 51,36, 52,36, 52,37, 53,38};
settextstyle(SMALL_FONT, HORIZ_DIR, 4);
settextjustify(CENTER_TEXT, TOP_TEXT);
setcolor(MAGENTA);outtextxy(x+AnchoIcono/2, y+AltoIcono,"Cereza");
x-=15; y-=20;
setcolor(LIGHTRED);
circle(x+30,y+45,5);
circle(x+50,y+45,5);
circle(x+40,y+60,5);
setfillstyle(SOLID_FILL,LIGHTRED); floodfill(x+31, y+44, LIGHTRED);
floodfill(x+51, y+44, LIGHTRED);floodfill(x+41, y+59, LIGHTRED);
for(int i=0; i<sizeof(cereza); i+=2)
putpixel(x+cereza[i]-3, y+cereza[i+1]+2, DARKGRAY);
}
void Icono21(int x, int y){
settextstyle(SMALL_FONT, HORIZ_DIR, 4);
settextjustify(CENTER_TEXT, TOP_TEXT);
89
setcolor(MAGENTA);outtextxy(x+AnchoIcono/2, y+AltoIcono,"Moneda");
setfillstyle(SOLID_FILL, YELLOW);
setcolor(YELLOW); circle(x+25,y+25,15);
floodfill(x+25, y+25,YELLOW);
setcolor(BLACK); circle(x+25, y+25,13);
settextstyle(TRIPLEX_FONT, HORIZ_DIR, 1);
settextjustify(CENTER_TEXT, CENTER_TEXT); outtextxy(x+25, y+25,"$");
}
void Icono22(int x, int y){
static char fresa[] =
31,16, 32,16, 33,16,
22,18, 40,18, 21,19,
18,23, 44,23, 18,24,
27,25, 37,25, 39,25,
46,26, 18,27, 21,27,
30,28, 34,28, 42,28,
32,30, 46,30, 18,31,
38,34, 46,34, 19,35,
34,38, 44,38, 20,39,
42,42, 22,43, 42,43,
25,47, 39,47, 26,48,
30,52, 31,52, 32,52,
int i;
{
24,16, 25,16, 26,16, 27,16, 28,16, 29,16, 30,16,
34,16, 35,16, 36,16, 37,16, 38,16, 23,17, 39,17,
41,19, 20,20, 42,20, 19,21, 43,21, 18,22, 44,22,
24,24, 25,24, 26,24, 38,24, 44,24, 18,25, 23,25,
45,25, 18,26, 22,26, 28,26, 36,26, 40,26, 44,26,
29,27, 35,27, 41,27, 43,27, 46,27, 18,28, 20,28,
46,28, 18,29, 19,29, 31,29, 33,29, 46,29, 18,30,
46,31, 18,32, 22,32, 46,32, 18,33, 46,33, 18,34,
45,35, 20,36, 26,36, 44,36, 20,37, 44,37, 20,38,
44,39, 20,40, 44,40, 21,41, 43,41, 22,42, 30,42,
22,44, 42,44, 23,45, 41,45, 24,46, 34,46, 40,46,
38,48, 27,49, 38,49, 28,50, 38,50, 29,51, 37,51,
33,52, 34,52, 35,52, 36,52
};//138 puntos
90
};
fillellipse(x+18,y+27,3,2);
}
void Icono24(int x, int y){
settextstyle(SMALL_FONT, HORIZ_DIR, 4);
settextjustify(CENTER_TEXT, TOP_TEXT);
setcolor(MAGENTA);outtextxy(x+AnchoIcono/2, y+AltoIcono,"Naranja");
y-=10; x+=5;
setcolor(LIGHTRED);
setfillstyle(SOLID_FILL,YELLOW);
circle(x+20,y+40,10);
floodfill(x+20,y+40, LIGHTRED);
static char naranja []={30,15, 29,16, 28,16, 28,17, 27,17, 27,18, 26,19,
26,20,25,21,25,22,24,23,24,24,23,25,23,26,22,27,22,28,21,29,21,30, 20,31};
for(int i=0; i<38; i+=2)
putpixel(x+naranja[i], y+naranja[i+1], GREEN);
setfillstyle(SOLID_FILL, GREEN);
fillellipse(x+17,y+23,6,3);
floodfill(x+17, y+23, GREEN);
}
void Icono25(int x, int y){ // Arriba
int Color=DARKGRAY;
settextstyle(SMALL_FONT, HORIZ_DIR, 4);
settextjustify(CENTER_TEXT, TOP_TEXT);
setcolor(MAGENTA);outtextxy(x+AnchoIcono/2, y+AltoIcono,"Arriba");
y-=10; x+=5; setcolor(Color);
line(x+20,y+20,x+12,y+36);
line(x+12,y+36,x+18,y+36);
line(x+18,y+36,x+18,y+49);
line(x+18,y+49,x+22,y+49);
line(x+22,y+49,x+22,y+36);
line(x+22,y+36,x+28,y+36);
line(x+28,y+36,x+20,y+20);
setfillstyle(SOLID_FILL, Color);
floodfill(x+20, y+45, Color);
}
void Icono26(int x, int y){// abajo
int Color=DARKGRAY;
settextstyle(SMALL_FONT, HORIZ_DIR, 4);
settextjustify(CENTER_TEXT, TOP_TEXT);
setcolor(MAGENTA);outtextxy(x+AnchoIcono/2, y+AltoIcono,"Abajo");
y-=10; x+=5; setcolor(Color);
line(x+18,y+20,x+22,y+20);
line(x+22,y+20,x+22,y+36);
line(x+22,y+36,x+28,y+36);
line(x+28,y+36,x+20,y+49);
line(x+20,y+49,x+12,y+36);
line(x+12,y+36,x+18,y+36);
line(x+18,y+36,x+18,y+20);
setfillstyle(SOLID_FILL, Color);
floodfill(x+20, y+45, Color);
}
void Icono27(int X, int Y){
int r = 20, x, y, color;
settextstyle(SMALL_FONT, HORIZ_DIR, 4);
settextjustify(CENTER_TEXT, TOP_TEXT);
setcolor(MAGENTA);outtextxy(X+AnchoIcono/2, Y+AltoIcono,"OVNI");
91
92
18,32, 19,32,
29,32, 30,32,
27,13, 27,14,
30,6, 30,7, 30,8,
23,2, 23,1, 30,4,
93
putpixel(x+Reina[i],y+Reina[i+1], DARKGRAY);
setfillstyle (SOLID_FILL, LIGHTRED);
floodfill (x+23,y+25, DARKGRAY);
}
void Icono35(int x, int y){
static char Caballo[] = {12,10, 13,11, 14,12, 13,13, 12,14, 13,14, 14,14,
15,14, 16,14, 17,15, 18,16, 19,17, 20,18, 19,19, 19,20, 18,21, 17,22, 16,23,
15,24, 15,25, 15,26, 15,27, 15,28, 16,29, 17,30, 18,31, 17,32, 16,33, 15,34,
15,35, 15,36, 15,37, 15,38, 15,39, 15,40, 16,40, 17,40, 18,40, 19,40, 20,40,
21,40, 22,40, 23,40, 24,40, 25,40, 26,40, 27,40, 28,40, 29,40, 30,40, 13,9,
14,8, 15,7, 16,6, 17,7, 18,8, 19,9, 20,9, 21,9, 22,9, 23,8, 24,7, 25,6, 26,5,
27,6, 27,7, 27,8, 28,9, 29,10, 30,11, 31,12, 32,13, 32,14, 32,15, 32,16, 32,17,
32,18, 31,19, 31,20, 31,21, 30,22, 29,23, 28,24, 27,25, 27,26, 27,27, 27,28,
27,29, 27,30, 28,31, 29,32, 30,33, 30,34, 30,35, 30,36, 30,37, 30,38, 30,39
};
int i;
settextstyle(SMALL_FONT, HORIZ_DIR, 4);
settextjustify(CENTER_TEXT, TOP_TEXT);
setcolor(MAGENTA);outtextxy(x+AnchoIcono/2, y+AltoIcono,"Caballo");
for(i=0;i<sizeof(Caballo);i+=2)
putpixel(x+Caballo[i],y+Caballo[i+1], DARKGRAY);
setfillstyle (SOLID_FILL, LIGHTMAGENTA);floodfill(x+25,y+21, DARKGRAY);
}
void Icono36(int x, int y){
static char LORO[] = { 4, 8, 3, 4, 9, 3, 4,10, 3, 4,11, 3, 4,12, 3, 4,13,
3, 4,14, 3, 4, 7, 4, 12, 8, 4, 12, 9, 4, 12,10, 4, 12,11, 4, 12,12, 4, 12,13,
4, 12,14, 4, 4,15, 4, 4, 6, 5, 12, 7, 5, 12, 8, 5, 12, 9, 5, 12,10, 5, 12,11,
5, 12,12, 5, 12,13, 5, 12,14, 5, 12,15, 5, 4,16, 5, 4, 5, 6, 12, 6, 6, 12, 7,
6, 12, 8, 6, 4, 9, 6, 4,10, 6, 4,11, 6, 4,12, 6, 4,13, 6, 12,14, 6, 12,15,
6, 12,16, 6, 4,17, 6, 0, 5, 7, 0, 6, 7, 0, 7, 7, 4, 8, 7, 15, 9, 7, 15,10,
7, 14,11, 7, 14,12, 7, 15,13, 7, 0,14, 7, 0,15, 7, 12,16, 7, 12,17, 7, 4,18,
7, 0, 4, 8, 14, 5, 8, 14, 6, 8, 14, 7, 8, 0, 8, 8, 15, 9, 8, 14,10, 8, 0,11,
8, 0,12, 8, 14,13, 8, 15,14, 8, 0,15, 8, 0,16, 8, 12,17, 8, 4,18, 8, 0, 3,
9, 14, 4, 9, 14, 5, 9, 14, 6, 9, 14, 7, 9, 0, 8, 9, 15, 9, 9, 14,10, 9, 0,11,
9, 0,12, 9, 14,13, 9, 15,14, 9, 0,15, 9, 0,16, 9, 12,17, 9, 12,18, 9, 4,19,
9, 0, 2,10, 14, 3,10, 14, 4,10, 14, 5,10, 14, 6,10, 14, 7,10, 0, 8,10, 15,
9,10, 15,10,10, 14,11,10, 14,12,10, 15,13,10, 15,14,10, 0,15,10, 0,16,10,
12,17,10, 12,18,10, 4,19,10, 0, 2,11, 14, 3,11, 14, 4,11, 0, 5,11, 0, 6,11,
0, 7,11, 0, 8,11, 15, 9,11, 15,10,11, 15,11,11, 15,12,11, 15,13,11, 15,14,11,
0,15,11, 0,16,11, 12,17,11, 12,18,11, 4,19,11, 0, 2,12, 14, 3,12, 0, 4,12,
0, 5,12, 0, 6,12, 0, 7,12, 15, 8,12, 15, 9,12, 15,10,12, 15,11,12, 15,12,12,
15,13,12, 15,14,12, 0,15,12, 0,16,12, 12,17,12, 12,18,12, 4,19,12, 0, 3,13,
8, 5,13, 15, 6,13, 15, 7,13, 15, 8,13, 15, 9,13, 15,10,13, 15,11,13, 15,12,13,
15,13,13, 15,14,13, 0,15,13, 0,16,13, 12,17,13, 12,18,13, 4,19,13, 8, 5,14,
15, 6,14, 15, 7,14, 15, 8,14, 15, 9,14, 15,10,14, 15,11,14, 15,12,14, 15,13,14,
0,14,14, 0,15,14, 0,16,14, 12,17,14, 12,18,14, 4,19,14, 8, 6,15, 15, 7,15,
15, 8,15, 15, 9,15, 15,10,15, 15,11,15, 15,12,15, 0,13,15, 0,14,15, 0,15,15,
0,16,15, 12,17,15, 12,18,15, 4,19,15, 8, 7,16, 0, 8,16, 0, 9,16, 0,10,16,
0,11,16, 0,12,16, 0,13,16, 0,14,16, 0,15,16, 0,16,16, 12,17,16, 12,18,16,
4,19,16, 0, 7,17, 0, 8,17, 0, 9,17, 0,10,17, 0,11,17, 0,12,17, 0,13,17,
0,14,17, 0,15,17, 12,16,17, 12,17,17, 12,18,17, 12,19,17, 4,20,17, 0, 7,18,
0, 8,18, 0, 9,18, 0,10,18, 0,11,18, 0,12,18, 0,13,18, 0,14,18, 12,15,18,
12,16,18, 12,17,18, 12,18,18, 12,19,18, 4,20,18, 0, 7,19, 0, 8,19, 0, 9,19,
0,10,19, 0,11,19, 0,12,19, 12,13,19, 12,14,19, 12,15,19, 12,16,19, 12,17,19,
12,18,19, 12,19,19, 12,20,19, 4,21,19, 4, 6,20, 4, 7,20, 4, 8,20, 12, 9,20,
12,10,20, 12,11,20, 12,12,20, 12,13,20, 12,14,20, 12,15,20, 12,16,20, 12,17,20,
12,18,20, 12,19,20, 12,20,20, 4,21,20, 4,22,20, 4,23,20, 4,24,20, 4,25,20,
4, 5,21, 12, 6,21, 12, 7,21, 4, 8,21, 12, 9,21, 12,10,21, 12,11,21, 12,12,21,
94
95
96
y+AnchoIcono-1);
y+AnchoIcono-1);
y+AnchoIcono-1);
y+AnchoIcono-1);
}
/************************************************************************** */
/* Funcion : main
*/
/* Objetivo : El programa inicia siempre por la funcin principal
*/
/************************************************************************** */
void main(){
int Manejador = DETECT, Modo, i, PosXi=25, PosYi=20, Deltax=80, Deltay=70;
initgraph(&Manejador, &Modo, "c:\\tc\\bgi");
cleardevice();
setbkcolor(LIGHTGRAY);
MarcoVentana(2, 2, 637, 477, DARKGRAY, WHITE);
MarcoVentana(4, 4, 635, 475, WHITE, DARKGRAY);
int x=PosXi, y=PosYi;
97
98
10
0
1
2
3
4
5
6
7
8
9 10 11
Observe que la variable cadena se ha dimensionado con LargoCadena+1
posiciones, es decir 10+1=11 posiciones(bytes), debe tener siempre esto en
cuenta, ya que se debe considerar un terminador de nulo, '\0' adicional a la
cadena que se pretenda almacenar en la variable cadena.
Inicialmente se pide se digite una cadena hasta de 10 caracteres de largo,
supongamos que esa cadena es: Cali Valle, en memoria quedar as:
99
cadena
'C''a''l''i'' ''V''a''l''l''e''\0'
0
1
2
3
4
5
6
7
8
9 10
11
longitud
LargoCadena
10
'C''a''l''i'' ''V''a''l''l''e''\0'
0
1
2
3
4
5
6
7
8
9 10
11
longitud
LargoCadena
10
la declaracin de la variable
puntero a caracter, sin darle
ltimo puede ser la ventaja,
el cdigo de programacin como
cadena de
un lmite
pero tiene
es siempre
caracteres se efecta
mximo a la cadena a
el inconveniente del
cuando se trabaja con
100
101
0.1 Se lee una variable, definida como puntero, de cadena de caracteres por
teclado y luego se muestra en pantalla su valor.
//CADENAS2.CPP
#include <iostream.h>
#include <conio.h>
#include <string.h>
#include <stdio.h>
void main(){
char *cadena;
clrscr();
cout << "Digite una cadena de caracteres: ";
gets(cadena);
cout << endl << endl;
cout << cadena << endl;
puts(cadena);//puts escribe cadena y es la instruccin "compaera" de gets
getch();
}
0.2 El siguiente programa presenta, a partir de la lectura de una cadena de
caracteres, su ordenamiento alfabtico ascendentemente. La variable cadena se ha
definido como un puntero a caracter, no reservndole espacio adecuado para
trabajo, es probable que este programa le funcione bien muchas veces, pero alguna
vez le fallar, en especial cuando digita cadenas largas. Insistimos en no
recomendar esta forma de trabajo. Las variables de cadena deben ser definidas
como vectores de caracter, con el dimencionamiento adecuado. Los punteros se
dejan exclusivamente para recibir parmetros en la definicin de funciones.
//CADENAS4.CPP
#include <iostream.h>
#include <string.h>
#include <conio.h>
#include <stdio.h>
void main(){
char *cadena, aux;
int i, j;
clrscr();
cout << "Digite una frase: ";
gets(cadena);
cout << "Longitud cadena = " << strlen(cadena) << "\n\n";
for(i=0; i<strlen(cadena); i++)
for(j = i+1; j<strlen(cadena); j++)
if(cadena[i] > cadena[j]){
aux = cadena[i];
cadena[i] = cadena[j];
cadena[j] = aux;
}
cout << "\"frase ordenada alfabticamente\": \n" ;
puts(cadena);
102
103
30 PROGRAMAS DE APLICACIN
3.1 Ejemplo de funciones varias para manipular cadenas de caracteres. La mayora
vienen incorporadas en el archivo a incluir string.h.
//CADENAS5.CPP
#include
#include
#include
#include
#include
<iostream.h>
<stdlib.h> /* NULL*/
<ctype.h>
<conio.h>
<stdio.h>
while(*cadena){
c++;
cadena++;
}
return c;
}
void AMayusculas(char *cadena){ //similar a strupr de string.h
while (*cadena){
if (*cadena>=97 && *cadena<=122 ) // ASCII: a=97 z=122 A=65
*cadena = *cadena - (97-65);
cadena++;
}
}
void AMinusculas(char *cadena){ //similar a strlwr de string.h
while (*cadena){
if (*cadena>=65 && *cadena<=90 ) // ASCII: A=65 Z=90 a=97
*cadena = *cadena + (97-65);
cadena++;
}
}
void Apropiado(char *s){
while(*s){
*s = toupper(*s);
s++;
while(*s && *s!=' '){
*s = tolower(*s);
s++;
}
while(*s && *s==' ')
s++;
}
}
void CopiarCadena(char *cadena2, char *cadena1){//Copia cadena1 en cadena2
*cadena2 = *cadena1;
while(*cadena1){
cadena2++;
cadena1++;
*cadena2 = *cadena1;
104
}
}
void ConcatenarCadena(char *cadena2, char *cadena1){
//esta funcin es similar a strcat de string.h
while (*cadena2) //Encuentra final de cadena2
cadena2++;
while(*cadena1){
//aade contenido de cadena1 a cadena2
*cadena2 = *cadena1;
cadena2++;
cadena1++;
}
*cadena2 = '\0'; //coloca terminador nulo a la cadena2
}
int CompararCadenas(char *cadena2, char *cadena1){//Similar a strcmp de string.h
int posicion=1; /*de la primera diferencia.*/
while(*cadena1 == *cadena2){
if( *cadena1 == NULL && *cadena2 == NULL)
return 0;
//las cadenas son iguales
cadena1++;
cadena2++;
posicion++;
}
if (*cadena1-1 < *cadena2-1)
posicion = -posicion;
return posicion;
}
int ContarOcurrenciaCaracter(char *cadena, char caracter){
int c=0;
while(*cadena != NULL){
if (*cadena == caracter)
c++;
cadena++;
}
return c;
}
int SustituirCaracterPorOtro(char *cadena, char carviejo, char carnuevo){
int contador=0;
while(*cadena){
if (*cadena == carviejo){
*cadena = carnuevo;
contador++;
}
cadena++;
}
return contador;
}
void main(){
char c1, c2, s2[80], *s1="Esto es una prueba";
105
int pos;
clrscr();
cout << s1;
cout << ": Tiene una longitud de " << longitud(s1) << " caracteres \n";
AMayusculas(s1);
cout << "\n\nEn maysculas fijas es: " <<s1;
AMinusculas(s1);
cout << "\n\nEn minsculas fijas es: " <<s1;
Apropiado(s1);
cout << "\n\nEn forma Apropiada es: " <<s1;
CopiarCadena(s2, s1);
cout << "\n\nCopiado S1 en s2 = "<< s2;
ConcatenarCadena(s2, " de cadenas");
cout << "\n\nConcatenado S2 con un mensaje = " << s2;
getch(); clrscr();
cout
106
107
pos=strlen(CadALeer)-1;
if(CadALeer[0]=='-' || CadALeer[0]=='+'){
Inicio++;
if(CadALeer[0]=='-')
Menos++;
}
for(int i=pos; i>=Inicio; i--){
numero = numero+(int)((CadALeer[i]-'0')*exp );
exp*=10;
}
if(Menos)
numero = -numero;
return numero;
}
3.4 La siguiente funcin, ASCIIaFloat, convierte una cadena de texto en un real,
siempre y cuando lo sea. Reemplaza a la funcin atof(...). Precaucin: No acepta
el caracter e, como en: 5.3e5 . Ver el programa Graph_IO.cpp para su utilizacin.
float ASCIIaFloat(char *CadNumerica) {
int punto=0, LargoCad=0, i=0, Signo=1, PosPunto=0;
float Real, Exponente;
char *c;
while (*CadNumerica == ' '){ // Elimina espacios en blanco al inicio
c=CadNumerica;
while(*c){
*c= *(c+1);
c++;
}
}
c=CadNumerica;
if(*c=='-')
Signo = -1;
if(*c=='+' || *c=='-'){
c++;
LargoCad++;
108
}
while( (*c>='0' && *c<='9') || (*c=='.') ){
LargoCad++;
//Cuenta el nmero de caracteres en la cadena
if(*c=='.'){
punto++;
if(punto>1){
cout <<'\a';return 0;
}
PosPunto=LargoCad-1;
}
c++;
}
if(*c){//No lleg al final de cadena numrica, No es numrico, hay error
cout <<'\a'; return 0;
}
c=CadNumerica;
Real=0;
if(PosPunto>0) //Se digit el punto decimal
i=PosPunto-1;
else
//No se digit un punto decimal
i=LargoCad-1;
Exponente=1;
while(i>=0 && c[i]!='+' && c[i]!='-'){
Real += (c[i]-'0')*Exponente; //Suma valor numrico de parte entera
Exponente *= 10;
i--;
}
if(PosPunto>0){ //Se digit el punto decimal
i=PosPunto+1;
Exponente=0.1;
while(i<LargoCad){
Real += (c[i]-'0')*Exponente;//Suma valor numrico de parte decimal
Exponente /=10.;
i++;
}
}
Real *= Signo;
return (Real);
}
3.5 La siguiente funcin se encarga de capturar una cadena en una posicin de la
pantalla en modo grfico.
int LeerCadena(char *CadALeer,
int x=10, int y=10, int largo=80,
int ColorTexto=BLUE, int ColorFondo=WHITE)
{
int pos=0, fin=0, LongCar, AltoCar, Terminar=0, L, i, Insertar=1;
struct textsettingstype AnteriorTexto;
struct viewporttype Vista;
char Tecla;
getviewsettings(&Vista); gettextsettings(&AnteriorTexto);
109
110
else
cout << '\a';
}
}
}
else{ // tecla de secuencia de ESC. Tecla es igual a 0 en primer byte
Tecla = getch();
// lee el segundo byte
switch (Tecla) {
case Home: pos=0; break;
case AltX: Terminar = 1; exit(0); //Alt+X aborta el programa
case End : pos=fin; break;
case Ins : if(Insertar) Insertar=0; //Modo se insercin
else Insertar=1;
break;
case Del: i = pos;//pos queda en el mismo sitio, a medida que borra
while(i<=fin){
CadALeer[i] = CadALeer[i+1];
i++;
}
fin--;
break;
case Izq: if (pos > 0) {
pos--;
} else cout <<"\a";
break;
case Der: if(pos>=largo-1)
cout<< "\a";
else{
if(pos >= fin){
fin++;
CadALeer[pos]=Espacio;
CadALeer[fin+1]=Nulo;
}
pos++;
}
break;
//Tecla Derecha. Que no haga nada
case CtrlIzq: ;
case CtrlDer: ;
default: cout<< "\a";
}
}
bar(x,y,x+LongCar*largo,y+AltoCar); //barra en que se escribe
rectangle(x-1,y-1,x+LongCar*largo+1,y+AltoCar+1);
if ( (pos < largo) && !Terminar)
outtextxy(x+(pos*LongCar),y+1,"_");
outtextxy(x, y+1, CadALeer);
} while (!Terminar);
while(CadALeer[fin-1]==Espacio){//Se eliminarn espacios blancos al final
CadALeer[fin]=Nulo; //se corre el nulo
fin--;
}
while(CadALeer[0]==Espacio){ //Se eliminarn espacios en blanco al inicio
i = 0;
while(i<=fin){
CadALeer[i] = CadALeer[i+1];
i++;
111
}
fin--;
}
bar(x,y,x+LongCar*largo,y+AltoCar); //barra en que se escribe
rectangle(x-1,y-1,x+LongCar*largo+1,y+AltoCar+1);
outtextxy(x, y+1, CadALeer); //Se reescribe sin espacios al inicio y final
//Restaura las condiciones antes de antes de entrar a esta funcin
settextstyle(AnteriorTexto.font,AnteriorTexto.direction,AnteriorTexto.charsize);
settextjustify(AnteriorTexto.horiz, AnteriorTexto.vert);
return fin; // retorna el largo de la cadena
}
PROGRAMA A REALIZAR COMO EJERCICIO
1. En el programa de las ventanas realizado en el captulo sobre pilas y con la
ayuda de la funcin LeerCadena presentada en este captulo y en el programa
IO_Graph.CPP, permita efectuar lectura de varias lineas en cada ventana. Numere
cada una de las ventanas en orden ascendente a medida que se van creando. El
texto que se digite en cada ventana debe poder ser actualizado a voluntad en el
nmero de ventana que se desee. El texto debe ser reescrito adecuadamente en cada
ventana cuando se retire una ventana que lo estaba tapando. Efecte los cambios
necesarios para utilizar el programa IO_Graph.CPP como archivo a incluir.
2. En todos los proyectos a presentar en este curso no utilice la librera
String.H, en su lugar emplee las funciones dadas en este captulo, las que le
faltaren elabore el correspondiente algoritmo en lenguaje C y utilcelas. Cree un
archivo a incluir dentro de su proyecto con ellas.
112
113
114
115
116
}
return;
}
//---------------------------------------------------------------------------double Sacar(double *P){
double item;
if (CimaNum) {
item = *CimaNum;
if (CimaNum == P) /* Era el ltimo elemento*/
CimaNum = Nulo;
else
CimaNum--;
}
return item;
}
//---------------------------------------------------------------------------int ConvertirInfijaAPostfija(char *Infija, char *Postfija){
char *Op=" \x0";
int Digito=0; //saber si el anterior(es) ha sido numrico(incluye punto)
int Punto=0; //para saber si un nmero tiene ms de un punto
int ParDer=0; //solucionar casos como: -(-3, con memos unario
CimaChar= Nulo;
ConcatenarCadenas(Infija, ")");
AsignarCadena(Postfija, "");
Meter(PilaChar, '(');
while(*Infija){
if(!CaracterValido(*Infija)) return 0;
if (EsNumerico(*Infija)){
if(*Infija=='.'){
if(Punto) return 0; //ya hay un punto, no es un # vlido
Punto++; // cuenta solo el primer punto
}
if(!Digito && *Infija=='.')
ConcatenarCadenas(Postfija, "0");
Digito=1;
Op[0] = Infija[0];
ConcatenarCadenas(Postfija, Op);
}
else{
if(Digito) {
if( *Infija==' ' && EsNumerico( *(Infija+1) ) )
return 0;
ConcatenarCadenas(Postfija, " ");
Digito=0;
Punto=0;
}
if (*Infija == '('){
Meter(PilaChar, '('); ParDer=1;
}
else
if (EsOperador(*Infija)){
if (!ParDer){
while( PriorizarOperadores(*CimaChar, *Infija)){
//Si el operador en PilaChar es mayor o igual en presedencia
Op[0] = Sacar(PilaChar);
ConcatenarCadenas(Postfija, Op );//se concatena con Postfija
117
118
}//if-else
}//while
return(Sacar(PilaNum));
}
//---------------------------------------------------------------------------void main(){
char Infija[Max], Postfija[Max];
clrscr();
puts("Los operadores pueden ser + - / * ^ ");
puts("Puede dejar espacios en blanco entre operandos y operador\n");
puts("En expresiones como: 2 ^ -1
digite como 2^(-1)");
puts("
2 ^ -1.1 digite como 2^(-1.1)" );
puts("NOTA: los menos unarios sern convertidos al caracter _");
puts("Digite expresin algebraica en Infija: ");
gets(Infija);
if(ConvertirInfijaAPostfija(Infija,Postfija) ){
cout <<"\nExpresin correspondiente en Postfija: ";
puts(Postfija);
cout <<"\n\nResultado = " << EvaluarPostfija(Postfija);
}
else
puts("\nError en expresin Infija");
while(!kbhit());
}//Fin main()
//-----------------------------------------------------------------------------
119
120
<IOStream.H>
<ConIo.H>
<StdLib.H>
<StdIO.H>
//=============================================================================/
/Definicin de prototipos de todas las funciones utilizadas
char AMayuscula(char c);
char AMinuscula(char c);
void AMinusculas(char *c);
void EsperarTecla();
int EstaEn(char Caracter, char *CaracteresValidos);
int LongitudCadena(char *cadena);
int ASCIIaInt(char *CadALeer);
void AsignarCadena(char *cadena2, char *cadena1);
int CompararCadenas(char *cadena1, char *cadena2);
//-----------------------------------------------------------------------------void AnalizarExpresionLogica();
//Funcin sobrecargada
void AnalizarExpresionLogica(int *Valor);
void MostrarNumeroError(int NumError);
void ObtenerOperadorOR(int *Valor);
void ObtenerOperadorAND(int *Valor);
void ObtenerOperadorNOT(int *Valor);
void ObtenerParentesisIzquierdo(int *Valor);
int ObtenerValorPrimitivo(int *Valor);
void DeterminarOperador(char Operador, int *Operando1, int *Operando2);
void LeerLeyesDeDeMorgan();
void TransformarExpresionLogica();
int
ObtenerSimbolo();
void main();
//=============================================================================/
/DEFINICION DE VARIABLES GLOBALES:
char Expresion[80];
char Simbolo[80];
char *Pos;
char CarValidos[10];
//=============================================================================
char AMayuscula(char c){
if(c>=97 && c<=122)
c -= (97-65);
return c;
}
//--------------------------------------------------------------------------char AMinuscula(char c){
if(c>=65 && c<=90)
c += (97-65);
return c;
}
//--------------------------------------------------------------------------//esta funcion reemplaza a strlwr de la librera string.h
121
122
*cadena2 = *cadena1;
cadena2++;
cadena1++;
}
*cadena2 = *cadena1;
123
ObtenerOperadorOR(Valor);
}
//--------------------------------------------------------------------------void MostrarNumeroError(int NumError){
static char *MensajeError[]={"Error de sintasis",
"Parntesis desequilibrado",
"Ninguna Expresion presente"
};
cout << MensajeError[NumError] << endl;
}
//--------------------------------------------------------------------------void ObtenerOperadorOR(int *Valor){
char op;
int Mantiene;
ObtenerOperadorAND(Valor);
while( (op = *Simbolo) == '|') {
ObtenerSimbolo();
ObtenerOperadorAND(&Mantiene);
DeterminarOperador(op, Valor, &Mantiene);
}
}
//--------------------------------------------------------------------------void ObtenerOperadorAND(int *Valor){
char op;
int Mantiene;
ObtenerOperadorNOT(Valor);
while( (op = *Simbolo) == '&') {
ObtenerSimbolo();
ObtenerOperadorNOT(&Mantiene);
DeterminarOperador(op, Valor, &Mantiene);
}
}
//--------------------------------------------------------------------------void ObtenerOperadorNOT(int *Valor){
char op;
op = 0;
if( *Simbolo == '!') {
op = '!';
ObtenerSimbolo();
}
ObtenerParentesisIzquierdo(Valor);
if(op)
DeterminarOperador(op, Valor, Valor);
}
//--------------------------------------------------------------------------void ObtenerParentesisIzquierdo(int *Valor){
if( *Simbolo == '(') {
ObtenerSimbolo();
ObtenerOperadorOR(Valor);
if( *Simbolo != ')')
MostrarNumeroError(1);
ObtenerSimbolo();
124
}
else
ObtenerValorPrimitivo(Valor);
}
//--------------------------------------------------------------------------int ObtenerValorPrimitivo(int *Valor){
int i;
if( EstaEn(*Simbolo, "01d") ){
if( *Simbolo == 'd')
*Valor = 'd';
else
*Valor = ASCIIaInt(Simbolo);
return ObtenerSimbolo();
}
MostrarNumeroError(0); //Error en sintaxis de expresion
}
//--------------------------------------------------------------------------void DeterminarOperador(char Operador, int *Operando1, int *Operando2){
switch(Operador){
case '&': if(*Operando1 != 'd' && *Operando2 != 'd'){
*Operando1 = *Operando1 && *Operando2;
return;
}
if(*Operando1 == 'd' && *Operando2 == 0)
*Operando1 = 0;
else
if(*Operando1 == 0 && *Operando2 == 'd')
*Operando1 = 0;
else
*Operando1 = 'd';
break;
case '|': if(*Operando1 != 'd' && *Operando2 != 'd'){
*Operando1 = *Operando1 || *Operando2;
return;
}
if(*Operando1 == 1 || *Operando2 == 1)
*Operando1 = 1;
else
*Operando1 = 'd';
break;
case '!': if(*Operando1 != 'd')
*Operando1 = !*Operando1;
else
*Operando1 = 'd';
break;
}
}
//--------------------------------------------------------------------------void LeerLeyesDeDeMorgan(){
AsignarCadena(CarValidos, "()");
clrscr();
cout << "Las reglas de De Morgan son : \n";
cout << "
no (P y Q) => no P o no Q \n";
cout << "
no (P o Q) => no P y no Q \n";
125
cout << "Digite una de las cuatro expresiones mostradas antes \n";
gets(Expresion);
if(*Expresion){
AMinusculas(Expresion);
cout << Expresion << endl;
Pos = Expresion;
TransformarExpresionLogica();
EsperarTecla();
}
}
//--------------------------------------------------------------------------void TransformarExpresionLogica(){
char p[80], q[80], s[4], EsY;
//Teoremas de De Morgan en forma inversa : \n";
//
~ P o ~ Q => ~ (P y Q)
//
~ P y ~ Q => ~ (P o Q)
Pos = Expresion; // se reinicializa
ObtenerSimbolo();
if(!CompararCadenas(Simbolo, "no") ){
ObtenerSimbolo();
AsignarCadena(p, Simbolo);
ObtenerSimbolo();
if(!CompararCadenas(Simbolo, "y") )
EsY = 1;
else
EsY = 0;
ObtenerSimbolo();
if(!CompararCadenas(Simbolo, "no") ){
ObtenerSimbolo();
AsignarCadena(q, Simbolo);
if(EsY)
AsignarCadena(s, "o");
else
AsignarCadena(s, "y");
cout << "\n\nno (" << (char)AMayuscula(p[0])
<< " " << s << " " << (char)AMayuscula(q[0]) << ")";
return;
}
}
//Teoremas de De Morgan son : \n";
//
~ (P y Q) => ~ P o ~ Q
//
~ (P o Q) => ~ P y ~ Q
Pos = Expresion;
ObtenerSimbolo();
if(!CompararCadenas(Simbolo, "no") ){
ObtenerSimbolo();
if(*Simbolo=='(') {
ObtenerSimbolo();
AsignarCadena(p, Simbolo);
ObtenerSimbolo();
if(!CompararCadenas(Simbolo, "y") )
EsY = 1;
else
126
EsY = 0;
ObtenerSimbolo();
AsignarCadena(q, Simbolo);
ObtenerSimbolo();
if(*Simbolo, ")") { //Es una expresion v lida de De Morgan
if(EsY)
AsignarCadena(s, "o");
else
AsignarCadena(s, "y");
cout << "\n\nno " << (char)AMayuscula(p[0])
<< " " << s << " no " << (char)AMayuscula(q[0]);
return;
}
}
}
Pos = Expresion; // Se reinicializa
cout << "\n\nTautologa no implementada o mal escrita \a\a";
return;
}
//--------------------------------------------------------------------------int
ObtenerSimbolo(){
char *p;
p = Simbolo;
while(*Pos==' ') Pos++; //Salta espacios en blanco al inicio
if(*Pos == '\0') { // es el final de la entrada
*p++ = '\0';
return 0;
}
if(EstaEn(*Pos, CarValidos) ) {
*p = *Pos;
p++;
Pos++;
*p = '\0';
return 1;
}
//Avanza caracteres hasta encontrar un espacio o parntesis,
// determinando una palabra
while(*Pos != ' ' && !EstaEn(*Pos, CarValidos) ) {
*p = *Pos;
Pos++;
p++;
}
*p = '\0';
return 0;
}
//--------------------------------------------------------------------------void main(){
char opcion;
do{
clrscr();
cout << " 1. Analizar expresion logica
\n";
cout << " 2. Verificar leyes de De Morgan \n";
cout << "Esc. para terminar el programa
\n";
127
opcion = getch();
switch(opcion){
case '1': AnalizarExpresionLogica(); break;
case '2': LeerLeyesDeDeMorgan(); break;
}
}while(opcion != 27);
}
//=============================================================================
128
COMPARACIN DE ORDENAMIENTOS
1. INTRODUCCIN
En el siguiente programa, podr observar una comparacin grfica entre los
algoritmos de ordenamiento: Merge Sort con recursin, Sorteo por Seleccin
Recursiva, QuickSort con recursin y el tradicional y psimo de Burbuja en forma
iterativa. Lo anterior no quiere decir que los algoritmos recursivos sean ms
rpidos. No, todo lo contrario. Las versiones iterativos de los mismos degen
trabajar ms rpido que los presentados en este programa.
2. EL PROGRAMA
/****************************************************************************/
#include<Graphics.h>
#include <StrStream.H>
#include <StdLib.H>
#include<ConIO.h>
#include <DOS.h>
#include <Time.H>
/****************************************************************************/
//Prototipos de funciones principales
void MergeSort(int *Vector, int Izq, int Der);
void SorteoPorSeleccionRecursiva(int *Vector, int i, int N);
void QuickSort(int *Vector, int Izq, int Der);
void Burbuja(int *Vector, int N);
void GraficarValores(int *Datos, int N, int PosA, int PosB, int Retardo=0);
/****************************************************************************/
const Max = 312; //Tamao del vector.
int N=0;
//Si lo aumenta de 314, la escala de las barras no queda bien.
const Entrar=13, Retroceso=8, CtrlC=3, Tab=9, Esc=27, Espacio=32, Nulo='\0';
const Home=71, Izq=75, AltX=45, Der=77, End=79, Ins=82,
Del=83, CtrlIzq=115, CtrlDer=116;
//***************************************************************************
void MergeSort (int *Vector, int Izq, int Der){
int i, j, k, Medio;
int b[Max];
if(Der>Izq){
Medio = (Der+Izq) >> 1;
MergeSort(Vector, Izq, Medio);
MergeSort(Vector, Medio+1, Der);
for(i = Medio+1; i>Izq; i--)
b[i-1] = Vector[i-1];
for(j = Medio; j < Der; j++)
b[Der+Medio-j] = Vector[j+1];
for(k = Izq; k <= Der; k++){
Vector[k] = (b[i]<b[j])? b[i++]:b[j--];
GraficarValores(Vector, N, k, j);
}
}
}
/****************************************************************************/
void SorteoPorSeleccionRecursiva (int *Vector, int i, int N)
{
int j, PosMenor;
int Aux;
129
if(i<N-1){
PosMenor = i;
for(j=i+1; j<N; j++)
if(Vector[j] < Vector[PosMenor])
PosMenor = j;
Aux = Vector[PosMenor];
Vector[PosMenor] = Vector[i];
Vector[i] = Aux;
GraficarValores(Vector, N, PosMenor, i);
SorteoPorSeleccionRecursiva(Vector, i+1, N);
}
}
/****************************************************************************/
void QuickSort (int *Vector, //Clasificacin r pida
int Izq,
int Der)
{
int izq=Izq, der=Der;
int pivote, aux;
pivote = Vector[(Izq+Der)/2];
do{
while (Vector[izq] < pivote)
izq++;
while (pivote < Vector[der])
der--;
if(izq <= der) {
aux = Vector[izq];
Vector[izq] = Vector[der];
Vector[der] = aux;
GraficarValores(Vector, N, izq, der);
izq++;
der--;
}
} while(izq < der);
if(Izq < der)
QuickSort(Vector, Izq, der);
if(izq < Der)
QuickSort(Vector, izq, Der);
}
/****************************************************************************/
void Burbuja (int *Vector, int N){
int i, j;
int Aux;
for(i=0; i<N-1; i++)
for(j=0; j<N-i; j++)
if(Vector[j] > Vector[j+1]){
Aux = Vector[j];
Vector[j] = Vector[j+1];
Vector[j+1] = Aux;
GraficarValores(Vector, N, j, j+1);
}
}
/* **************************************************************************/
/* Funcin
: CentrarXCad
*/
/* Objetivo : Esta funcin se encarga de Escribir una cadena
*/
130
/*
centrada en la pantalla en modo gr fico
*/
/****************************************************************************/
void CentrarXCad(int Fila, char *Cad, int Color){
int largo;
setcolor(Color);
largo = textwidth(Cad); outtextxy((getmaxx()-largo)/2,Fila,Cad);
}
/****************************************************************************/
void GraficarValores(int *Datos,
int N,
int PosA,
int PosB,
int Retardo)
{
int i, Izquierda, Arriba=5, ArribaBar, Ancho, Abajo, Eje=10, MayorValor=0;
float Fraccion, Delta;
if( N ){
MayorValor=Datos[0];
for( i=1; i<N; i++)
if(Datos[i]>MayorValor)
MayorValor = Datos[i];
Ancho = (int)( (getmaxx()-Eje) / ((N * 2 ) + 1) );
Abajo = getmaxy() - 40;
Izquierda = Ancho+Eje;
Delta= (float)(Abajo-Arriba+1)/MayorValor;
if(PosA==-1 || PosB==-1){
setcolor(WHITE); line(Eje/2, Arriba, Eje/2, Abajo); //Eje y
for(float rayita=Abajo; rayita>=Arriba-Delta; rayita-=Delta)
line(3, (int)rayita, 7, (int)rayita);
for( i=0; i<N; i++){
Fraccion = (float) Datos[i] / MayorValor;
ArribaBar = (int)(Abajo - Fraccion * (Abajo-Arriba) );
setcolor(RED); setfillstyle(SOLID_FILL, MAGENTA);
bar(Izquierda, ArribaBar, (Izquierda + Ancho), Abajo);
Izquierda += (Ancho * 2);
}
}
else
for( i=0; i<N; i++){
if(PosA==i || PosB==i){
Fraccion = (float) Datos[i] / MayorValor;
ArribaBar = (int)(Abajo - Fraccion * (AbajoArriba) );
setcolor(RED); setfillstyle(SOLID_FILL, MAGENTA);
bar(Izquierda, ArribaBar, (Izquierda + Ancho),
Abajo);
setfillstyle(SOLID_FILL, BLUE);
bar(Izquierda, Arriba, (Izquierda + Ancho),
ArribaBar);
}
Izquierda += (Ancho * 2);
}
delay(Retardo);
}
else{
131
132
/****************************************************************************/
/* Funcin : MarcoVentana
*/
/* Objetivo : Dibujar un ReCuadro resaltado o undido.
*/
/****************************************************************************/
void RecuadroVentana(int X1,int Y1,int X2,int Y2,int ArbAbj){
EsconderCursorMouse();
setlinestyle(SOLID_LINE,0,NORM_WIDTH);
if(ArbAbj == 1)
setcolor(DARKGRAY);
else
setcolor(WHITE);
line(X1, Y1, X1, Y2);
line(X1, Y1, X2, Y1);
if(ArbAbj == 1)
setcolor(WHITE);
else
setcolor(DARKGRAY);
line(X2, Y1, X2, Y2);
line(X1, Y2, X2, Y2);
MostrarCursorMouse();
}
/****************************************************************************/
/* FUNCION
: RealzarCursor
*/
/* OBJETIVO : Muestra un rectangulo en pantalla, el cual significa
*/
/*
una de las opciones de un men.
*/
/****************************************************************************/
void RealzarCursor(int x1,int y1,int x2,int y2,int Color1,int Color2,int Color3)
{
EsconderCursorMouse();
setcolor(Color1);line(x1,y1,x2,y1); line(x1,y1,x1,y2);
setcolor(Color2);line(x1,y2,x2,y2); line(x2,y2,x2,y1);
setcolor(Color3);line(x1+1,y1+1,x2-1,y1+1);line(x1+1,y1+1,x1+1,y2-1);
line(x1+1,y2-1,x2-1,y2-1);line(x2-1,y2-1,x2-1,y1+1);
setfillstyle(1,Color3); floodfill(x1+5,y1+5,Color3);
setcolor(Color2); line(x1+1,y2-1,x2-1,y2-1); line(x2-1,y2-1,x2-1,y1+1);
MostrarCursorMouse();
}
/****************************************************************************/
/* Funcin : Cursor
*/
/* Objetivo : Realiza recuadro, con una cadena centrada en su interior,
*/
/****************************************************************************/
void Cursor(int X, int Y, int LargoCuadro, char *Cad,
int Col1,int Col2,int Col3,int Col4,int
Col5,int Oprimido){
int AltoCuadro;
char c[3];
EsconderCursorMouse();
settextstyle(DEFAULT_FONT,HORIZ_DIR,1);
AltoCuadro=textheight(Cad) + 10;
if(LargoCuadro==0)
LargoCuadro = X + textwidth(Cad) + 10;
else
LargoCuadro = X + LargoCuadro + 10;
if(!Oprimido){
BarraDeColor(X,Y,LargoCuadro,Y+AltoCuadro,SOLID_FILL,Col1);
RecuadroVentana(X,Y,LargoCuadro,Y+AltoCuadro,1);
setcolor(Col3);
}
133
else{
BarraDeColor(X,Y,LargoCuadro,Y+AltoCuadro,SOLID_FILL,Col2);
RecuadroVentana(X,Y,LargoCuadro,Y+AltoCuadro,1);
setcolor(Col4);
}
outtextxy(X+5,Y+5,Cad);
setcolor(Col5);
c[0] = Cad[0];
outtextxy(X+5,Y+5,c);
MostrarCursorMouse();
c[1] ='\0';
}
/**************************************************************************/
/* Funcin : PulsadoCuadro
*/
/* Objetivo : Realiza Cursor con una cadena centrada en su
*/
/*
interior y da la sensacion de que se oprime.
*/
/**************************************************************************/
void UndidoCursor(int X,int Y,int LargoCadenaMayor,
char *Cad, int Col1, int Col2, int
Col3, int Col4, int Col5){
const NoActual=0, Actual=1;
EsconderCursorMouse();
Cursor(X, Y, LargoCadenaMayor,Cad, Col1, Col2, Col3, Col4,
Col5, NoActual
);
delay(100);
Cursor(X, Y, LargoCadenaMayor,Cad, Col1, Col2, Col3, Col4, Col5, Actual );
delay(100);
Cursor(X, Y, LargoCadenaMayor,Cad, Col1, Col2, Col3, Col4, Col5,
NoActual);
MostrarCursorMouse();
}
/* *********************************************************************** */
/* Funcin : AMAYUSCULA
*/
/* Objetivo : Convierte un caracter en minscula a mayscula.
*/
/* *********************************************************************** */
char AMayuscula(char c){
if(c>=97 && c<=122)
c -= (97-65);
return c;
}
/* ************************************************************************
/* Funcin : EscribirComentarioOpcionMenu
/* Objetivo : Muestra avisos correspondientes a opciones del men
/* ************************************************************************
void EscribirComentarioOpcionMenu(char *Comentario,
*/
*/
*/
*/
EsconderCursorMouse();
RealzarCursor(Xo, Yo, Xf, Yf, DARKGRAY, WHITE, BLUE);
setfillstyle(SOLID_FILL, BLUE);
bar(Xo+4, Yo+4, Xf-4, Yf-2);
settextstyle(DEFAULT_FONT, 0, 1);
CentrarXCad(Yo+5, Comentario, WHITE);
MostrarCursorMouse();
}
/****************************************************************************/
134
void PresentacionInicial(){
EsconderCursorMouse();
setcolor(WHITE); rectangle(0,0,getmaxx(),getmaxy());
RealzarCursor(170,110,480,370,WHITE,DARKGRAY,LIGHTGRAY);
RealzarCursor(16,20,624,435,WHITE,DARKGRAY,LIGHTGRAY);
RealzarCursor(55,60,585,400,DARKGRAY,WHITE,LIGHTGRAY);
RealzarCursor(58,63,582,397,WHITE,DARKGRAY,LIGHTGRAY);
setcolor(11);
for(int i=170;i<480;i+=5)
line(325,240,i,110);
setcolor(14);
for(i=170;i<479;i+=3)
line(170,110,i,368);
setcolor(15);
for(int j=110;j<379;j+=20) line(325,240,478,j);
CentrarXCad(150,"ITESM", BLACK);
CentrarXCad(190,"CIENCIAS DE LA COMPUTACION", BLACK);
CentrarXCad(230,"ANALISIS DE ALGORITMOS", RED);
CentrarXCad(270,"GRUPO 21", MAGENTA);
CentrarXCad(310,"Noviembre-2000", BLACK);
MostrarCursorMouse();
}
/* *********************************************************************** */
/*
FUNCION PRINCIPAL
*/
/* *********************************************************************** */
void main(){
const Der=77, Izq=75, Esc=27, Entrar=13, MaxOp=5,
NoActual=0, Actual=1, DeMas=12;
int Pos=0, Invocar=1,
i, Fila=442, Xm=320, Ym=Fila-20,
Click, PosX[MaxOp], AnchoCursor=0;
int Vector[Max], Aux[Max];
char Tecla, Cad[80],
Op[MaxOp][20]={"Random", "Seleccin","QuickSort","MergeSort","Burbuja"},
Comentario[MaxOp][80]={
"Generar al azar valores para vector",
"Algoritmo de Sorteo por Seleccin con Recursin",
"Algoritmo de Sorteo del QuickSort Recursivo",
"Algoritmo de Sorteo por fusin de sublistas",
"Algoritmo de Ordenamiento de Burbuja" };
clock_t TiempoInicial, TiempoFinal;//ver Time.h
int Manejador = DETECT, Modo;
initgraph (&Manejador, &Modo, "\\tc\\bgi");
setbkcolor(BLUE);
if(!IniciarMouse(Click)){
outtextxy(10,10,"El ratn NO est
delay(2000);
return;
}
CursorMouseAXY(Xm, Ym);
PresentacionInicial();
settextstyle(DEFAULT_FONT,HORIZ_DIR,0);
settextjustify(LEFT_TEXT,TOP_TEXT);
instalado");
for(i=0;i<MaxOp;i++)
AnchoCursor += textwidth(Op[i])+DeMas;
PosX[0] = (getmaxx()-AnchoCursor)/2;
for(i=1;i<MaxOp;i++)
PosX[i] = PosX[i-1]+textwidth(Op[i-1])+DeMas;
EscribirComentarioOpcionMenu(Comentario[Pos]);
for(i=0; i<MaxOp; i++)
Cursor(PosX[i],Fila,0,Op[i],LIGHTGRAY,CYAN,WHITE,WHITE,RED, NoActual);
Cursor(PosX[Pos],Fila,0,Op[Pos],LIGHTGRAY,CYAN,WHITE,WHITE,RED,Actual);
Invocar = 0;
135
Xm=PosX[Pos]+1;
Ym=Fila+DeMas;
for(;;){
if(Invocar){
EscribirComentarioOpcionMenu(Comentario[Pos]);
for(i=0; i<MaxOp; i++)
Cursor(PosX[i],Fila,0, Op[i], LIGHTGRAY, CYAN, WHITE,
WHITE, RED, NoActual);
Cursor(PosX[Pos],Fila,0,Op[Pos], LIGHTGRAY, CYAN, WHITE,
WHITE, RED, Actual);
Invocar = 0;
Xm=PosX[Pos]+1;
Ym=Fila+DeMas;
}
MostrarCursorMouse();
do{
Click = ClickMouseEnXY(Xm,Ym);
if(Ym>=Fila && Ym<=Fila+textheight("H")+10){
i=0;
while(i<MaxOp && !(Xm>PosX[i] &&
Xm<PosX[i]+textwidth(Op[i])+DeMas))
i++;
if(i<MaxOp){
if(Click)//
Se hizo "click" en recuadro del men
Invocar = 1;
if(i!=Pos){
Cursor(PosX[Pos],Fila,0,Op[Pos], LIGHTGRAY,
CYAN, WHITE, WHITE, RED,NoActual);
Pos=i;
EscribirComentarioOpcionMenu(Comentario[Pos]);
Cursor(PosX[Pos],Fila,0,Op[Pos], LIGHTGRAY,
CYAN, WHITE, WHITE, RED,Actual);
}
}
}
} while (!kbhit() && !Click);
if(!Click){ //Se digit del teclado
Tecla = getch();
if(Tecla == 0 ){
Tecla = getch();
switch(Tecla){
case Der:
Cursor(PosX[Pos],Fila,0,Op[Pos], LIGHTGRAY,
CYAN, WHITE, WHITE, RED,NoActual);
EscribirComentarioOpcionMenu(Comentario[Pos]);
Pos++;
if(Pos == MaxOp) Pos=0;
EscribirComentarioOpcionMenu(Comentario[Pos]);
Cursor(PosX[Pos],Fila,0,Op[Pos], LIGHTGRAY,
CYAN, WHITE, WHITE, RED,Actual);
break;
case Izq:
Cursor(PosX[Pos],Fila,0,Op[Pos], LIGHTGRAY,
CYAN, WHITE, WHITE, RED,NoActual);
136
EscribirComentarioOpcionMenu(Comentario[Pos]);
Pos--;
if(Pos == -1)
Pos = MaxOp-1;
EscribirComentarioOpcionMenu(Comentario[Pos]);
Cursor(PosX[Pos],Fila,0,Op[Pos], LIGHTGRAY,
CYAN, WHITE, WHITE, RED,Actual);
break;
case 45: return; //
Alt-X
case 59:
//F1
break;
}
}
else{
EscribirComentarioOpcionMenu(Comentario[Pos]);
Cursor(PosX[Pos],Fila,0,Op[Pos],
LIGHTGRAY, CYAN, WHITE, WHITE,
RED,NoActual);
Pos=i;
Cursor(PosX[Pos],Fila,0,Op[Pos],
LIGHTGRAY, CYAN, WHITE, WHITE,
RED,Actual);
}
Invocar=1;
}
}
}
}
if(Invocar){
UndidoCursor(PosX[Pos],Fila,0,Op[Pos],
LIGHTGRAY, CYAN, WHITE, 15, RED);
EsconderCursorMouse();
setfillstyle(SOLID_FILL, BLUE);
bar(1,1, 638, Fila-2);
setcolor(WHITE); rectangle(1,1, 638, Fila-2);
switch(Pos){
case 0:randomize();
for(int j=0; j<Max; j++){
Vector[j] = random(100)+1;
Aux[j] = Vector[j];
}
N=Max;
GraficarValores(Vector, N, -1, -1);
setfillstyle(SOLID_FILL, BLUE);
bar(getmaxx()-111, getmaxy()-31,
getmaxx()-1, getmaxy()-1);
setcolor(YELLOW);
137
case
case
case
case
138
}
}
/****************************************************************************/
139
SEGUNDA PARTE
ESTRUCTURAS AUTOREFERENCIADAS.
LISTAS ENLAZADAS.
VARIABLES EN MEMORIA DINAMICA.
EDUCACION LIBERADORA
En la educacin hay que poner el
acento en el amor, no en el temor:
"Procura ms bien hacerte amar,
que hacerte temer".
(San Juan Bosco.)
El amor nos da personas
sinceras, el temor incita a mentir y
acaba con la confianza.
El amor inpulsa a nios y
jovenes a ser decididos, y positivos;
el temor engendra seres
acomplejados y pesimistas.
Quien educa con el amor sabe
corregir e imponer sanciones sin
injusticias, amenazas, ni malos
tratos.
En la educacin hay que poner el
acento en la autonoma, no en la
dependencia. Se educa para liberar
no para esclavizar.
Una educacin liberadora forma
al individuo desde nio para que
tome decisiones y sea artfice de su
vida.
Supone trazar lmites, pero no
aquellos que brotan de la
sobreproteccin, el egosmo o los
celos.
Implica saber correr riesgos y no
tener a los seres como posesin.
Eduquemos para una libertad responsable.
GONZALO GALLO GONZALEZ
"CUATRO AMORES"
140
Primera Parte
Segunda Parte
Tercera Parte
141
0x1000
0x1000
la
new a asignado el valor entero de 0x1000, esto es solo una suposicin para
explicar lo ocurrido, al puntero Cima. Diremos que Cima vale 0x1000. De esta
forma Cima apunta a la direccin de memoria, en RAM, de 0x1000; en esta direccin
y con un desplazamiento (offset) en bytes dado por el tamao de struct PILA. En
este momento las posiciones de memoria que inician en 0x1000 tendrn "basura". Se
deber proceder a asignar informacin al campo de Info y al puntero ant, por
medio de alguna operacin adecuada.
142
Cima
0x1000
0x1000
Carolina
16
1.56
NULL
Cima
0x1000
0x1000
Carolina
16
1.56
NULL
0x1050
Tania
23
1.55
NULL
Nuevo
0x1050
Para efectuar el enlace de este nuevo nodo y que quede la lista enlazada
representando una pila, procedemos por medio de la siguiente instruccin:
Nuevo->Ant = Cima;
Cima
0x1000
Carolina
0x1050
Tania
Nuevo
143
0x1000
16
1.56
NULL
23
1.55
0x1000
0x1050
Cima
0x1050
0x1050
Tania
23
1.55
0x1000
0x1000
Carolina
16
1.56
NULL
Nuevo
0x1050
144
Cima
0x1100
0x1100
Valentina
0.75
0x1050
0x1050
Tania
23
1.55
0x1000
0x1000
Carolina
16
1.56
NULL
Nuevo
0x1100
Cima
0x1050
Aux
0x1100
0x1100
Valentina
0.75
0x1050
0x1050
Tania
23
1.55
0x1000
0x1000
Carolina
16
1.56
NULL
Cima
0x1050
0x1050
Tania
23
1.55
0x1000
0x1000
Carolina
16
1.56
NULL
145
un
nodo
de
la
pila
Sacar(){
PILA *Aux;
if(Cima){
Aux = Cima;
cout << "Eliminado el nodo de la persona: " << Cima->Info,Nombre << " de
la cima de la pila" << endl;
delete(Aux);
}
else
cout << "Pila est vaca";
}
4. FUNCION LISTAR ELEMENTOS EN PILA
Aunque estrictamente, siendo dogmticos, solo se debe tener acceso al elemento en
la cima de la pila, a continuacin mostramos cdigo para recorrer la lista
enlazada en la que est la pila:
ListarPila(){
Pila *p;
int N=0;
if(Cima){
p = Cima;
while (p){
N++;
cout <<p->Info.Nombre <<" tiene " <<p->Info.Edad <<" aos" << endl;
p = p->Ant;
}
cout << "En pila existen " << N << " elementos en espera\n";
}
else
cout << "Pila est vaca";
}
5. PROGRAMA DE EJEMPLO DE ESTRUCTURA DE DATOS PILA
El siguiente programa, PILALIST.CPP, implementa la estructura de datos pila como
una lista simplemente enlazada en memoria dinmica. Observe los cambios
efectuados en las funciones bsicas, buscando una mayor generalidad del cdigo y
evitar repeticiones en el mismo.
#include
#include
#include
#include
#include
#include
#include
<iostream.h>
<iomanip.h>
<fstream.h>
<conio.h>
<stdio.h>
<cadenas.h>
<graphics.h>
146
char Titulo[20];
char Autor[15];
char Cota[10];
float CostoLibro;
int NumeroEjemplares;
};
struct PILA {
struct Datos Datos;
struct PILA *sig;
} *Cima = NULL;
//--------------------------------------------------------------------------//
int MeterEnPila(Datos Item)
{ struct PILA *Nuevo;
clrscr();
Nuevo = new(PILA);
if(Nuevo==NULL)
{
cout << "\nMemoria llena" << endl;
return(0);
}
else
{
Nuevo->Datos = Item;
Nuevo->sig = NULL;
if(Cima)
Nuevo->sig = Cima;
Cima = Nuevo;
return(1);
}
}
//--------------------------------------------------------------------------//
void CapturarDatos()
{ Datos Item;
clrscr();
cout << "\nColocar un libro en pila"<< endl;
cout << "============================"<< endl;
cout << "El nombre del libro :";
gets(Item.Titulo);
cout << "El nombre del autor:";
gets(Item.Autor);
cout<<"El cdigo Dewey del libro: ";
gets(Item.Cota);
cout<<"El valor del libro: ";
cin >> Item.CostoLibro;
cout<<"Nmero de ejemplares: ";
cin >> Item.NumeroEjemplares;
MeterEnPila(Item);
}
//--------------------------------------------------------------------------//
void SacarLibroDePila()
{ struct PILA *p;
clrscr();
if(Cima==NULL)
{
cout<<"\nNo hay registros en memoria"<<endl;
}
else
147
{
cout << "\nLibro en la cima de la pila:" << endl
<< "=================================" << endl
<< "Nombre del libro: " << Cima->Datos.Titulo << endl
<< "Codigo del libro: "<< Cima->Datos.Cota << endl
<< "Valor de cada ejemplar: "<< Cima->Datos.CostoLibro << endl
<< "Nmero de ejemplares en existencia: "
<<Cima->Datos.NumeroEjemplares;
p = Cima;
Cima = Cima->sig;
delete(p);
}
getch();
}
//--------------------------------------------------------------------------//
void ListarLibrosEnPila()
{
clrscr();
if(Cima==NULL){
cout<<"No hay ningn libra en la pila";
}
else {
int NumTitulos=0, NumLibros=0;
struct PILA *p=Cima;
cout << "No. Ttulo
Autor
Cota"
<< "
Valor
Ejemplares\n\n";
while(p) {
NumTitulos++;
NumLibros += p->Datos.NumeroEjemplares;
cout << setiosflags(ios::right) << setw(2) << NumTitulos << "
"
<< setiosflags(ios::left) << setw(20) << p->Datos.Titulo
<< setw(15) << p->Datos.Autor
<< setw(10) << p->Datos.Cota
<< setiosflags(ios::right | ios::showpoint | ios::fixed)
<< setprecision(2) << setw(15) << p->Datos.CostoLibro
<< setiosflags(ios::right)
<< setw(8) << p->Datos.NumeroEjemplares << endl;
p = p->sig;
}
cout << "\nTotal de ttulos: " << NumTitulos
<< "\nTotal de libros en existencia: " << NumLibros;
}
}
//--------------------------------------------------------------------------//
void ConsultarDatoEnPila()
{
char item[20];
clrscr();
if(Cima==NULL)
cout<<"No hay libros en la Pila";
else {
cout<< "Digite el nombre del libro que desea buscar: ";
gets(item);
148
// invocacin recursiva
149
150
getch();
closegraph();
}
//--------------------------------------------------------------------------//
void main(){
int opcion;
CargarDesdeDiscoPila();
for(;;){
ListarLibrosEnPila();
cout << "\n\nMeter Sacar
151
Cima
0x2000
0x2000
152
Frente->Atras = NULL;
Final = Frente;
}
0x2000
Vanessa
Final
10
0x2000
1.4
NULL
Puntero Atras
Frente
0x2000
Frente
0x1500
0x1500
Vanessa
Final
10
0x1500
1.40
NULL
Puntero Atras
0x2000
Marcela
Nuevo
13
0x2000
1.65
NULL
Puntero Atras
Para que este nuevo nodo llegue al final de la cola, debemos codificar las
instrucciones:
Final->Atras = Nuevo;
Final = Nuevo;
Frente
0x1500
0x1500
Vanessa
10
1.40
0x2000
0x2000
Marcela
13
1.65
NULL
Final
0x2000
153
Frente
0x1500
0x1500
Vanessa
10
1.4
0x2000
0x2000
Marcela
13
1.65
0x2500
0x2500
Natalia
0.9
NULL
Final
0x2500
Vanessa
10
1.4
0x2000
Frente
0x2000
0x2000
Marcela
13
1.65
0x2500
0x2500
Natalia
0.9
NULL
Final
0x2500
cout << "Atendido: " << Frente->Info.Nombre << " del frente de la cola" <<
endl;
Aux = Frente;
Frente = Frente->Atras;
A continuacin el nodo apuntado por
quedando en definitiva toda la funcin as:
Aux,
deber
liberarse
con
delete,
AtenderCola(){
if(Frente){
cout << "Atendido: " << Frente->Info.Nombre
<< " del frente de la cola" << endl;
Aux = Frente;
Frente = Frente->Atras;
delete (Aux);
}
154
else
cout << "Cola vaca";
}
Como ejercicio elimine uno por uno los dos nodo que quedan en el dibujo
anterior, observe que el cdigo sigue funcionando cuando la cola est vaca, est
bien seguro de esto.
4. FUNCION LISTAR ELEMENTOS EN COLA
Aunque estrictamente, siendo dogmticos, solo se debe tener acceso al elemento
del Frente de la cola, a continuacin mostramos cdigo para recorrer la lista
enlazada en la que est la cola:
ListarCola(){
COLA *p;
int N=0;
if(Frente){
p = Frente;
while (p){
N++;
cout <<p->Info.Nombre <<" tiene " <<p->Info.Edad <<" aos" << endl;
p = p->Atras;
}
cout << "En cola existen " << N << " elementos en espera\n";
}
else
cout << "Cola est vaca";
}
Si ha entendido hasta aqu, notar que los algoritmos con listas enlazadas
son mucho ms simples que los correspondientes a los efectuados con vectores.
5. PROGRAMA DE APLICACION DE LA ESTRUCTURA DE DATOS COLA
Programa de estructura de datos cola, implementada como una lista simplemente
enlazada en memoria dinmica. Sehan utilizado las instrucciones tradicionales del
C: malloc, en vez de new, y free(en vez de delete), y as mismo el observe el
manejo de archivos con el archivo a incluir fcntl.h.
//COLALIST.CPP
#include <iostream.h>
#include <stdlib.h> // NULL
#include <conio.h>
#include <io.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <dos.h>
#include <ctype.h>
#define ARCHIVO "AGENDA.CLT"
typedef struct INFO INFO;
typedef struct NODO NODO;
struct INFO{
155
int edad;
char nombre[25];
};
struct NODO{
INFO info;
NODO *sig;
} *Frente=NULL, *Final=NULL;
const int BytesNodo=sizeof(NODO);
void Insertar (){
NODO *Nuevo;
if ( (Nuevo =(NODO *) malloc(BytesNodo) ) == NULL )
cout <<"No hay memoria suficiente";
else{
cout <<"\n\nDigite nombre: ";
gets(Nuevo->info.nombre);
cout <<"Digite edad: ";
cin >> Nuevo->info.edad;
Nuevo->sig = NULL;
if(!Frente)
Frente = Nuevo;
else
Final->sig = Nuevo;
Final = Nuevo;
}
}
void Eliminar(){
NODO *q;
if (!Frente)
cout <<"\nNo hay INFO";
else{
q = Frente;
Frente = Frente->sig;
cout <<"\nEliminado: "<<q->info.nombre<<" de " <<q->info.edad <<" aos";
free(q);
}
getch();
}
void GrabarColaLista(){
int NArch;
NODO *p, *q;
NArch = _creat(ARCHIVO, 32); _close(NArch);
NArch = _open(ARCHIVO, O_WRONLY);
p = Frente;
while ( p ) {
_write( NArch, (char *)&p->info, sizeof(p->info) );
q = p;
p = p->sig;
free(q);
}
_close(NArch);
156
}
void CargarColaLista(){
int NArch;
NODO *Nuevo;
if ( (NArch = _open(ARCHIVO, O_RDONLY) ) == -1){
cout <<"Archivo no existe \a"; delay(1000);
}
else{
Frente = Final = NULL;
Nuevo = (NODO *) malloc(BytesNodo);
while ( _read(NArch, (char *)&Nuevo->info, sizeof(Nuevo->info) )!=0) {
Nuevo->sig = NULL;
if (!Frente)
Frente = Final = Nuevo;
else
Final = Final->sig = Nuevo;
Nuevo =(NODO *) malloc(BytesNodo);
}
_close(NArch);
}
}
void ListarCola(){
NODO *p;
clrscr();
p = Frente;
while(p){
cout << p->info.nombre << " " << p->info.edad << "\n";
p = p->sig;
}
}
157
void main(){
char op;
CargarColaLista();
do{
ListarCola();
cout <<"\nInsertar
Eliminar
op = toupper(getch());
switch (op){
case 'I':Insertar();
break;
case 'E':Eliminar();
break;
}
} while (op != 'T');
GrabarColaLista();
Terminar: ";
}
A continuacin prueba de
anterior progrma COLALIST.CPP
Frente
Null
Nuevo
1000
Final
Null
1000
13
CAROLINA
NULL
ejecucin
manual
de
la
funcin
Insertar()
del
NODO
info.edad
info.nombre
*sig
Frente
1000
Final
1000
Nuevo
1000
1000
13
CAROLINA
NULL
158
Frente
1000
Final
1000
Nuevo
2000
La instruccin if(!Frente)
se pasa a evaluar la parte
quedando en memoria:
1000
2000
13
21
CAROLINA TANIA
NULL
NULL
equivale a if(!1000), el cual es falso, por esto
de else: final->sig=Nuevo, y luego Final=Nuevo;
1000
2000
13
21
CAROLINA TANIA
2000
>
NULL
->Nuevo sig
En una
memoria:
tercera
invocacin,
1000
2000
13
21
CAROLINA TANIA
2000
>
NULL
Final->sig
Frente
1000
digitamos
edad
Nuevo
2000
23
3000
Frente
23
1000
NELCY
NULL
->Nuevo sig
Final
2000
Nombre
NELCY
Final
2000
quedando
en
Nuevo
3000
1000
Final
3000
1000
2000
3000
13
21
23
CAROLINA TANIA
NELCY
2000
>
3000
>
NULL
Nuevo
3000
159
Frente=Frente->sig
q
Frente
Final
1000
2000
3000
1000
2000
3000
13
21
23
CAROLINA TANIA
NELCY
2000
>
3000
>
NULL
siguiendo en pantalla "Eliminando CAROLINA de 13 aos" y la direccin del Nodo a
que apunte q quedando:
q
1000
Frente
2000
2000
3000
21
23
TANIA
NELCY
3000
>
NULL
Final
3000
160
INFO
*Puntero
nulo
D
2500->
una lista con un solo NODO
nulo
Se inserta un item E:
Cab
2500-->
2500
3000 -->
3000
nulo
161
Se inserta un item B:
4000
2500 -->
Se inserta un item M:
4000
Cab
B
4000-->
2500 -->
Cab
4000-->
2500
3000 -->
3000
nulo
2500
3000 -->
3000
4500 -->
4500
nulo
Se inserta un item H:
4000
Cab
B
4000-->
2500 ->
2500
3000 ->
3000
5000 ->
5000
4500 ->
4500
nulo
4000-->
4000
2500 -->
2500
5000 -->
5000
4500 -->
4500
nulo
2500-->
2500
5000 -->
5000
4500 -->
4500
nulo
162
Nuevo->sig = nulo;
Nuevo->info = item;
while(q && item>q->info)
{
p = q;
q = q->sig;
}
if(!p)
{
//se inserta de primero el Nuevo NODO
Nuevo->sig = Cab;
Cab = Nuevo;
}
else
{
if(!q)
// se inserta de ltimo el Nuevo NODO
p->sig = Nuevo;
else
{
p->sig = Nuevo; //se inserta intermedio en lista
Nuevo->sig = q;
}
}
Para la explicacin del algoritmo supondremos, por conveniencia, se encuentra en
memoria la siguiente lista enlazada:
Cab
1000->
1000
2000 -->
2000
3000 -->
3000
1500 -->
1500
nulo
1000->
nulo
1000
2000 ->
1000
2000
3000 ->
item
3000
1500 ->
1500
nulo
4000
nulo
Nuevo
4000
163
1000->
1000
2000 ->
1000
2000
3000 ->
2000
3000
1500 ->
1500
nulo
item
la
4000
nulo
Nuevo
4000
B
E G N
I
1000-->
item
p
q
Nuevo
I
2000
3000
4000
q=q->sig;
B
1000-->
2000 ->
item
2000
3000
1500
E G N
3000 ->1500 ->nulo
p
q
3000 1500
4000
nulo
Nuevo
4000
164
1000-->
1000
2000->
item
2000
3000
E G
3000 ->4000
p
3000
1500
nulo <
q
1500
4000
1500
Nuevo
4000
1000-->
1000
2000->
2000
3000 ->
item
3000
4000 ->
3000
4000
1500 ->
nuevo
4000
1500
nulo
1500
nulo
p
nuevo
nulo
5000
nuevo
5000
item
p = nulo;
q = Cab;
Nuevo = new (NODO);
Nuevo->sig = nulo;
Nuevo->info = item;
q
1000
165
1000
2000->
cab
1000-->
2000
3000 ->
3000
4000 ->
4000
1500 ->
1500
nulo
A B E G I N
5000-->
nulo
5000
1000
A
6000
6000
nulo
A
5000-->
1000
2000
3000
4000
1500
166
nulo
5000
el while(q && item>q->info) es verdadero, 'Q' es mayor que 'A', por esto, al
entrar al while, p y q avanzarn:
5000
1000
2000
3000
4000
1500
cab
A B E G I N
5000-->
5000
1000
A B E G I N
5000-->
1000
2000
A B E G I N
5000-->
2000
3000
cab
5000->
5000
1000
2000
3000
4000
1500
A B E G I N
1000 ->2000 ->3000 ->4000 ->1500 ->nulo
167
3000
4000
volvemos arriba al while, q vale 4000 y 'Q' es mayor que 'I', es verdadero:
cab
5000->
5000
1000
2000
3000
4000
1500
A B E G I N
1000 ->2000 ->3000 ->4000 ->1500 ->nulo
p
4000
1500
//este if es falso
5000
1000
2000
3000
4000
1500
6000
168
5000
1000
2000
3000
4000
1500
6000
nulo
p
nuevo
q
1500 6000 nulo
Aunque debiera haber sido lo primero en explicar. Insertemos a continuacin un
nodo cuando la lista simplemente enlazada est vaca. Insertemos un item 'E':
p = nulo;
q = Cab;
Nuevo->sig = nulo;
Nuevo->info = item;
p
nulo
nulo
nuevo
2000
2000
nulo
cab
nulo
nulo
nulo
nuevo
2000
cab
2000-->
2000
nulo
169
A B E G I
5000-->
5000
P recibe este valor, Cabeza de lista, al invocarse inicialmente
5000
ListaInversa(1000)
1000
5000
ListaInversa(1000)
1000
ListaInversa(2000)
2000
ListaInversa(4000)
ListaInversa(NULL)
170
3000
4000
NULL
5000
ListaInversa(1000)
1000
ListaInversa(3000)
3000
ListaInversa(4000)
4000
ListaInversa(2000)
2000
5000
ListaInversa(1000)
1000
ListaInversa(2000)
2000
ListaInversa(3000)
3000
5000
ListaInversa(1000)
1000
ListaInversa(2000)
2000
171
5000
ListaInversa(1000)
1000
ListaInversa(5000)
5000
LISTADIN.CPP
Ejercicio de Programacin: Utilice el programa ListaDin.cpp anterior- como herramienta para realizar lo propuesto
a continuacin:
1. Colquele un men de conmutadores y manejo del mouse(es decir debe poder moverse con las flechas las
opciones), en forma grfica.
2. A la struct INFO agrguele el campo de Altura de la persona. Efecte modificaciones por esto en las
funciones de captura y de listar.
3. Efecte captura de al menos 10 registros, el archivo binario generado debe entregrmelo en un disquete.
4. Realice funcin la cual muestre en pantalla el nombre de la persona que tiene ms aos y, la que tiene menos
aos, supongamos que es nica en ambos casos.
5. Realice funcin que busqu las personas en el rango de dos estaturas digitadas por teclado. Mostrar en
pantalla y grabar en archivo de texto(Copiarlo en disquete que me entregaran).
6. Realice funcin la cual muestre en pantalla y grabe en archivo de texto, los nombres de cada una de las
personas y la diferencia que tienen cada una con la edad promedio de todas. Por ejemplo, si el promedio de
las 10 personas es 34 aos y Mara tiene 20 aos y Juan 40, debera aparecer en pantalla((observe el negativo
en Mara):
....
Mara 20
-14.
Juan 40
6
....
El promedio de las edades es 34 aos
7. Muestre en pantalla y grabe en archivo de texto(entregrmelo en disquete) los registros clasificados por edad
172
ascendentemente. Para esto defina un nuevo puntero Cab2; debe recorrer la lista en memoria, apuntada
inicialmente por Cab, e ir insertando en nuevas direcciones de memoria cada uno de los registros de las
personas. La falla de hacerlo as es que cada Nodo quedar dos veces. Pero bueno es un simple ejercicio.
8. Muestre en pantalla y archivo de texto(entregrmelo en disquete) los registros clasificados por altura
ascendentemente. Esta vez efecte la clasificacin cambiando el orden que tiene. Es decir que Cab quedar
apuntando al nodo de la persona de menor edad, este nodo apuntar a la segunda de menor edad, etctera.
Utilice al menos dos variables de tipo puntero(NODO *p, *q) con ellos debe ir desplazndose por la lista e ir
intercambiando los nodos. El algoritmo puede ser una versin de la burbuja pero no en vectores, sino
directamente sobre la lista enlazada.
9. Similar a la funcin que graficar barras representando edades(ver ListaDIN.cpp), cambie ahora a las alturas
de las personas(Observe que el cambio es de int a flot. Truco: convierta cada edad en metros a centmetros
multiplicando por 100, y efecte conversin forzada, (cast), de esta forma: AlturaCms = (int) AlturaMetros *
100;
10. Todo el programa ListaDin.CPP, con las modificaciones anteriores, grabarlo en disquete y entregrmelo. En
Word, o similar, contestar el enunciado anterior, insertando en cada caso el cdigo y los resultados
correspondientes, entregarme copia de este archivo tambin. Es decir este archivo (Segundo Parcial
Informtica III.Doc) con sus respuestas. En resumen, deben entregarme en un disquete:
Copia de este archivo con todas las respuestas: Segundo Parcial Informtica III.Doc. Para calificar
solo mirar este archivo. De los dems solo quiero que los coloquen por si veo alguna inconsistencia
y, ayudarlos a corregirla. Entonces debe estar muy bien presentado.
Copia de su versin de ListaDin.cpp (con las funciones que realiz y que corra. Las funciones que
no lo hagan, marcarlas con comentarios.)
Archivo binario con los, al menos, 10 registros capturados.
Archivos de texto de las preguntas 5, 6, 7 y 8( cuatro archivos)
En total 7 archivos.
173
174
clasificados
por
salario,
renta,
BUSCAR: Submens que permitan encontrar los ciudadanos que estn en cada uno
de los rangos de salario mnimo sealados anteriormente; a partir de una cdula
mostrar los datos de la correspondiente persona. Digitar un valor de renta y
mostrar todos los registros que cumplen con que la de ellos en mayo o igual.
3. Una editorial tiene un conjunto de registros para cada uno de los ttulos de
libros existentes, cada uno de los cuales contiene: cdigo del libro, ttulo de
la obra, nombre completo del autor, nmero de pginas, y si es en rstica o de
lujo, existencia en bodega de cada ttulo. Efectuar funciones que permitan:
CAPTURAR: la captura de estos registros y mantenerlos en memoria en la lista
enlazada.
PRECIO UNITARIO: A partir de digitar el cdigo de un libro, efectuar su
bsqueda y mostrar su precio teniendo en cuanta lo siguiente: El precio bsico de
un libro es de $2.000, ms 35 pesos por pgina; empero, si el nmero de pginas
excede de 300, el precio sufrir un recargo adicional de $10; si el nmero de
pginas excede de 550, el precio se incrementar $8, y esto debido al mayor costo
de la compaginacin y empastado. Si la edicin no es en rstica, es decir es de
lujo el precio calculado hasta el momento se aumentar en un 60%.
LISTAR: Por medio de un submen mostrar en pantalla o en papel lo siguiente.
Calcular e imprimir el cdigo y el precio para cada uno de los libros,
clasificados por el cdigo del libro. Imprimir el total, en pesos, del inventario
de libros. Mostrar el mismo inventario de libros clasificados por autor. Mostrar
tambien clasificado por ttulo.
BUSCAR: Por medio de submens conteste cada uno de los siguientes
interrogantes: Se debe digitar un cdigo de libro y si existe en el inventario
decir su precio. Digitar un valor de libro y listar a continuacin todos los
libros que tienen igual o mayor precio. Digitar el nombre de un autor y a
continuacin mostrar todos los libros que le pertenescan de entre el inventario.
Digitar un ttulo de un libro y a continuacin decir cuantos ejemplares de ese
ttulo hay en existencia en el momento. Digitar un apellido o nombre y a
continuacin presentar todos los nombres completos de autores que lo contengan.
Digitar una palabra y mostrar en pantalla todos los ttulos que la contengan.
CLASIFICAR: Por medio de submenus clasificar por: cdigo, valor de cada
libro, titulo y autor. Escoja al gusto si prefiere ordenes descendentes o
ascendentes.
ESTADISTICA: presente estadsticas de el valor de los libros, con la ayuda
del programa ESTADIST.CPP
4. Cierta Universidad est interesada en saber estadsticamente la calificacin
promedio de los estudiantes que recibieron matemtica durante un semestre. Desea
saber tambin el nmero total de estudiantes y el nmero de estudiantes
175
176
177
submens
por las
mostrar
en
pantalla
claves: cdula, nombre
clasificaciones
cliente, valor
178
179
Nombre pasajero,
edad,
telfono,
cdula,
estado de la silla(Vaca, Reservada, Ocupada)
Nacionalidad
Representar globalmente mediante lista enlazada y variable que cuente las
reservas efectuadas. Al iniciar el programa debe inicializar los campos que
corresponden al estado de la silla con vaco (podra ser un cero o una letra V).
A continuacin, presentar un men principal de conmutadores, el cual permita
invocar funciones que hagan lo siguiente:
RESERVAR CUPO: En caso de estar llenos los cupos que aparezca el aviso "CUPO
COMPLETO. POR FAVOR CIERRE EL VUELO". En caso de haber disponibilidad se le
asigna el nmero de silla marcando como "Reservada" en el campo "Estado de la
silla". De esta forma el nmero de reservas aumentar en una cada vez que sea
invocada esta funcin.
CANCELAR RESERVA: Se pide al pasajero el nmero de silla que tiene reservada,
y se debe dejar marcada como "vaca" en el campo "Estado de la Silla"
correspondiente. De esta forma el nmero de reservas se decrementar en una.
CONFIRMAR RESERVA: Cuando el pasajero se presenta al aeropuerto se le debe
solicitar el nmero de silla(se supondr que se la sabe) y marcarla como
"ocupada".
LISTAR: presentar en pantalla un submen el cual permita listar la
informacin clasificada por: cdula, y otro por apellido, y otra opcin que
permita imprimir en papel.
CERRAR EL VUELO(y terminar el programa): Cuando el avin vaya a despegar,
producir un listado con la siguiente estadstica:
Nmeros de sillas ocupadas y sillas vacas (las vacas son las marcadas como
"vacas" ms las reservadas que no viaj nadie en ellas).
Estadsticas de
ESTADIST.CPP.
Los pasajeros que sean de nacionalidad satanizada por los Estados Unidos,
imprimirlos en papel, con todos sus datos.
las
edades
de
los
pasajeros,
con
la
ayuda
del
programa
180
<stdio.h>
<fstream.h>
<iostream.h>
<conio.h>
<ctype.h>
<dos.h>
//delay()
// LISTADOBL.CPP
como el primero
181
Eliminar(LISTADOBLE *p){
LISTADOBLE *q;
Listar(){
LISTADOBLE *p;
if (!Cab)
cout << "Lista vaca \a\n";
else {
182
p = Cab;
while ( p ){
cout << p->Info.Cadena << "
p = p->sig;
}
}
}
void
ListaDesdeElFinal(){
LISTADOBLE *p;
if (!Fin)
cout << "\n\nLista vaca \a\n";
else {
clrscr();
p = Fin;
while ( p ){
cout << p->Info.Cadena << "
p = p->ant;
}
}
delay(2000);
}
void
GrabarLista(){
LISTADOBLE *p;
ofstream out(ARCHIVO);
if (!out){
//out es una funcin de la clase ios que est en fstream.h
cout << "No se puede abrir el archivo \a\n"; delay(2000); return;
}
p = Cab;
while ( p ) {
out.write( (unsigned char *)&p->Info, BytesReg );
p = p->sig;
}
out.close();
}
void
}
void main(){
char op;
INFO item; LISTADOBLE *p;
183
LISTADOBLE Lista;
CargarLista();
do{
clrscr(); Listar();
cout <<"\n\nInsertar Borrar
switch (
op = toupper( getch() ) ){
case 'I':
cout <<"\nDigite entero: ";
cin >> item.Entero;
cout <<"\nDigite Cadena: ";
gets(item.Cadena);
if ( ! Insertar(item) ){
cout <<"\nRepetido \a\n"; delay(2000);
}
break;
case 'B':
cout <<"\nDigite Entero a eliminar: ";
cin >> item.Entero;
if (p = Encontrar(item))
Eliminar(p);
else{
cout <<"\n\nNO encontrado en lista\a\n";
delay(2000);
}
break;
case 'E':
cout <<"\nDigite Entero a encontrar: " ;
cin >> item.Entero;
if (p = Encontrar(item))
cout <<"\nEncontrado en lista con Cadena: "
<< p->Info.Cadena;
else
cout <<"\n\nNO encontrado en lista\a\n";
delay(2000);
break;
case 'L': ListaDesdeElFinal();
} //switch
} while (op != 'T');
GrabarLista();
}
184
185
//**************************************************************************
// COMIENZAN FUNCIONES PARA EL MANEJO DEL MOUSE CON INTERRUPCION 33 DEL DOS
//**************************************************************************
int IniciaMouse( int &BotonMouse){
union REGS entra,sale;
entra.x.ax = 0x0000;
int86( 0x33, &entra, &sale);
BotonMouse = sale.x.bx;
return ( sale.x.ax );
}
//**************************************************************************
void MuestraMouse( void ){
union REGS entra, sale;
entra.x.ax = 0x0001;
int86 ( 0x33, &entra, &sale );
}
//**************************************************************************
void EscondeCursorMouse( void ){
union REGS entra, sale;
entra.x.ax = 0x0002;
int86( 0x33, &entra, &sale);
}
//**************************************************************************
int LeerTeclaXYMouse( int &x, int &y){
union REGS entra,sale;
entra.x.ax = 0x0003;
int86( 0x33, &entra, &sale );
x = sale.x.cx;
y = sale.x.dx;
return(sale.x.bx);//Botn: 0=no pulsado; 1=izquierdo; 2=derecho;4=central.
}
//**************************************************************************
void MarcoVentana(int X1, int Y1, int X2, int Y2, int ArbAbj)
{
setlinestyle(SOLID_LINE,0,NORM_WIDTH);
if (ArbAbj == Arriba)
setcolor(15);
else
setcolor(DARKGRAY);
line(X1, Y1, X1, Y2);
line(X1,Y1, X2,Y1);
if (ArbAbj == Arriba)
setcolor(DARKGRAY);
else
setcolor(WHITE);
line(X2,Y1, X2,Y2);
line(X1,Y2, X2,Y2);
}
//**************************************************************************
void Cursor(int X,int Y,char *Cad,int Oprimido){
register int AltoCuadro,LargoCuadro;
char c[2];
settextstyle(DEFAULT_FONT,
HORIZ_DIR,1);
AltoCuadro=textheight(Cad) + 7;
LargoCuadro= X + textwidth(Cad) + 7;
EscondeCursorMouse();
if (!Oprimido) {
MarcoVentana(X,Y,LargoCuadro,Y+AltoCuadro,Arriba);
setcolor(DARKGRAY);
186
}
else {
MarcoVentana(X,Y,LargoCuadro,Y+AltoCuadro,Abajo);
setcolor(WHITE);
}
outtextxy(X+5,Y+5,Cad);
c[0] = Cad[0];
c[1] ='\0';
setcolor(RED);
outtextxy(X+5,Y+5, c);
MuestraMouse();
}
//**************************************************************************
/* Funcion : PulsadoCuadro
*/
/* Objetivo : Realiza Cursor con una cadena centrada en su
*/
/*
interior y da la sensacion de que se oprime.
*/
/**************************************************************/
void PulsadoCuadro(int X,int Y,char *Cad)
{
Cursor(X,Y,Cad,DesActivo);
delay(100);
Cursor(X,Y,Cad,Activo);
delay(100);
Cursor(X,Y,Cad,DesActivo);
}
//**************************************************************************
void OVNI(int X,int Y){
int Radio =7;
setfillstyle( SOLID_FILL, BLUE); fillellipse(X,Y, Radio, Radio-1);
setfillstyle(SOLID_FILL, YELLOW);
fillellipse(X,Y+2,6,1);
setcolor(LIGHTRED); line(X+4, Y-2, X+5, Y-6); line(X-4, Y-2, X-5, Y-6);
fillellipse(X+6, Y-8, 3, 4); fillellipse(X-6, Y-8, 3, 4);
fillellipse(X-6, Y-8, 2, 2); fillellipse(X+6, Y-8, 2, 2);
}
//**************************************************************************
void Bloque(int x,int y){
setfillstyle(1, BLUE); bar(x,y,x+Ancho,y+Alto);
setcolor(LIGHTMAGENTA);
line(x,y,x+(Ancho-4),y);
line(x,y,x,y+(Alto-4));
line(x+3,y+3,x+Ancho,y+3);
line(x+3,y+3,x+3,y+Alto);
line(x+6,y+6,x+6,y+(Alto-6)); line(x+6,y+6,x+(Ancho-6),y+6);
line(x+(Ancho-3),y+6,x+(Ancho-3),y+(Alto-3));
line(x+6,y+(Alto-3),x+(Ancho-3),y+(Alto-3));
}
//**************************************************************************
void DibujarLaberinto(){
int c, f;
clearviewport();
for(f=0;f<Fila;f++)
for(c=0;c<Col;c++)
if(Matriz[f][c]==1){
Bloque(Xo+c*Ancho,y0+f*Alto);
}
else
if(Matriz[f][c]==0){
setfillstyle(SOLID_FILL, BLACK);
setcolor(DARKGRAY);
rectangle(Xo+c*Ancho,y0+f*Alto,Xo+c*Ancho+Ancho,y0+f*Alto+Alto);
}
return;
187
}
//**************************************************************************
void InsertarEnListaDoble(int x,int y){
LABERINTO *nuevo, *p;
nuevo= new LABERINTO;
nuevo->info.x=x;
nuevo->info.y=y;
if(!Cab){
Cab=nuevo;
nuevo->Sig=NULL;
Final =nuevo;
nuevo->Ant=NULL;
}
else{
nuevo->Ant=Final;
Final->Sig=nuevo;
nuevo->Sig=NULL;
Final=nuevo;
}
}
//**************************************************************************
void EnsenarAlAgenteMoverseEnLaberinto(){
int x=Xo+1.5*Ancho, y=y0+1.7*Alto;
int c,f;
N=0;
OVNI(x, y);
InsertarEnListaDoble(x,y);
N++;
do{
c = getch();
if (c == 0 ) {
c = getch();
switch (c) {
case Der: if(Matriz[(y-y0)/Alto][(x-Xo)/Ancho+1]!=1){
setfillstyle(SOLID_FILL, BLACK);
bar(x-9, y-12, x+(Ancho-13), y+(Ancho-16));
x+=Ancho;
InsertarEnListaDoble(x,y);
OVNI(x,y);
N++;
if((y-y0)/Alto==8 && (x-Xo)/Ancho==Col-1){
delay(500);
setfillstyle(SOLID_FILL, BLACK);
bar(x-9,y-12, x+(Ancho-13),
y+(Ancho-16));
x = Xo+2*Ancho;
y = y0+7*Alto;
OVNI(x, y);
sound(440); delay(100); nosound();
}
else
sound(2500); delay(20);
sound(1500);delay(10);nosound();
}
break;
case Izq: if(Matriz[(y-y0)/Alto][(x-Xo)/Ancho-1]!=1){
setfillstyle(SOLID_FILL, BLACK);
bar(x-9, y-12, x+(Ancho-13), y+(Ancho-16));
188
x-=Ancho;
InsertarEnListaDoble(x,y);
N++;
OVNI(x, y);
sound(2500);delay(20);
sound(1500);delay(10);nosound();
}
break;
case Abj: if(Matriz[(y-y0)/Alto+1][(x-Xo)/Ancho]!=1){
setfillstyle(SOLID_FILL, BLACK);
bar(x-9, y-12, x+(Alto-13), y+(Alto-16));
y+=Alto;
InsertarEnListaDoble(x,y);
N++;
OVNI(x, y);
sound(2500);delay(20);
sound(1500);delay(10);nosound();
sound(2500);delay(5);
sound(15);delay(10);nosound();
sound(2500);delay(5);
sound(1500);delay(10);nosound();
sound(2500);delay(10);
sound(15);delay(5);nosound();
}
break;
case Arb: if(Matriz[(y-y0)/Alto-1][(x-Xo)/Ancho]!=1){
setfillstyle(SOLID_FILL, BLACK);
bar(x-9,y-12,x+(Alto-13), y+(Alto-16));
y-=Alto;
OVNI(x, y);
InsertarEnListaDoble(x,y);
N++;
sound(2500);delay(5);
sound(15);delay(10);nosound();
sound(2500);delay(5);
sound(1500);delay(10);nosound();
sound(2500);delay(10);
sound(15);delay(5);nosound();
}
break;
default: sound(440); delay(10); nosound();
}
}
} while (c!=27);
}
//**************************************************************************
void ListarHaciaAdelante(){
LABERINTO *p,*q;
p=Cab;
q=NULL;
while(p){
q=p;
p=p->Sig;
OVNI(p->info.x,p->info.y);
setfillstyle(SOLID_FILL, BLACK);
bar(q->info.x-9,q->info.y-12 ,
q->info.x+(Ancho-13), q->info.y+(Ancho-16));
setfillstyle(SOLID_FILL,14); fillellipse(q->info.x,q->info.y-4,4,4);
189
delay(100);
sound(1350);delay(10);sound(1150);delay(5);nosound();
sound(1150);delay(5);sound(1350);delay(10);nosound();
}
}
//**************************************************************************
void ListarHaciaAtras(){
LABERINTO *p,*q;
p=Final;
q=NULL;
while(p){
q=p;
p=p->Ant;
OVNI(p->info.x,p->info.y);
setfillstyle(SOLID_FILL, BLACK);
bar(q->info.x-9,q->info.y-12 ,
q->info.x+(Ancho-13), q->info.y+(Ancho-16));
delay(100);
sound(3500);delay(10);sound(1500);delay(5);nosound();
sound(1500);delay(5);sound(3500);delay(10);nosound();
}
}
//**************************************************************************
void main(){
int i, c, pos=0, Invocar=1;
char *Opcion[MaxOp1] = {"Ensear","Auto","Revez","Salir"};
int PosX[MaxOp1], TotalAnchoCaracteres=0, TeclaMouse=0, x, y;
int ManejadorGrafico = DETECT, ModoGrafico;
initgraph( &ManejadorGrafico, &ModoGrafico, "\\tc\\bgi" );
setbkcolor(LIGHTGRAY);
DibujarLaberinto();
for(i=0;i<MaxOp1;i++)
TotalAnchoCaracteres += textwidth(Opcion[i])+Margen;
PosX[0] = (getmaxx()-TotalAnchoCaracteres)/2;
for(i=1;i<MaxOp1;i++)
PosX[i]=PosX[i-1]+textwidth(Opcion[i-1])+Margen;
for(;;){
if(Invocar){
for (i=0; i<MaxOp1; i++){
Cursor(PosX[i], FilaMenu1, Opcion[i],DesActivo);
}
Cursor(PosX[pos], FilaMenu1, Opcion[pos],Activo);
Invocar=0;
}
MuestraMouse();
do{
TeclaMouse = LeerTeclaXYMouse(x,y);
} while (!kbhit() && !TeclaMouse);
if(!TeclaMouse){
c = getch();
if (c == 0) {
c = getch();
switch (c) {
case Der: Cursor(PosX[pos], FilaMenu1,
190
Opcion[pos],DesActivo);
pos++;
if (pos == MaxOp1)
pos=0;
Cursor(PosX[pos],FilaMenu1,
Opcion[pos],Activo);
break;
case Izq: Cursor(PosX[pos],FilaMenu1,
Opcion[pos],DesActivo);
pos--;
if (pos == -1) pos = MaxOp-1;
Cursor(PosX[pos],FilaMenu1,
Opcion[pos],Activo);
break;
case 45:
return; //Alt-X
}
}
else {
if(c==ESC)
return;
c=toupper(c);
i=0;
while( c!=Opcion[i][0] &&
i<MaxOp1)
i++;
if(i<MaxOp1){// Se digit letra inicial de opcin
pos = i;
Invocar=1;
}
if (c==Entrar )
Invocar = 1;
}
}
else{ //Se digit tecla en el mouse
if(y>=FilaMenu1 && y<=FilaMenu1+textheight("H")+Margen){
Cursor(PosX[pos],FilaMenu1,Opcion[pos],DesActivo);
i=0;
while(i<MaxOp1 && !(x>PosX[i] &&
x< PosX[i]+textwidth(Opcion[i])+10) )
i++;
if(i<MaxOp1){ // Se hizo "click" en recuadro del mena
pos=i; Invocar=1;
}
else
TeclaMouse=0;
Cursor(PosX[pos],FilaMenu1,Opcion[pos],Activo);
}
}
if(Invocar){
PulsadoCuadro(PosX[pos],FilaMenu1,Opcion[pos]);
switch (pos){
case 0 : EnsenarAlAgenteMoverseEnLaberinto();break;
case 1 : ListarHaciaAdelante();break;
case 2 : ListarHaciaAtras();break;
case 3 : return;
}
}
}
}
191
192
LISTA DE LISTAS
/*El siguiente algoritmo implementa una lista simplemente enlazada en la cual
de cada uno de sus nodos se puede desprender una sublista simplemente enlazada.
En cada uno de los nodos de la lista principal, tenemos la informacin de un
mdico: Nombre, Telfono y Honorarios por hora. En cada una de las sublistas que
se pueden desprender de los nodos anteriores, tendremos los pacientes de cada
uno de los mdicos, con informacin de Nombre Paciente, Horario de su cita y su
telfono.
*/
//LISTALIST.CPP
#include <IOStream.h>
#include <IOManip.h>
#include <FStream.h>
#include <ConIO.h>
#include <StdIO.h>
#include <DOS.h>
#include <String.H>
#include <CType.H>
char NombreArch[20] = "Citas.Dr";
fstream Archivo;
typedef
typedef
typedef
typedef
struct
struct
struct
struct
INFOLISTA INFOLISTA;
LISTA LISTA;
InfoSubLista InfoSubLista;
SubLista SubLista;
struct InfoCitas{
char Horario[20];
char Nombre[25]; // del paciente
char Telefono[10];
};
struct SubLista{
InfoCitas Info;
SubLista *Sig;
};
struct INFOMEDICO{
char Nombre[25]; //permite hasta 24 caracteres
char Telefono[10];
float ValorHora;
};
struct LISTA{
INFOMEDICO Info;
SubLista *Cab;//Apunta a cada sublista desde cada nodo de la lista
principal
LISTA *Sig;
} *CAB=NULL;
LISTA *InsertarLISTA (INFOMEDICO item){
LISTA *p, *q, *nuevo;
193
nuevo = new(LISTA);
if ( nuevo == NULL ) {
cout << "No hay memoria suficiente";
return(NULL); // No insertado
}
p = NULL;
q = CAB;
while (q != NULL && strcmp(item.Nombre, q->Info.Nombre)>0){
p = q;
q = q->Sig;
}
if (q && strcmp(item.Nombre, q->Info.Nombre)==0){
delete(nuevo);
return (NULL); //repetido,
}
nuevo->Info = item;
nuevo->Sig = q;
nuevo->Cab = NULL;
if ( p == NULL)
CAB = nuevo; //era el primero de la lista
else
p->Sig = nuevo; //"caso general"
return(nuevo); // insertado
}
int EliminarLISTA(LISTA *p){
LISTA *q;
if (p == CAB)
CAB = p->Sig; //eliminado el primer LISTA de la lista
else {
q = CAB;
while (q->Sig != p)
q = q->Sig;
q->Sig = p->Sig;
}
delete(p);
return 1;
}
LISTA* EncontrarLISTA(INFOMEDICO item){
LISTA *p;
p = CAB;
while (p && strcmp(item.Nombre,p->Info.Nombre)>0)
p = p->Sig;
if(p && strcmp(item.Nombre,p->Info.Nombre)!=0 )
p= NULL;
// No encontrado
return p;
}
194
void ListarLISTA(){
if (!CAB)
cout << "Lista vaca \a";
else {
LISTA *p = CAB;
int i=0;
while ( p ){
cout << setiosflags(ios::right) << setw(8) << i++ << "
"
<< setiosflags(ios::left) << setw(25)
<< p->Info.Nombre
<< setiosflags(ios::right) << setw(3) << p->Info.Telefono
<< setiosflags(ios::right | ios::showpoint | ios::fixed)
<< setprecision(2) << setw(15) << p->Info.ValorHora << endl;
p = p->Sig;
}
}
}
void CapturarLISTA(){
INFOMEDICO item;
cout << "\n\nDigite Info a InsertarLISTA: ";
cout << "\n\Nombre del mdico: ";
gets(item.Nombre);
cout << "\n\nTelfono: ";
cin >> item.Telefono;
cout << "\n\nHonorarios por hora: ";
cin >> item.ValorHora;
if ( InsertarLISTA(item) == 0 ){
cout << "\n\nRepetido \a";
getch();
}
}
void BorrarLISTA(){
INFOMEDICO item;
LISTA *LISTA;
if (CAB == NULL)
cout << "Lista vaca \a";
else{
cout << "\n\nDigite Nombre del mdico a borrar: ";
gets(item.Nombre);
LISTA = EncontrarLISTA(item);
if (LISTA)
EliminarLISTA(LISTA);
else {
cout << "\n\nNo encontrado en lista";
getch();
}
}
}
void EncontrarEnLISTA(){
INFOMEDICO item;
LISTA *p;
if (CAB == NULL)
cout << "Lista vaca \a";
195
else{
cout << "\n\nDigite Nombre del mdico a encontrar: ";
gets(item.Nombre);
if (p = EncontrarLISTA(item))
cout << "\n\nEncontrado en lista y tiene el telfono "
<< p->Info.Telefono;
else
cout << "\n\nNo encontrado en lista";
}
getch();
}
// ===========================================================================
//
A CONTINUACION LAS FUNCIONES PARA MANEJAR CADA SubLista
// ===========================================================================
SubLista *InsertarEnSubLista (InfoCitas item, SubLista *Cab){
SubLista *p, *q, *nuevo;
if ( (nuevo = new SubLista ) == NULL ){
cout << "No hay memoria suficiente";
return NULL;
}
p = NULL;
q = Cab;
while (q != NULL && strcmp(item.Nombre, q->Info.Nombre)>0){
p = q;
q = q->Sig;
}
nuevo->Info = item;
nuevo->Sig = q;
if ( p == NULL)
Cab = nuevo; //era el primero de la lista
else
p->Sig = nuevo; //"caso general"
return(Cab);
}
SubLista *EliminarEnSubLista(SubLista *p, SubLista *Cab){
SubLista *q;
if (p == Cab)
Cab = p->Sig; //eliminado el primer nodo de la lista
else {
q = Cab;
while (q->Sig != p)
q = q->Sig;
q->Sig = p->Sig;
}
delete(p);
return Cab;
}
SubLista* EncontrarEnSubLista(InfoCitas item, SubLista *Cab){
SubLista *p;
p = Cab;
while (p && strcmp(item.Nombre,p->Info.Nombre)>0)
196
p = p->Sig;
if (p && strcmp(item.Nombre,p->Info.Nombre)!=0)
p=NULL;
return p;
}
void ListarSubLista(SubLista *Cab){
SubLista *p; int Cliente=0;
if (!Cab)
cout << "No tiene citas \a\n";
else {
p = Cab;
while ( p ){
cout.setf(ios::left);
cout << setw(2) << ++Cliente << ": "
<< setw(25) <<p->Info.Nombre;
cout << setw(15) <<p->Info.Telefono;
cout << setw(20) <<p->Info.Horario << endl;
p = p->Sig;
}
}
}
SubLista *CapturarSubLista(SubLista *Cab){
InfoCitas item;
cout << "\n\nDigite datos del paciente a insertar: ";
cout << "\n\Nombre: ";
gets(item.Nombre);
cout << "\n\nTelefono: ";
cin >> item.Telefono;
cout << "\n\Horario de la cita: ";
gets(item.Horario);
Cab = InsertarEnSubLista(item, Cab);
if ( !Cab ){
cout << "\n\nNo se pudo insertar: se lleno la memoria\a";
getch();
}
return Cab;
}
SubLista* BorrarSubLista(SubLista *Cab){
InfoCitas item;
SubLista *Nodo;
if (Cab == NULL)
cout << "Lista vaca \a";
else{
cout << "\n\nDigite Nombre de paciente a borrar su cita: ";
gets(item.Nombre);
Nodo = EncontrarEnSubLista(item, Cab);
if (Nodo)
Cab = EliminarEnSubLista(Nodo, Cab);
else {
cout << "\n\nNo encontrado en lista";
197
getch();
}
}
return Cab;
}
void EncuentraSubLista(SubLista *Cab){
InfoCitas item;
SubLista
*p;
if (Cab == NULL)
cout << "Lista vaca \a";
else{
cout << "\n\nDigite Nombre de paciente a encontrar: ";
gets(item.Nombre);
if (p=EncontrarEnSubLista(item, Cab))
cout << "\n\nEncontrado en lista y tiene el telfono "
<< p->Info.Telefono;
else
cout << "\n\nNo encontrado en lista";
}
getch();
}
void SubListaEnlazada(){
char op;
INFOMEDICO item;
LISTA *q;
if(CAB){
clrscr();
cout <<"Nombre del Mdico a encontrar y colocarle las citas: ";
cin >> item.Nombre;
q = CAB;
while (q && strcmp(item.Nombre, q->Info.Nombre)!=0)
q = q->Sig;
if (!q)
cout << "No se encuentra ninguna persona de Nombre "
<< item.Nombre;
else{
do{
clrscr();
cout << "Estos son los pacienticos de "
<< q->Info.Nombre << endl;
ListarSubLista(q->Cab);
op = toupper(getch());
switch (op){
case 'I': q->Cab=CapturarSubLista(q->Cab); break;
case 'B': q->Cab=BorrarSubLista(q->Cab);
break;
case 'E': EncuentraSubLista(q->Cab);
break;
} //switch
} while (op != 'T');
}
} else
cout << "Lista de mdicos vaca\a";
}
//===========================================================================
198
// funcion recursiva
if ( P ) {
Archivo.write((char *)&P->Info, sizeof(P->Info));
p = P->Cab;
n = 0;
while(p) { n++; p=p->Sig; } //Cuenta # nodos en lista enlazada
Archivo.write((char *)&n, sizeof(n)); //Graba en disco # nodos
p = P->Cab;
while(p) {
Archivo.write((char *)&p->Info, sizeof(p->Info));
p=p->Sig;
}
GrabarLISTA_y_SubListas(P->Sig);
}
}
void Grabar(){
Archivo.open(NombreArch, ios::out|ios::binary|ios::trunc);
if (!Archivo)
cout << "Error en la apertura del archivo \a";
else{
GrabarLISTA_y_SubListas(CAB);
Archivo.close();
}
}
void CargarLISTA_y_SubListas(){
INFOMEDICO registro;
LISTA *p;
int n;
InfoCitas reg;
SubLista *Cab;
CAB = NULL;
Archivo.open(NombreArch,ios::in|ios::binary);
if (!Archivo){
cout << "No se puede abrir el archivo \a\n";
}
else {
while(
Archivo.read( (char *)®istro, sizeof(registro) ) ){
p = InsertarLISTA(registro);
//p es puntero a donde se inserto en lista
Archivo.read( (char *)&n, sizeof(n) );
//n es el nmero de nodos en lista enlazada
p->Cab=NULL;
for(int i=0; i<n; i++){
Archivo.read( (char *)®, sizeof(reg) );
p->Cab = InsertarEnSubLista(reg, p->Cab);
}
}
Archivo.close();
}
}
void main(){
199
char op;
unlink(NombreArch);
//Habilite si quiere borrar NombreArch
clrscr();
CargarLISTA_y_SubListas();
do{
clrscr();
ListarLISTA();
cout<<"\n\nMENU PRINCIPAL:Medicos Borrar Encontrar Citas Terminar:";
switch ( op = getch() ){
case 'm': ; case 'M': CapturarLISTA();
break;
case 'b': ; case 'B': BorrarLISTA();
break;
case 'e': ; case 'E': EncontrarEnLISTA(); break;
case 'c': ; case 'C': SubListaEnlazada(); break;
}
} while (!(op == 'T' || op == 't' ));
Grabar();
}
200
EL CDIGO ASCII
El cdigo ASCII(American Standard Committed for Information Interchange), es el
cdigo con el cual operan los microcomputadores que trabajan bajo el sistema
operativo MS-DOS y Windows. Se compone de un conjunto de caracteres de control,
y caracteres imprimibles, numerados del 0 al 255. Ocupa cada uno de ellos un
Byte de memoria, es decir ocho bit.
Tabla de Caracteres ASCII imprimibles.
32
42 *
52 4
62 >
72 H
82 R
92 \
102 f
112 p
122 z
132
142
152 _
162
172
182
192
202
212
222
232 F
242
252 _
33
43
53
63
73
83
93
103
113
123
133
143
153
163
173
183
193
203
213
223
233
243
253
!
+
5
?
I
S
]
g
q
{
34
44
54
64
74
84
94
104
114
124
134
144
154
164
174
184
194
204
214
224
234
244
254
"
,
6
@
J
T
^
h
r
|
a
W
35
45
55
65
75
85
95
105
115
125
135
145
155
165
175
185
195
205
215
225
235
245
255
#
7
A
K
U
_
i
s
}
36
46
56
66
76
86
96
106
116
126
136
146
156
166
176
186
196
206
216
226
236
246
$
.
8
B
L
V
`
j
t
~
37
47
57
67
77
87
97
107
117
127
137
147
157
167
177
187
197
207
217
227
237
247
%
/
9
C
M
W
a
k
u
p
f
38 &
39 '
40 (
41 )
48 0
49 1
50 2
51 3
58 :
59 ;
60 <
61 =
68 D
69 E
70 F
71 G
78 N
79 O
80 P
81 Q
88 X
89 Y
90 Z
91 [
98 b
99 c 100 d 101 e
108 l 109 m 110 n 111 o
118 v 119 w 120 x 121 y
128 129 130 131
138 139 140 141
148 149 150 151
158 _ 159 160 161
168 169 _ 170 171
178 179 180 181
188 189 190 191
198 199 200 201
208 209 210 211
218 219 220 221
228 S 229 s 230 m 231 t
238 e 239 240 241
248 249 250 251
201
siguiente
cdigo
c = getch();
cout << " el cdigo extendido es " << (int) c;
se coloca el reforzador de tipo, (int), para evitar que nos escriba en
pantalla el ASCII correspondiente al 50
Teclas que producen cdigos extendidos al digitarlas solas:
HOME
FLECHA ARRIBA
PAGE UP
FLECHA IZQUIERDA
FLECHA DERECHA
END
FLECHA ABAJO
PAGE DOWN
INSERT
DELET
F1 al F10
F11
F12
0
0
0
0
0
0
0
0
0
0
0
0
0
71
72
73
75
77
79
80
81
82
83
59 al 0 68
133
134
A a la Z
F1 al F10
F11
F12
65 al 90
0 84 al 0 93
0 135
0 136
202
A
continuacin
los
cdigos
extendidos
de
teclas
simultneamente con las teclas CTRL y ALT respectivamente:
CTRL
A
...
Y
F1
...
F10
IZQUIERDA
DERECHA
END
PAGE DOWN
HOME
PAGE UP
F11
F12
ARRIBA
+
ABAJO
INSERT
DELETE
/
*
ALT
1
...
25
0 94
...
0 103
0 115
0 116
0 117
0 118
0 119
0 132
0 137
0 138
0 141
0 142
0 144
0 145
0 146
0 147
0 149
0 150
al
ser
pulsadas
ALT
ESC
RETROCESO
Q
W
E
R
T
Y
U
I
O
P
ENTER
A
S
D
F
G
H
J
K
L
;
'
`
\
Z
X
C
V
B
N
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
14
16
17
18
19
20
21
22
23
24
25
28
30
31
32
33
34
35
36
37
38
39
40
41
43
44
45
46
47
48
49
M
,
.
/
F1...F10
1
2
3
4
5
6
7
8
9
0
=
F11
F12
HOME
FLECHA ARRIBA
PAGE UP
FLECHA IZQUIERDA
FLECHA DERECHA
END
FLECHA ABAJO
PAGE DOWN
INSERT
DELETE
TAB
ENTER
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
50
51
52
53
104-113
120
121
122
123
124
125
126
127
128
129
130
131
139
140
151
152
153
155
157
159
160
161
162
163
165
166
...
Despus de tntas y de tan pequeas
cosas, -busca el esprit mejores aires,
mejores aires.
Toda aqusa gentuza verborrgica
-trujamanes de feria, gansos del capitolio,
engibacaires, abderitanos, macuqueros,
casta inferior desglandulada de potencia,
casta inferior elocuenciada de impotencia-,
toda aqusa gentuza vervorrgica
me causa hasto, bascas me suscita,
gelasmo me ocaciona:
mejores aires,
-busca, busca el espritu mejores aires-.
... "
203
Segunda Parte
Tercera Parte
204