parc120140918.cpp
#include <cstdio>
#include <cstdlib>
#include <stack>
#include <list>
#include <map>
#include "./util.h"
using namespace std;
/* COMIENZO DE DESCRIPCION
__USE_WIKI__
stack-sep: Dada una pila #S#, escribir una funcion que deja en el tope los
elementos pares y en el fondo los impares. El algoritmo
debe ser *estable* es decir que los pares deben estar en el mismo
orden entre si y los impares tambien.
exists-path: Dado un mapa #M# que representa un grafo
dirigido, y dos nodos #m#, #n# determinar si existe un camino
que va del vertice #m# al #n#.
extractm: Dada una lista #L#, y un entero #m#, escribir
una funcion
#void extractm(list<int> &L,int m,list<int> &Lm);#
que genere una lista #Lm# con todos los elementos
que aparecen exactamente #m# veces en #L#.
[Tomado en el 1er parcial de 2014-09-18].
keywords: lista, correspondencia
FIN DE DESCRIPCION */
//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
void stacksep(stack<int> &S) {
// Usa pilas auxiliares S1 S0,
// pero no usa "memoria adicional", ya que
// a medida que la suma de los tamanos de
// S, S1, y S0 es n.
stack<int> S1, S0;
// Va sacando elementos S y los pone en S1,S0
// Quedan invertidos en S0, S1
while (!S.empty()) {
int x = S.top();
S.pop();
if (x%2) S1.push(x);
else S0.push(x);
}
// Pasa los elementos de S1 a S.
// El orden es importante ya que si no quedan al reves.
while (!S1.empty()) {
S.push(S1.top());
S1.pop();
}
// Pasa los elementos de S1 a S.
while (!S0.empty()) {
S.push(S0.top());
S0.pop();
}
}
//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
// Esta version es un poco mas compacta
// Hace el paso de S0,S1 a S con el mismo lazo
// usando referencias
void stacksep2(stack<int> &S) {
stack<int> S1, S0;
while (!S.empty()) {
int x = S.top();
S.pop();
if (x%2) S1.push(x);
else S0.push(x);
}
// Para j=0 transpasa de S1, y para j=1 desde S0
for (int j=0; j<2; j++) {
stack<int> &Sfrom = (j==0? S1 : S0);
// Pasa los elementos de Sfrom a S.
// El orden es importante ya que si no quedan al reves.
while (!Sfrom.empty()) {
S.push(Sfrom.top());
Sfrom.pop();
}
}
}
//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
// Funcion auxiliar, imprime el contenido de una pila
void prints(stack<int> &S,const char *lab=NULL) {
if (lab) printf("%s: ",lab);
stack<int> S2=S;
while (!S2.empty()) {
printf("%d ",S2.top());
S2.pop();
}
printf("\n");
}
//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
void extractm(list<int> &L,int m,list<int> &Lm) {
// Freq: elementos unicos en L -> cantidad de veces que aparece en L
map<int,int> Freq;
Lm.clear();
// Recorre los elementos de L y los cuenta en Freq
list<int>::iterator q = L.begin();
while (q!=L.end()) Freq[*q++]++;
// Recorre Freq e inserta en Lm los que tienen conteo m
map<int,int>::iterator r = Freq.begin();
while (r!=Freq.end()) {
if (r->second==m) Lm.push_back(r->first);
r++;
}
}
//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
int main() {
// Genera una pila con [0,N)
stack<int> S;
printf("\nstacksep, ejemplo 1 --------------\n");
int N=10;
for (int j=0; j<N; j++) S.push(j);
prints(S,"S");
stacksep(S);
// stacksep2(S); // Es equivalente
prints(S,"stacksep(S)");
for (int j=0; j<5; j++) {
printf("\nstacksep, ejemplo 2.%d --------------\n",j+1);
stack<int> S2;
for (int j=0; j<N; j++) S2.push(rand()%30);
prints(S2,"S2");
// stacksep(S2);
stacksep2(S2); // Es equivalente
prints(S2,"stacksep(S2)");
}
for (int j=0; j<5; j++) {
printf("\nextractm, ejemplo %d --------------\n",j+1);
list<int> L;
int M = 20;
for (int j=0; j<M; j++)
L.push_back(rand()%10);
printf("L: ");
printl(L);
for (int m=1; m<M; m++) {
list<int> Lm;
extractm(L,m,Lm);
if (!Lm.empty()) {
printf("repetidos %d veces: ",m);
printl(Lm);
}
}
}
return 0;
}
Generated by GNU Enscript 1.6.6.