Prev Up Next
Go backward to Números de Stirling 2
Go up to Alguns exercícios a exemplos dados nas aulas teóricas
Go forward to Mais recursividade

Números de Stirling 3

Dado nk, imprime todas as partições dos objecctos {1,...,n} em k subconjuntos não vazios.
#include <stdio.h>
#define MAXN 10
#define SOLS 50

struct set{
  int n;                       // Num elementos
  int elem[MAXN];              //  os elementos
};

struct partition{
  int s;                       // Num conjuntos
  struct set one_set[MAXN];    // one_set[i]:
};                             //  um conjunto

struct sols{
  int ns;                      // Num de solucoes
  struct partition part[SOLS]; // part[i]: uma sol.
};

void print_solution(struct sols);
//-----------------------------------------------------------------
main(){
  int n,k;
  struct sols solutions;
  struct sols stirling(int,int);

  scanf("%d",&n);
  scanf("%d",&k);

  solutions=stirling(n,k);
  print_solution(solutions);
}

//-----------------------------------------------------------------
struct sols empty={0,{0,{0,{0}}}};
//struct sols one  ={1,{1,{1,{1}}}};
struct sols one  ={1,1,1,1};

struct sols stirling(int n,int k){
  int i,j,m,r,last,index;
  struct sols s,s1;

  if(n==1 && k==1)
    return(one);    // Dividir um conjunto numa parte
  if(k<1 || k>n)
    return(empty);  // Sem solucoes
  //                                              {n,k} =
  // novo conjunto {n} em cada partição           {n-1,k-1} +...
  s=stirling(n-1,k-1);
  for(i=0;i<s.ns;i++){
    s.part[i].one_set[s.part[i].s].n=1;
    s.part[i].one_set[s.part[i].s].elem[0]=n;
    s.part[i].s++;
  }

  // Elemento n em cada uma das partições          ...k{n-1,k}
  s1=stirling(n-1,k);
  for(i=0;i<s1.ns;i++){            // Para cada solução
    for(r=0;r<s1.part[i].s;r++){     
                                   // coloque n num conj. j
      index=s.ns;
      s.ns ++;
      for(j=0;j<s1.part[i].s;j++){ // Para cada conjunto
	s.part[index].s=s1.part[i].s;
	s.part[index].one_set[j].n = s1.part[i].one_set[j].n; 
	for(m=0;m<s1.part[i].one_set[j].n;m++) // copie os elementos
	  s.part[index].one_set[j].elem[m] = 
                         s1.part[i].one_set[j].elem[m];
	if(j==r){
	  last = s.part[index].one_set[j].n;
	  s.part[index].one_set[j].elem[last] = n;
	  s.part[index].one_set[j].n++;
	}
      }
    }
  }
  return(s);
}

//-----------------------------------------------------------------
void print_solution(struct sols resul){
  void print_set(int x[], int);
  int i,j;

  for(i=0;i<resul.ns;i++){
    for(j=0;j<resul.part[i].s;j++)
      print_set(resul.part[i].one_set[j].elem,resul.part[i].one_set[j].n);
    printf("\n");
  }
}

void print_set(int x[], int n){
  int i;
  printf("  {",n);
  for(i=0;i<n;i++){
    printf("%-1d",x[i]);
    if(i<n-1)
      printf(", ");
  }
  printf("}");
}

Prev Up Next