incall.cpp
// $Id$
/*
COMIENZO DE DESCRIPCION
__USE_WIKI__
Dados #n# conjuntos #A_0#, #A_1#, ... #A_{n-1}# determinar si
alguno de ellos (digamos #A_j# ) incluye a todos los otros.
Es decir #A_j\subset A_k# para todo #k#. En ese caso,
retornar el indice #j#, si no retornar -1.
#int includes_all(vector< set<int> > &setv);#
[Tomado en tercer parcial 22-NOV-2007].
keywords: conjunto
FIN DE DESCRIPCION */
// -----------------------------------------------------------------
#include <iostream>
#include <vector>
#include <set>
#include <cassert>
#include "./util.h"
using namespace std ;
//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
int includes_all(vector< set<int> > &setv) {
int j=0, n=setv.size();
// Busca el conjunto candidato `j' con MAYOR cantidad de
// elementos. Si algun conjunto satisface la condicion
// del enunciado, entonces DEBE SER el `j'.
for (int k=0; k<n; k++)
if (setv[k].size()>setv[j].size()) j=k;
// Para cada conjunto `k' verifica
// que setv[k] este INCLUIDO en setv[j].
// En este caso lo hace recorriendo todos
// los elementos de setv[k]
set<int> &sj = setv[j];
for (int k=0; k<n; k++) {
set<int> &s = setv[k];
set<int>::iterator q = s.begin();
while (q!=s.end()) {
if (sj.find(*q)==sj.end()) return -1;
q++;
}
}
return j;
}
//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
int included_in_all(vector< set<int> > &setv) {
// Similar a `includes-all' pero ahora busca si uno de los
// conjuntos esta INCLUIDO en todos los otros.
// Busca el conjunto candidato `j' con MENOR cantidad de
// elementos. Si algun conjunto satisface la condicion
// del enunciado, entonces DEBE SER el `j'.
int j=0, n=setv.size();
for (int k=0; k<n; k++)
if (setv[k].size()<setv[j].size()) j=k;
// Para cada conjunto `k' verifica
// que setv[k] INCLUYA A setv[j].
// En este caso lo hace recorriendo todos
// los elementos de setv[j]
set<int> &sj = setv[j];
for (int k=0; k<n; k++) {
set<int> &sk = setv[k];
set<int>::iterator q = sj.begin();
while (q!=sj.end()) {
if (sk.find(*q)==sk.end()) return -1;
q++;
}
}
return j;
}
//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
int includes_all2(vector< set<int> > &setv) {
// Esta version se basa en OPERACIONES BINARIAS
// de conjuntos, esto es verifica que setv[k] este
// incluido en setv[j] usando `set_difference'
int j=0, n=setv.size();
// Busca el conjunto candidato `j' con MAYOR cantidad de
// elementos. Si algun conjunto satisface la condicion
// del enunciado, entonces DEBE SER el `j'.
for (int k=0; k<n; k++)
if (setv[k].size()>setv[j].size()) j=k;
// Para cada conjunto `k' verifica que `setv[j]' este
// incluido en `setv[k]' usando `set_difference()'
set<int> tmp;
for (int k=0; k<n; k++) {
set_difference(setv[k],setv[j],tmp);
if (!tmp.empty()) return -1;
}
return j;
}
//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
int included_in_all2(vector< set<int> > &setv) {
// Similar a `includes-all' pero ahora busca si uno de los
// conjuntos esta INCLUIDO en todos los otros.
// Esta version se basa solamente en operaciones de
// conjuntos, esto es verifica que setv[k] incluya
// a setv[j] usando `set_diference'
// Busca el conjunto candidato `j' con MENOR cantidad de
// elementos. Si algun conjunto satisface la condicion
// del enunciado, entonces DEBE SER el `j'.
int j=0, n=setv.size();
for (int k=0; k<n; k++)
if (setv[k].size()<setv[j].size()) j=k;
// Para cada conjunto `k' verifica
// que setv[k] incluya a setv[j].
set<int> tmp;
for (int k=0; k<n; k++) {
set_difference(setv[j],setv[k],tmp);
if (!tmp.empty()) return -1;
}
return j;
}
//--------------------------------------------------------------------
int main() {
int N=10, m=4, NN=100, ok=0, okk=0, J, J2, JJ, JJ2;
for (int l=0; l<NN; l++) {
printf("------------------------\n");
vector< set<int> > setv(N);
// Genera `N' conjuntos aleatorios con `m' elementos
// escogidos aleatoriamente en [0,m). Para eso
// recorre todos los elementos de [0,m) y "tira la moneda"
// (rand()%2) para ver si lo incluye o no.
for (int j=0; j<N; j++) {
printf("setv[%d] = {",j);
for (int k=0; k<m; k++) {
if (rand()%2) {
setv[j].insert(k);
printf("%d ",k);
}
}
printf("}\n");
}
J = includes_all(setv);
J2 = includes_all2(setv);
JJ = included_in_all(setv);
JJ2 = included_in_all2(setv);
printf("set[J] that includes all: J=%d, "
"included by all JJ %d\n",
J,JJ);
// Verifica que los dos algoritmos den el mismo resultado
assert(J==J2);
assert(JJ==JJ2);
ok += (J>=0);
okk += (JJ>=0);
}
printf("total %d, had superset of all %d, rate %f\n",
NN,ok,float(ok)/NN);
printf("had subset of all %d, rate %f\n",
okk,float(okk)/NN);
}
Generated by GNU Enscript 1.6.6.