Sie sind auf Seite 1von 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))));
}
}
Solucin:
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
6
7
8
9
10

5
0
1
2
3
4

Recuerde que en una pila el primer elemento que entra es el ultimo que sale. La
representa a la pila st:

siguiente

figura

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= 0
Salida en pantalla
Si
No
While (count < 5) {
count = count + 1
13524
if (RanFun())
13542
Print count
else
13513
Push(myStack, count)
}
12345
While (! IsEmpty(myStack))
{ number=Pop(myStack)
Print number
}

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
No
1
1
1
1

3
3
3
2

5
5
5
3

2
4
1
4

4
2
3
5

X
X
X
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.
Problemas
1.- 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 mazo


Dentro 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<X<52.


El algoritmo para barajar el mazo consiste en lo siguiente: Se remueve el 1er elemento de la
primera pila, y se inserta en una pila nueva. Ahora se remueve el 1er elemento de la segunda pila,
y tambin se inserta en la pila nueva. Se hace esto hasta que las cartas de las dos pilas se
acaben. La siguiente figura ilustra
el nuevo mazo barajado.

Al final retornamos la pila nueva que hemos generado.

Codigo:
Stack *MazoBarajado(Stack*Mazo) {
Stack*mazoUno = stackNew();
Stack*mazoDos = stackNew();

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 1000
typedef 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.
Expresin

Resultado

(A+B]

[(A+B])

{A-(B]}

(A+{B-C}) -1
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.

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.

Das könnte Ihnen auch gefallen