propsubset.cpp

// $Id$

/* COMIENZO DE DESCRIPCION
   
  __USE_WIKI__
   Dada una lista de conjuntos
  #list< set<int> > L#, escribir una funci\'on predicado 
  #bool proper_subset(list< set<int> > &L)#, que determina si los
  conjuntos de la lista #L# son subconjuntos propios en forma
  consecutiva. Es decir, si #L = (A_0, A_1, ...., A_{n-1})#, 
  determinar si #A_j# es subconjunto propio de #A_{j+1}#, 
  para #j=0,...,n-2#. 
  [Tomado en el examen final 7/7/2005]. 
  keywords: conjunto

  FIN DE DESCRIPCION */

#include <cstdio>
#include <cmath>
#include <set>
#include <list>
#include <algorithm>
#include "./util.h"

using namespace std;

typedef set<int> set_t;
typedef list<set_t> list_t;

//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
void aed_set_union(set_t &a,set_t &b, set_t &c) {
  c.clear();
  set_union(a.begin(),a.end(),b.begin(),b.end(),
		 inserter(c,c.begin()));
}

//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
void aed_set_intersection(set_t &a,set_t &b, set_t &c) {
  c.clear();
  set_intersection(a.begin(),a.end(),b.begin(),b.end(),
		 inserter(c,c.begin()));
}

//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
void aed_set_difference(set_t &a,set_t &b, set_t &c) {
  c.clear();
  set_difference(a.begin(),a.end(),b.begin(),b.end(),
		 inserter(c,c.begin()));
}

//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
bool proper_subset(list< set<int> > &L) {
  list_t::iterator p = L.begin();
  if (p == L.end()) return true;

  set_t tmp;
  while (p != L.end()) {
    // *p es A[j] y *q es A[j+1]
    list_t::iterator q = p; q++;

    // Aseguramos que p y
    // q son dereferenciables
    if (q==L.end()) break;

    // Verifica que A[j] incluido en A[j+1]
    // es decir, tmp = A[j]-A[j+1] es vacio
    aed_set_difference(*p,*q,tmp);
    if (!tmp.empty()) {
      // printf("NO incluye!!\n");
      return false;
    }

    // Verifica que la inclusion es propia
    // es decir, tmp = A[j+1]-A[j] NO es vacio
    aed_set_difference(*q,*p,tmp);
    if (tmp.empty()) {
      // printf("Inclusion NO propia!!\n");
      return false;
    }

    p=q;	   
  }
  return true;
}

//---:---<*>---:---<*>---:---<*>---:---<*>---:---<*>
// Hace S un conjunto aleatorio con approx. m enteros en [0,n)
void make_random_set(set<int> &S,int m,int n) {
  S.clear();
  double lambda = 1.0/(m+1);
  while (drand() > lambda) 
      S.insert(rand() % n);
}

// Auxiliar function, prints set
void prints(set_t &S,const char *s=NULL) {
  // printf("size() %d\n",S.size());
  set_t::iterator q = S.begin();
  if (s) printf("%s: ",s);
  while (q != S.end()) printf(" %d",*q++);
  if (s) printf("\n");
}

// -------------------------------------------------------------------
int main () {

  list_t L;
  set_t S,DS,SS;

  // Prueba generando aleatoriamente listas
  // de vectores 
  for (int it=0; it<20; it++) {
    L.clear();
    S.clear();
    for (int j=0; j<3; j++) {
      // Agrega un conjunto aleatorio
      make_random_set(DS,3,100);
      aed_set_union(S,DS,SS);
      S = SS;

      // Quita un conjunto aleatorio
      make_random_set(DS,10,100);
      aed_set_difference(S,DS,SS);
      S = SS;

      L.push_back(S);
    }

    list_t::iterator q = L.begin();
    int j=0;
    while (q!=L.end()) {
      printf("L{%d} = (",j);
      set_t::iterator r = q->begin();
      while (r!=q->end()) 
	printf(" %d",*r++);
      printf(")\n");
      j++; q++;
    }
    printf("son subconjuntos propios? %s\n---------------\n",
	   (proper_subset(L)? "si" : "no"));
  }
}
// -------------------------------------------------------------------

Generated by GNU Enscript 1.6.6.