conjunto2.cpp

// $Id$

/*
  COMIENZO DE DESCRIPCION

Diversas operaciones con conjuntos:
disjuntos: verifica si una serie de conjuntos son disjuntos entre si. 
cubre_todo: verifica si un dado conjunto W cubre incluye a toda una
     serie de conjuntos Si.
todos_pares: verifica si todos los elementos de un conjunto son pares. 
Keywords: conjunto, lista

  FIN DE DESCRIPCION */

#include <iostream>
#include <list>
#include "../aedsrc/setl.h"
#include "./util.h"

using namespace std;
using namespace aed;

//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>---: 
//
//     AUXILIARES
//
// Hace un vector random insertando N elementos al azar entre 0 y M-1
// Guarda que el conjunto final puede tener menos de N elementos
// ya que varios de los elementos insertados pueden coincidir entre si. 
void make_random_set(set<int> &s,int N,int M) {
  s.clear();
  for (int j=0; j<N; j++) 
    s.insert(irand(M));
}

// Imprime el conjunto
template <class T>
void prints (set <T> & S) {
  typename set <T> :: iterator p ;
  p = S.begin ();
  while (p != S.end ()) cout << *p++ << " ";
  cout << endl;
}

//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>---: 
// Escribir una funcion predicado bool disjuntos(v)
// que verifica si todos los conjuntos dentro del vector
// de conjuntos v[] son disjuntos 
bool disjuntos(vector< set<int> > &v) {
  int n = v.size();
  // Dos lazos anidados que recorren los pares de conjuntos.  para
  // cada par debemos verificar que la interseccion de los dos
  // conjuntos sea vacia.  Por supuesto si no hace falta verificar j,k
  // y k,j ya que el resultado de la interseccion es independiente del
  // orden.  Sobre todo debe evitarse que verifique al conjunto
  // consigo mismo (es decir el caso j=k) ya que en ese caso la
  // interseccion daria no vacia, (a menos que el conjuntos sea nulo).
  for (int j=0; j<n-1; j++) {
    for (int k=j+1; k<n; k++) {
      set<int> tmp;
      set_intersection(v[j],v[k],tmp);
      if (!tmp.empty()) { 
	cout << j << " y " << k << " no son disjuntos!!\n";
	return false;
      }
    }
  }
  return true;
}

// Escribir una funcion predicado cubre_todo(v,W) que verifica
// si todos los conjuntos en el vector de conjuntos v estan
// incluidos en W. 
bool cubre_todo(vector< set<int> > &v,set<int> W) {
  // Primero hacemos la union de todos los conjuntos en
  // v `todo_v' y despues hacemos la diferencia dif = todo_v - W
  // Si esta diferencia es no vacia entonces quiere decir que
  // hay al menos un elemento en los v[j] que no esta en W. 
  int n = v.size();
  set<int> todo_v,tmp,dif;
  for (int j=0; j<n; j++) {
    set_union(v[j],todo_v,tmp);
    todo_v = tmp;
  }
  set_difference(todo_v,W,dif);
  if (!dif.empty()) {
    cout << "elementos no contenidos en W: ";
    prints(dif);
  }
  return dif.empty();
}

int main () {
  // verifica `disjuntos'. Crea un vector de conjuntos aleatorio.  los
  // imprime y verifica si son disjuntos o no. Lo repite varias veces.
  int N = 10;
  vector< set<int> > v(N);
  for (int k=0; k<10; k++) {
    for (int j=0; j<N; j++) {
      make_random_set(v[j],3,1000);
      cout << "S_" << j << ": ";
      prints(v[j]);
    }
    cout << "disjuntos? " << (disjuntos(v) ? "si" : "no") << endl;
  }

  // verifica `cubre_todo'. Crea un vector W insertando 200 enteros
  // entre 0 y 100. (Notar que no necesariamente W contendra a todos
  // los enteros del 0 al 100). Despues genera un vector con 3
  // conjuntos de 3 elementos (o menos) y verifica. Lo repite varias
  // veces.
  set<int> W;
  make_random_set(W,250,100);
  N=3; 
  v.resize(N);
  for (int k=0; k<30; k++) {
    cout << "\n\n\n------------------\n";
    cout << "W: ";
    prints(W);
    for (int j=0; j<N; j++) {
      make_random_set(v[j],3,100);
      cout << "S_" << j << ": ";
      prints(v[j]);
    }
    cout << "W contiene a todos los v[j] ? " << (cubre_todo(v,W) ? "si" : "no") << endl;
  }

} 

Generated by GNU Enscript 1.6.6.