Ejercicios_Resueltos_Pilas

12
PREGUNTAS 1. Cual es la salida del siguiente programa main() { int i; Stack*st = stackNew(); Stack*s=stackNew(); for (i = 0; i <=10; i++) { stackPush(st, nodeListNew(integerNew(i%6))); } while (!stackIsEmpty(st)) { stackPush(s, stackPop(s:t)); if (*(int*) nodeListGetCont(stackPeek(s)) % 2) stackPush(s, nodeListNew(integerNew(integerGet(nodeListGetCont(stackPop(s)))*2))); } while (!stackIsEmpty(s)){ printf(“ % d”, integerGet(nodeListGetCont(stackPop(s)))); } } Solución: Tenemos dos pilas, s y st.. Al principio se llena la pila st con enteros. En la siguiente tabla podemos ver los valores que se van ingresando. Valor de i N almacenado en la pila(i%6) 0 0 1 1 2 2 3 3 4 4 5 5 6 0 7 1 8 2 9 3 10 4 Recuerde que en una pila el primer elemento que entra es el ultimo que sale. La siguiente figura representa a la pila st:

description

Ejercicios que requieren el uso de pilas por medio de librerias en C

Transcript of Ejercicios_Resueltos_Pilas

  • PREGUNTAS1. Cual es la salida del siguiente programamain() { int i; Stack*st = stackNew(); Stack*s=stackNew(); for (i = 0; i
  • Siguiendo el flujo de ejecucin vemos que entramos a un ciclo while que terminara hasta que la pila st este vaca. En el cuerpo del ciclo se realizan algunas acciones:Al principio se remueve el tope de la pila st (numero 4) y se ingresa a la pila s. Ya que 4%2 es igual a cero no se cumple la condicin para entrar al condicional. Recordar que la instruccin stackPeek(s) nos retorna una referencia al tope de la pila s.Veamos la otra iteraccion, ahora se remueve el 3 de la pila st y lo metemos en la pila s. Ya que 3%2 es igual a uno, entramos al condicional. Bsicamente lo que se hace aqu es lo siguiente: Se remueve el tope de la pila, obtenemos el valor del nodo(numero 3) y lo multiplicamos por dos, obtenemos el 6 que sera el nuevo numero ingresado en la pila.En la siguiente iteraccion, se toma el 2 de la pila st y se ingresa en la pila s. Ya que 2%2 es cero no entramos al condicional. Se sigue iterando.El siguiente elemento a ingresar es el uno. Notar que 1%2 es igual a uno, entramos al condicional. Se remueve el tope de la pila, obtenemos el valor del nodo(numero 1) y lo multiplicamos por dos, obtenemos el 2 que sera el nuevo numero ingresado en la pila.Hacemos esto hasta que st quede vaca.Al final se imprimen los valores almacenados por s. Antes de ver cual es la respuesta, intente seguir el flujo de ejecucin y obtener su propio resultado.

    Resultado: 0 2 2 6 4 10 0 2 2 6 4

    2. Dado el siguiente bloque de pseudo-codigo indique que salidas en pantalla son posibles. La funcion RanFun retorna TRUE o FALSE de forma aleatoria.

    count= 0While (count < 5) {

    count = count + 1if (RanFun())

    Print countelse

    Push(myStack, count) }

    While (! IsEmpty(myStack)){ number=Pop(myStack)

    Print number }

    Salida en pantalla Si No

    1 3 5 2 41 3 5 4 21 3 5 1 31 2 3 4 5

    Supongamos que RanFun retorno TRUE en todas las iteraciones entonces la salida sera : 1 2 3 4 5 , entonces la ultima opcion es correcta.Ahora observe las tres opciones restantes. Es claro notar que los tres primeros numeros son los mismos (1 3 5). Para que esto ocurra sucedio lo siguiente:En la primera iteraccion, cont=1 y RanFun fue TRUE. Se imprime 1 en pantalla. La pila myStack esta vacia

    En la segunda iteraccion, cont=2, RanFun tuvo que retornar FALSE, se almacena el valor de cont en la pila myStack.

  • En la tercera iteracion, cont=3, RanFun devuelve de nuevo TRUE. Se imprime el 3 en pantalla

    En la cuarta iteracion, cont=4, RanFun fue FALSE, se almacena el valor de cont en la pila myStack.

    En la quinta y ultima iteracion, cont=5, RanFun fue TRUE. Se imprimime el 5 en pantalla.

    Ahora se remueve los elementos de la pila y se imprimen en pantalla.

    Vemos que es imposible que ocurra la primera y la tercera opcin. La salida corresponde a la opcion dos, entonces tenemos:

    Salida en pantalla Si No1 3 5 2 4 X1 3 5 4 2 X1 3 5 1 3 X1 2 3 4 5 X

  • 3. Cul es el tamao mximo de elementos que se puede almacenar en una pila?Una pila implementada con una lista enlazada simple no posee un limite en particular, este depende de cuanta memoria libre exista en el computador. Podemos ingresar tantos elementos como necesitemos y as mismo removerlos si es necesario.La implementacin de una pila con arreglos estticos, limitara el tamao de la pila al tamao que hayamos declarado para el arreglo.

    Problemas1.- Escriba una funcin que determine si una cadena es un palndromo (es decir, que la cadena se deletree en forma idntica, tanto al revs como al derecho). Una cadena es palndromo si se deletrea de la misma forma, tanto al revs como al derecho. El prototipo de nuestra funcion es int esPalindromo(char cadena[]); que devuelve 1 si cadena es palindromo y 0 si esto no es cierto. Lo que vamos a hacer es encontrar la cadena inversa del arreglo cadena que recibimos por parmetro. De esta forma lo nico que nos bastara es comparar si estas dos cadenas son iguales para poder dar un resultado. Para invertir la cadena vamos a usar una pila.

    Codigo:int esPalindromo(char cadena[]){ Stack*pila=stackNew(); char *caracter=cadena; NodeList*p; int i=0; char *cadena_invertida=(char*)malloc(sizeof(char)*strlen(cadena));//se separa un bloque de memoria (del mismo tamao que la cadena original) para almacenar la cadena invertida while(*caracter!='\0'){ stackPush(pila,nodeListNew(charNew(*caracter)));//se llena una pila con cada carcter de cadena caracter++; } i=0; while(!stackIsEmpty(pila)){ p=stackPop(pila); cadena_invertida[i]=charGet(nodeListGetCont(p));//se forma la cadena invertida i++; } cadena_invertida[i]='\0';//caracter de fin de cadena if(strcmp(cadena,cadena_invertida)==0){ return 1; }else{ return 0; }}

  • 2.- Usted debe implementar una funcin que consiste en una simulacin que baraja un mazo de cartas.Inicialmente, el mazo de cartas tiene 52 cartas y tiene que ser dividido en dos grupos. La divisin de cartas ser elegida aleatoriamente.Posteriormente, un nuevo mazo se forma eligiendo la primera carta de un grupo y luego la primera carta del otro grupo hasta que se terminen las cartas de uno o de los dos grupos. Si un grupo de cartas se termina, las cartas del otro grupo continuaran colocando en el mazo como se mencion previamente.

    Solucin:Podemos representar el mazo de cartas como una Pila. Escogemos este TDA para no alejarnos de la nocin real que tenemos de un mazo de cartas, en donde la ultima carta almacenada en el mazo seria la primera que podramos tomar.No nos especifican el prototipo de la funcin que vamos a implementar as que podemos asumir algunos detalles para hacer el problema ms sencillo. Nuestra funcin recibir como parmetro una Pila donde se almacenaran las referencias a las 52 cartas. La funcin tambin deber retornar una nueva pila con las cartas barajadas. El prototipo podra ser: Stack *MazoBarajado(Stack*Mazo);Observe que no nos piden representar la estructura de la carta, ni llenar el mazo con las cartas, simplemente asumimos que tenemos la pila mencionada anteriormente.La figura a continuacin representa a la variable Mazo que hace referencia a la pila de cartas con la que vamos a trabajar.

    C1,C2,C3,...C52 representan las cartas del mazoDentro de la funcin declaramos dos Pilas que representaran los mazos en los que se divide el mazo inicial (52 cartas).Recordar que la divisin debe ser aleatoria, es decir que si el mazo uno tiene un tamao x, el mazo dos tendr un tamao 52-x tal como lo podemos ver en la siguiente figura:

  • X ser el nmero aleatorio generado por nuestro programa donde 0
  • Stack*mazoBarajado=stackNew(); NodeList *it = NULL; int x, i = 0, flag = 0; //Division del mazo: x = 1 + rand() % 52; while (!stackIsEmpty(Mazo)) { if (i == x) { it=stackPop(Mazo); stackPush(mazoDos,nodeListNew(nodeListGetCont(it))); }else{ it=stackPop(Mazo); stackPush(mazoUno,nodeListNew(nodeListGetCont(it))); i++; } } i=0; it=NULL; //algoritmo para ingresar las cartas al mazo nuevo de forma alternada while(i>=52){ if(flag==0&&!stackIsEmpty(mazoUno)){//se remueve una carta del primer mazo y se agrega al mazo nuevo it=stackPop(mazoUno); stackPush(mazoBarajado,nodeListNew(nodeListGetCont(it))); flag=1; i++; }else{ if(!stackIsEmpty(mazoDos)){//se remueve una carta del segundo mazo y se agrega al mazo nuevo it=stackPop(mazoDos); stackPush(mazoBarajado,nodeListNew(nodeListGetCont(it))); i++; } flag=0; } //podemos notar que con cambiar el valor de la variable entera flag en cada iteracin ingresamos las cartas de la forma en que nos solicita el problema } return mazoBarajado;}

    3.- El termino blog fue acuado por Jorn Barger en 1997. Un blog tambin conocido como weblog o bitcora, es un sitio web que recopila cronolgicamente artculos de uno o varios autores, apareciendo primero el mas reciente.Habitualmente, en cada articulo, los lectores pueden escribir sus comentarios y el autor darles respuestas de forma que es posible establecer un dialogo.

  • Para facilitar la bsqueda de artculos en los motores de bsqueda (Google,Yahoo,Altavista,etc) se suelen agregar un conjunto de palabras claves a cada articulo, estas palabras claves van en funcin del contenido, representando o asumiendo en una o dos palabras de que se trata el articulo. Por ejemplo si un articulo aborda el tema de Como resolver problemas usando estructuras de datos, las palabras claves podran ser TDA,abstraccin.a) Defina usando lenguaje C, la o los TDA's necesarios para representar el problema anterior.b) Implemente una funcin que dada una palabra clave en un motor de bsqueda, retorne los posibles artculos que tengan relacin. Observe que estos artculos debern estar en orden cronolgico. Asuma que tiene disponible la funcion int textoRelacionado(texto, palabra) ; en donde las variables texto y palabra hacen referencia a una cadena de caracteres o string, esta funcin retorna 1 si el string palabra se encuentra dentro del string texto.c) Implemente un procedimiento que muestre la informacin del articulo mas reciente. Asuma que dispone del procedimiento void mostrarInfo(articulo) que muestra en pantalla la informacin almacenada en un articulo.En el primer prrafo nos describe en que consiste un blog. Resumiendo: un blog es un conjunto de artculos, en donde aparece primero el articulo mas reciente. Para representar esta entidad usaremos una pila que almacene las referencias de los artculos, en donde el ultimo articulo ingresado al blog, sera el primero en verse.Un articulo esta compuesto por texto, tambin tienen un autor. Podemos asumir que cada autor debe tener un nombre que lo caracteriza. Observe que debido al hecho de que los artculos son ingresados cronolgicamente estos deben tener una fecha de publicacin. En el siguiente prrafo nos dicen que los artculos tambin poseen comentarios. Un comentario debe guardar el nombre del usuario que lo ingreso, y una lista de las respuestas que se generan a partir de el.Del ultimo prrafo del problema destacamos que cada articulo posee un conjunto de palabras claves.La funcin que vamos a implementar en la siguiente: List*articulosRelacionados(Blog*blog, String palabra_clave); Lo que vamos a hacer es buscar dentro de la pila de artculos, cuales son los que tienen relacin a palabra_clave. Recuerde que cada articulo posee una lista de palabras claves. Vamos a ir removiendo elemento por elemento de la pila para despus ir verificando si estos elementos forman parte del conjunto solucin que buscamos(artculos relacionados con la palabra clave ingresada en el buscador). Todos los artculos analizados son almacenados temporalmente en otra pila. Esto con e fin de devolverlos a la pila del blog, observe que esta pila se mantiene de la misma forma que al principio, en orden cronolgico. Los artculos que forman parte de la solucin son almacenados en una nueva lista la cual retornaremos al final de la funcin.

    Solucin: typedef char String[1000]; //Hemos definido este tipo de dato String que no es otra cosa que un arreglo de caracteres de tamao 1000typedef struct Blog{ Stack *articulos;}Blog;

    typedef struct Articulo{ String texto; Stack*comentarios; List*palabras_claves; Autor *autor; Fecha fecha_de_publicacion;}Articulo;

    typedef struct Comentario{ List*respuestas; String nombrePublicador;

  • }Comentario;

    typedef struct Autor{ String nombre;}Autor;

    typedef struct Fecha{ int dia,mes,anio;}Fecha;

    List*articulosRelacionados(Blog*blog, String palabra_clave) { NodeList*p, *q; Stack*articulos = blog->articulos; Stack*temporal = stackNew(); List*articulos_relacionados = listNew(); while (!stackIsEmpty(articulos)) { p = stackPop(articulos); Articulo*articulo_actual = (Articulo*) nodeListGetCont(p); q=listSearch(articulo_actual->palabras_claves,palabra_clave,textoRelacionado); if(q!=NULL){ listAddNode(articulos_relacionados,nodeListNew(articulo_actual)); } stackPush(temporal, nodeListNew(articulo_actual));//se almacena articulo_actual de forma

    temporal } while (!stackIsEmpty(temporal)) {// se devuelve los elementos de la pila temporal al blog Articulo*articulo_actual = (Articulo*) nodeListGetCont(stackPop(temporal));//devolvemos los

    articulos al blog stackPush(articulos, nodeListNew(articulo_actual)); } return articulos_relacionados;}Existe una forma mas sencilla de resolver el problema anterior. Recuerde que el TDA Pila ha sido implementado con una Lista enlazada. Esto quiere decir que en la practica podemos iterar y hacer operaciones sobre los elementos de la Pila como lo haramos con cualquier otra Lista enlazada. Desde el punto de vista terico, de la pila solo conocemos su tope y si queremos llegar a algn otro elemento debemos ir removiendo este tope hasta llegar a dicho elemento, tal como ya lo hicimos. Sin embargo mostramos esta solucin como un truco que es factible usar.

    List*articulosRelacionados(Blog*blog, String palabra_clave) { NodeList*p, *q; Stack*articulos = blog->articulos; Stack*temporal = stackNew(); List*articulos_relacionados = listNew(); for(p=listGetHeader(articulos);p!=NULL;p=nodeListGetCont(p)) { Articulo*articulo_actual = (Articulo*) nodeListGetCont(p); q=listSearch(articulo_actual->palabras_claves,palabra_clave,textoRelacionado); if(q!=NULL){ listAddNode(articulos_relacionados,nodeListNew(articulo_actual)); } } return articulos_relacionados;}

    La coleccin de artculos dentro del blog tambin puede ser representada como una lista enlazada ordenada segn la fecha de publicacin, o con una cola de prioridad, donde se desencola en orden cronolgico. Intente implementar la funcin List*articulosRelacionados(Blog*blog, String palabra_clave) usando estas representaciones.

  • La ultima funcin es muy sencilla de implementar, solo necesitamos la referencia al elemento mas reciente, este elemento es el tope de la pila de artculos.

    void mostrarArticuloMasReciente(Blog*blog){ NodeList*p=stackPeek(blog->articulos); mostrarInfo(nodeListGetCont(p));}

    4.- Escriba una funcin que valide si una expresin matemtica tiene sus delimitadores de mbito escritos correctamente y que retorne la posicin en que se encontr el primer error o -1 si es que valida. Para que la expresin sea vlida se deben cumplir 2 condiciones: a) Smbolo que cierra el mbito debe ser del mismo tipo de smbolo que lo abre. b) Existe el mismo nmero de smbolos de apertura y cierre.

    Es muy importante que entendamos que es lo que nos pide resolver el problema, nuestra solucin se limitara a las especificaciones detalladas en la descripcin del mismo. Observe que nos piden implementar una funcin que valide si una expresin matemtica tiene sus delimitadores de mbito escritos de forma correcta. No nos piden evaluar la expresin, ni que verifiquemos que los operados y operadores tengan sentido, esto requerira de un mayor esfuerzo.

    Nuestro objetivo es verificar las condiciones planteadas en el problema. Cuando encontremos un delimitador de apertura debemos verificar que este se cierra, en el orden correcto. Al final tendremos el mismo numero de delimitadores de apertura y cierre.

    Usaremos una pila para resolver el problema, ademas implementaremos las funciones:

    int delimitadorApertura(char caracter); que retorna uno si carcter es un delimitador de apertura y cero si esto no es cierto.

    int esOperando(char caracter); que retorna uno si carcter es un operando (+,-,*,/).

    Nuestra funcin har lo siguiente:

    Vamos a iterar el arreglo de carcter que representa a la expresin matemtica. Llevaremos el control de un contador que representan las posiciones.

    Cuando encontremos un delimitador de apertura, almacenaremos este carcter en una pila auxiliar.

    Para efectos de este problema si leemos un dgito o un operando, los vamos a ignorar como ya detallamos.

    Cuando encontramos un delimitador de cierre, debemos verificar el tope de la pila. El delimitador de cierre debe corresponder al carcter almacenado, si esto no es cierto entonces hemos detectado un error y podemos retornar la posicin en donde encontramos dicho error. Si la correspondencia es correcta entonces removemos el tope de la pila y continuamos analizando.

    Observe que al final la pila debera estar vaca para asegurarnos que la expresin tiene sus delimitadores de mbito correctamente.

    Expresin Resultado

    (A+B] 4

    [(A+B]) 5

    {A-(B]} 5

    (A+{B-C}) -1

  • Cdigo:int validarExpresion(char*ptr) { int i = 0, pos; Stack *pila = stackNew(); Generic g; NodeList *it, *p; char value; while (ptr[i] != '\0') { if (delimitadorApertura(ptr[i])) { stackPush(pila, nodeListNew(charNew(ptr[i]))); } else { if (!isdigit(ptr[i])&&!esOperando(ptr[i])&&!stackIsEmpty(pila)) {//si es delimitador de cierra se verifica que sea el correcto it = stackPeek(pila); g = nodeListGetCont(it); value = charGet(g); if (value == '{' && (ptr[i] == '}')) { p = stackPop(pila); free(p); } else if (value == '(' && (ptr[i] == ')')) { p = stackPop(pila); free(p); } else if (value == '[' && (ptr[i] == ']')) { p = stackPop(pila); free(p); } else { pos = i; break; } } } i++; }

    if (stackIsEmpty(pila)) { return -1; } else { return pos; }}

    int delimitadorApertura(char ptr) { int flag = 1; switch (ptr) {//si es delimitador de apertura se almacena en la pilas case '{': break; case '[': break; case '(': break; default: flag = 0; break; } return flag;

  • }int esOperando(char ptr) { int flag = 1; switch (ptr) {//si es delimitador de apertura se almacena en la pilas case '+': break; case '-': break; case '*': break; case '/': break; default: flag = 0; break; } return flag;}

    Intente agregar las funcionalidades necesarias para validar que los operandos y los operadores se hayan ingresado correctamente.