Sie sind auf Seite 1von 15

CAPTULO 10

PILAS Y SUS APLICACIONES


EJEMPLO 10.3
Paso de notacin infija a notacin postifija:

la expresin 2 + 4 * 3 * ( 1 + 2 ) en notacin postfija es 2 4 3 * 1 2 + * + la expresin 3 + 4 * 5 ^ ( 1 / 2 ) en notacin postfija es 3 4 5 1 2 / ^ * + la expresin 6.25 * 4 + 5.7 en notacin postfija es 6.25 4 * 5.7 +

PROBLEMAS RESUELTOS

10.1.
#include <stdio.h> #include <stdlib.h> typedef float TipoElemento; typedef struct UnNodo { TipoElemento e; struct UnNodo *sig; }Nodo; typedef Nodo Pila; int EsVaciaP(Pila *P) { return P == NULL; } void VaciaP(Pila** P) { *P = NULL; } void AnadeP(Pila** P,TipoElemento e) { Nodo * NuevoNodo; NuevoNodo=(Nodo*)malloc(sizeof(Nodo)); NuevoNodo -> e = e; NuevoNodo->sig= (*P); *P=NuevoNodo; } TipoElemento PrimeroP(Pila *P) { TipoElemento Aux; if (EsVaciaP(P)) { puts("Se intenta sacar un elemento en pila vaca");

exit (1);

Algoritmos y estructuras de datos. Una perspectiva en C. Libro de Problemas

} Aux = P->e; return Aux; } void BorrarP(Pila** P) { Pila *NuevoNodo; if (EsVaciaP(*P)) { puts("Se intenta sacar un elemento en pila vaca"); exit (1); } NuevoNodo=(*P); (*P) = NuevoNodo->sig; free(NuevoNodo); }

10.2
#include <stdio.h> #include <stdlib.h> #include <string.h> int PrioridadDentro(char opdor) { switch (opdor) { case '(': return 0; case '^': return 3; case '*': return 2; case '+': return 1; } return 0; }

case '/': return 2; case '-': return 1;

int PrioridadFuera(char opdor) { switch (opdor) { case '(': return 5; case '^': return 4; case '*': return 2; case '+': return 1; } return 0; }

case '/': return 2; case '-': return 1;

int Operador( char ch) { return ( ch=='('||ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='^' ); } void Postfija(char Linea[80],char post[80]) { Pila *P; char ch, aux[2]; int i, Apilado ;

Pilas y sus aplicaciones

VaciaP(&P); aux[1] = '\0' ; post[0] = '\0'; for (i = 0; i < strlen(Linea); i++) if (Operador(Linea[i])) { Apilado = 0; while (!Apilado) if (EsVaciaP(P)) { AnadeP(&P,Linea[i]); Apilado = 1; } else { ch = PrimeroP(P); if(PrioridadDentro(ch) >= PrioridadFuera(Linea[i])) { aux[0] = ch; strcat(post,aux); BorrarP(&P); } else { AnadeP(&P,Linea[i]); Apilado = 1; } } } else if (Linea[i] == ')' ) { ch = PrimeroP(P); BorrarP(&P); while (ch != '(') { aux[0] = ch; strcat(post,aux); ch = PrimeroP(P); BorrarP(&P); } } else /*(operando(Linea[i]*/ { aux[0] = Linea[i]; strcat(post,aux); } while(!EsVaciaP(P)) { ch = PrimeroP(P); BorrarP(&P); aux[0] = ch; strcat(post,aux); } }

Algoritmos y estructuras de datos. Una perspectiva en C. Libro de Problemas

void main (void) { char post[80], Linea[80]; puts(" expresion a pasar a Postfija\n"); gets(Linea); Postfija(Linea,post);puts("\n Postfija\n");puts(post); }

10.3
float valor(char c) { return (float) c; } float evaluar ( char post[80]) { float valor1, valor2,valor3; int i; Pila *P; VaciaP(&P); for(i = 0; i<strlen(post); i++) if (operador(post[i])) { valor2 = PrimeroP(P); BorrarP(&P); valor1 = PrimeroP(P); BorrarP(&P); switch (post[i]) { case '^' : valor3 = pow(valor1,valor2); break; case '/' : valor3 = valor1/valor2; break; case '*' : valor3 = valor1*valor2; break; case '+' : valor3 = valor1+valor2; break; case '-' : valor3 = valor1-valor2; } AnadeP(&P,valor3); } else { valor3 = valor(post[i]); AnadeP(&P,valor3); } valor1 =PrimeroP(P); BorrarP(&P); return valor1; }

10.4
#include <stdio.h> #include <stdlib.h> enum Tpalo {oros, copas, espadas, bastos};

Pilas y sus aplicaciones

enum Tvalor { as, dos, tres, cuatro, cinco, seis, siete, sota, caballo, rey}; struct Tcarta { Tpalo palo; Tvalor valor; } ; typedef Tcarta TipoElemento; typedef struct unnodo { TipoElemento e; struct unnodo *sig; }Nodo; typedef Nodo Pila; typedef Pila Pila_de_Cartas ; void Barajar_Las_Cartas(int a[40]) { int aux[40], i, j, k, h; for (i = 0; i < 40; i++) aux[i] = i; j = 40; i = 0; randomize(); while ( j > 0) { k = random(j); a[i] = aux[k]; i++; for (h = k; h < j - 1; h++) aux[h] = aux[h + 1]; j --; } } void EscribeCarta(Tcarta ca) { printf("%3d",(ca.palo-oros)*10 + ca.valor-as); } void LeeCarta(Tcarta *ca, int i ) { /*Trasforma el nmero entero i en una carta */ int num1, num2, j; /*Cada nmero contiene dos dgitos que corresponden con el palo y le valor de carta*/ num1 = i % 10; num2 = i/ 10; ca->palo = oros; for (j = 0; j < num2; j++) ca->palo++; ca->valor = as; for (j = 0; j < num1; j++) ca->valor++; } void LeeMazo(Pila_de_Cartas ** maz,int n[40]) {

/*Se encarga de barajar las cartas */

Algoritmos y estructuras de datos. Una perspectiva en C. Libro de Problemas

Tcarta car; int i; VaciaP(maz); printf("mazo\n"); for (i = 0; i < 40; i++) { LeeCarta(&car, n[i]); EscribeCarta(car);AnadeP(maz, car); }; printf("fin mazo\n"); } void ColocaCarta(Pila_de_Cartas **des, Pila_de_Cartas * mon[4], int *coloca) { /*Coloca todas las cartas que puede dedescartes en los montones de las bases*/ int Seguimos, Valida; /*continua colocando y puede colocarse*/ Tcarta car; /*carta de descartes */ Tcarta ultima; /* carta de las bases*/ Seguimos = 1; /*Mientras haya cartas en descartes y debamos seguir*/ while (! EsVaciaP(*des)&& Seguimos) { car = PrimeroP(*des); if (EsVaciaP(mon[car.palo])) Valida = car.valor == as; /*la base est vaca. Se valida que sea un as*/ else { /*la base tiene cartas.Valida si es la siguiente a la ltima*/ ultima = PrimeroP(mon[car.palo]) ; Valida = ultima.valor+1== car.valor; } if (Valida) { /*Pasa carta a la base y se sigue */ printf("se coloca carta"); EscribeCarta(car);printf("\n"); AnadeP(&(mon[car.palo]), car); BorrarP(des); *coloca = 1; } else Seguimos = 0; } } void DaVuelta( Pila_de_Cartas **Monton, Pila_de_Cartas **Descartes) { /*a la vuelta a la pila d en la pila m */ Tcarta Car; while (! EsVaciaP(*Descartes)) { Car=PrimeroP(*Descartes); /*extrae carta del montn de descartes */ EscribeCarta(Car); BorrarP(Descartes); AnadeP(Monton, Car); /*Inserta la carta en el mazo*/ } } void main(void)

Pilas y sus aplicaciones

{ Pila_de_Cartas *Monton,*Descartes, *mon[4];/*mazo descartes y bases*/ int FinDelSolitario, Colocada, AlgunaColocada, i; Tcarta CartaAux; /*auxiliar para cartas*/ int Numeros_de_Cartas[40]; /*vector con cartas barajadas*/ Barajar_Las_Cartas(Numeros_de_Cartas); for (i = 0 ; i < 4; i++) /*Pone las bases vacias */ VaciaP(&mon[i]); LeeMazo(&Monton, Numeros_de_Cartas); /*Realiza la lectura inicial del mazo*/ FinDelSolitario = 0; while (! FinDelSolitario) { VaciaP(&Descartes); Colocada = 0; AlgunaColocada = 0; while (! EsVaciaP(Monton)) { /*Pasa una pareja al montn de descartes. Si solo hay una debe pasarla*/ CartaAux=PrimeroP(Monton); BorrarP(&Monton); AnadeP(&Descartes, CartaAux); if (!EsVaciaP(Monton)) { CartaAux = PrimeroP(Monton); BorrarP(&Monton); AnadeP(&Descartes, CartaAux); } ColocaCarta(&Descartes, mon, &Colocada); /*pasa cartas a las bases*/ AlgunaColocada = AlgunaColocada || Colocada; } printf("\n vuelta al mazo\n"); DaVuelta(&Monton, &Descartes); printf("\n"); FinDelSolitario = !AlgunaColocada ||EsVaciaP(Monton); } if (EsVaciaP(Monton)) printf(" solitario realizado\n"); else printf(" solitario fallido\n"); }

10.5
void DestruyeLista(Lista { Lista *Auxiliar; while (*p != NULL) { Auxiliar = *p; (*p) = (*p)->sig; free(Auxiliar); } } **p)

void EscribeListaAlReves(Lista *p) { if (p!=NULL)

/*escribe la pila al revs

recursivamente*/

Algoritmos y estructuras de datos. Una perspectiva en C. Libro de Problemas

{ EscribeListaAlReves(p->sig); printf("%c",p->el); } } void SumarListasDeNumeros (Lista **Total, Lista *Sumando) { /* Total y sumando nunca son vacios*/ int acarreo, el ; Lista *Nuevo, *TotalAux, *AntetiorTotal, *s; printf("Total parcial:"); EscribeListaAlReves (*Total); printf("\n'Sumando: \n"); EscribeListaAlReves(Sumando); printf("\n"); acarreo = 0; TotalAux = *Total; AntetiorTotal = NULL; s = Sumando; while ((TotalAux != NULL) && (s != NULL)) { /* suma de los dos*/ el = TotalAux->el + s->el + acarreo - 2 * 48; TotalAux->el = el% 10 + 48; acarreo = el / 10; AntetiorTotal = TotalAux; TotalAux = TotalAux->sig; s = s->sig; } while (s !=NULL) { /* suma de s*/ el = s->el - 48 + acarreo; Nuevo =(Lista*)malloc(sizeof(Lista)); Nuevo->el = el % 10 + 48; acarreo = el / 10; Nuevo->sig = NULL; AntetiorTotal->sig = Nuevo; AntetiorTotal = Nuevo; s = s->sig; } while (TotalAux !=NULL) { /* suma de TotalAux*/ el = acarreo + TotalAux->el - 48; acarreo = el / 10; TotalAux->el = el %10 + 48; AntetiorTotal = TotalAux; TotalAux = TotalAux->sig ; } if (acarreo == 1) { Nuevo =(Lista*)malloc(sizeof(Lista)); Nuevo->el = '1'; Nuevo->sig = NULL; AntetiorTotal->sig = Nuevo; } printf("Nuevo Total Parcial: \n"); EscribeListaAlReves(*Total); printf("\n"); } void main (void)

Pilas y sus aplicaciones

{ Lista *Total, *Sumando; FILE *f; char el ; if ((f = fopen("numeros.dat","r+t")) == NULL) { puts("error de apertura texto"); exit(1); } Total = NULL; Sumando = NULL; if (!feof(f)) { el = getc(f); while (el != '\n') /*fin de linea*/ { AnadeP(&Total,el); el = getc(f); } EscribeListaAlReves(Total); printf(" primer paso\n"); while (!feof (f)) { el = getc(f); while (el != '\n') { AnadeP(&Sumando,el); el = getc(f); } SumarListasDeNumeros (&Total, Sumando); DestruyeLista (&Sumando); } } else printf("Fichero de datos vaco"); fclose (f); }

/* fin de linea*/

10.6
void Hanoi(int n, int d, int h, int u) { if (n == 1) printf(" llevo disco %3d del palo %3d al palo %3d\n",n,d,h); else { Hanoi(n - 1, d, u, h); printf(" llevo disco %3d del palo %3d al palo %3d\n",n,d,h); Hanoi(n - 1, u, h, d) ; } } void Hanoinr(int n, int d, int h,int { u)

10

Algoritmos y estructuras de datos. Una perspectiva en C. Libro de Problemas

elemento e, e1; Pila *p; VaciaP(&p); e.n =n ; e.d = d; e.h = h; e.u = u; e.estado = uno; AnadeP(&p, e); while (! EsVaciaP(p)) { e = PrimeroP(p); BorrarP(&p); switch (e.estado) { case uno: { if (e.n == 1) printf(" llevo disco %3d del palo %3d al palo %3d\n",e.n,e.d,e.h); else { e1.n = e.n-1; e1.estado = uno; e1.d = e.d; e1.h = e.u; e1.u = e.h; e.estado = dos; AnadeP(&p, e); AnadeP(&p, e1); } break; } case dos: { printf(" llevo disco %3d del palo %3d al palo %3d\n",e.n,e.d,e.h); e1.n = e.n - 1; e1.estado = uno; e1.d = e.u; e1.h = e.h; e1.u = e.d; AnadeP(&p, e1); } } } } void main(void) { Hanoinr(4, 1, 2, 3); }

10.7
#define n 5

Pilas y sus aplicaciones

11

enum Estados {Ninguno, Incluido, Excluido} ; struct elemento { Estados estado; } ; typedef elemento TipoDato; int Pesos[n], OabjetivoAalcanzar; void Inicializa() { Pesos[0]= 7; Pesos[1] = 5; Pesos[2] = 4; Pesos[3] = 4; Pesos[4] = 1; OabjetivoAalcanzar = 10; } void MochilaExacta(int OabjetivoAalcanzar,int i, int *Solucion) { int Encontrado, Posibilidad; /*Se termina con xito siObjetivo=0 o bien con fallo sio Objetivo<0 o bien i=n*/ if (( OabjetivoAalcanzar <= 0) || (i== n)) if (OabjetivoAalcanzar == 0 ) /*solucin*/ *Solucion = 1; else ; /*no hacer nada porque Objetivo<0 o bien i=n*/ else { Posibilidad = 0; Encontrado = 0;; do { Posibilidad ++; switch (Posibilidad) { case 1: /*Inclusin*/ MochilaExacta(OabjetivoAalcanzar-Pesos[i], i+1, &Encontrado); if( Encontrado) printf("%d ",Pesos[i]); *se ha inluido y se tiene solucin*/ break; case 2: /*exclusin*/ MochilaExacta(OabjetivoAalcanzar, i+1, &Encontrado); /*aunque Encontrado sea verdadero, no hace falta hacer nada*/ } } while (!((Posibilidad == 2) || Encontrado)); *Solucion = Encontrado; } } void MochilaExacta_N_R(int OabjetivoAalcanzar) { int i, Solucion; Pila *P; elemento e, e1; i = 0; Solucion = 0; e.estado = Ninguno; VaciaP(&P);

12

Algoritmos y estructuras de datos. Una perspectiva en C. Libro de Problemas

AnadeP(&P, e); /*Asigna el valor inicial a la pila P considerando Pesos[0]*/ while (! EsVaciaP(P)) { e = PrimeroP(P); BorrarP(&P); if (Solucion) /*si se tie ne ya una solucin entonces escribirla*/ { if (e.estado == Incluido) printf("%d \n",Pesos[i]); /*{solo se escribe algo si est incluido*/ i --; /*retrocede*/ } else /*solucion es false*/ if (((OabjetivoAalcanzar <= 0) && (e.estado == Ninguno)) || (i == n)) { if (OabjetivoAalcanzar == 0) Solucion = 1; /*siempre se obtiene solucin*/ i --; /*el i no se ha probado. Se retrocede en la recursividad*/ } else /*no hay decisin se considera el estado del candidato actual*/ switch (e.estado) { case Ninguno: /*Primero se incluye avance de la recursividad*/ OabjetivoAalcanzar -= Pesos[i]; i ++; e1.estado=Incluido; AnadeP(&P, e1); e1.estado = Ninguno; AnadeP(&P, e1); /* se va al comienzo*/ break; case Incluido: /*Ahora se excluye avance de la recursividad*/ /*se retrocede i--; en opcin else de q*/ OabjetivoAalcanzar += Pesos[i]; /*como se quit hay que sumarlo*/ i ++; e1.estado=Excluido; AnadeP(&P, e1); e1.estado=Ninguno; AnadeP(&P, e1); break; case Excluido: /*la eleccin actual no dio resultado se ha terminado la recursividad*/ i--; } } } void main (void) { int Solucion; Inicializa(); MochilaExacta(OabjetivoAalcanzar, 0, &Solucion); if( Solucion) printf("Solucin dada para Objetivo = %d \n", OabjetivoAalcanzar); Solucion = 0; OabjetivoAalcanzar = 10; MochilaExacta_N_R(OabjetivoAalcanzar);

Pilas y sus aplicaciones

13

if (Solucion) printf(" se encontr solucin"); }

10.8.
#define nn 8 enum Estados {uno, dos} ; struct elemento { Estados Estado; int Posibilidad; }; typedef elemento TipoElemento; int Contador, i, j, x, y, DespX[8],DespY[8],Tablero[8][8], n ,nCuadrado; void Escribesolucion() { int i, j; for(i = 0; i < n; i++) { for (j = 0; j < n; j++) printf("%5d",Tablero[i][j]); printf("\n"); }; printf("solucin %3d\n",Contador); }; void ensayartodas() { int Posibilidad = -1; do { Posibilidad++; x += DespX[Posibilidad]; y += DespY[Posibilidad]; if ((x < n) && (y < n) && (x >= 0) && (y >= 0)) if (Tablero[x][y] == 0) { Tablero[x][y ] = i; if (i < nCuadrado) { i ++; ensayartodas(); i --; } else { Escribesolucion(); Contador++; } Tablero[x][y] = 0; } x -= DespX[Posibilidad]; y -= DespY[Posibilidad]; }

14
}

Algoritmos y estructuras de datos. Una perspectiva en C. Libro de Problemas

while(Posibilidad<8-1);

void ensayartodasnr() { int Posibilidad,colocado; Pila *P; elemento e, e1; VaciaP(&P); e.Posibilidad = -1; e.Estado = uno; AnadeP(&P, e); while (! EsVaciaP(P)) { e1=PrimeroP(P); BorrarP(&P); e = e1; switch (e.Estado) { case uno: { Posibilidad = e.Posibilidad; colocado = 0; while (! colocado && (Posibilidad < 8-1)) { Posibilidad++; x += DespX[Posibilidad]; y +=DespY[Posibilidad]; if ((x < n) && (y < n) && (x >= 0) && (y >= 0)) if (Tablero[x][y] == 0) colocado = 1; if (! colocado) { x -= DespX[Posibilidad]; y -= DespY[Posibilidad]; } } if (colocado) { Tablero[x][y] = i; if (i == nCuadrado) { Escribesolucion(); Contador ++; e.Estado = dos; e.Posibilidad = Posibilidad; i ++; AnadeP(&P, e); } else { e.Estado = uno; e.Posibilidad = Posibilidad; AnadeP(&P, e); e.Estado = dos;

Pilas y sus aplicaciones

15

e.Posibilidad = Posibilidad; AnadeP(&P, e); e.Estado = uno; e.Posibilidad = -1; AnadeP(&P, e); i ++; } } break; } case dos: { Posibilidad = e.Posibilidad; Tablero[x][y] = 0; i --; x -= DespX[Posibilidad]; y -= DespY[Posibilidad]; } } } } void main(void) { printf("valor de n "); scanf("%d",&n); nCuadrado = n * n; DespX[0] = 2; DespY[0] = DespX[2] = -1; DespY[2] = DespX[4] = -2; DespY[4] = DespX[6] = 1; DespY[6] = Contador=1; for (i = 0; i < n; i++) for (j = 0;j < n; j++) Tablero[i][j] = 0; Tablero[0][0] = 1; i = 2; x = 0; y = 0; /*ensayartodasnr();*/ ensayartodas(); }

1; 2; -1; -2;

DespX[1] DespX[3] DespX[5] DespX[7]

= 1; = -2; = -1; = 2;

DespY[1] DespY[3] DespY[5] DespY[7]

= = = =

2; 1; -2; -1;

Das könnte Ihnen auch gefallen