trabalho1.c 3.35 KB
Newer Older
1 2 3
#include<stdio.h>
#include"listas.h"

4 5 6
#define TRUE 1
#define FALSE 0

7
void decompoe(relacao *, apDF, uint);
André Machado's avatar
André Machado committed
8
int contem(relacao*, atributo);
9
void imprime_relacao(relacao, uint);
10
void le_nome(atributo, char*);
11

12
void decompoe(relacao *r0, apDF dependencia, uint id){
13
  apAtt att, aux, aux2;
14
  relacao *r1=(relacao*)malloc(sizeof(relacao));
15 16 17 18
  if((dependencia->prox == NULL) && (id != 0)){
    if(r0->inicio->prox->prox != r0->fim)
      imprime_relacao(*r0, id);
  }else if(dependencia->prox != NULL){
19
    //decompoe
20
    cria_lAtt_vazia(r1);
21
    //insere os elementos de X e de Y
22
    for(att=dependencia->X->inicio->prox;att!=NULL;att=att->prox){
23
      aux=cria_no_Att();
24
      sprintf(aux->nome, "%s", att->nome);
25
      insere_no_lAtt(r1, aux);
26 27
    }
    //também remove os elementos de Y da super relacao
28
    for(att=dependencia->Y->inicio->prox;att!=NULL;att=att->prox){
29
      aux=cria_no_Att();
30
      sprintf(aux->nome, "%s", att->nome);
31
      insere_no_lAtt(r1, aux);
32 33
      for(aux2=r0->inicio;aux2->prox!=NULL;aux2=aux2->prox)
	if(strcmp(aux2->prox->nome,att->nome)==0)
34 35 36
	  remove_prox_no_lAtt(aux2);
    }
    //imprime a nova relacao na BCNF
37
    imprime_relacao(*r1, id+1);
38 39
    //chama a função para a proxima dependencia.
    decompoe(r0, dependencia->prox, id+2);
40
  }
41
}
42 43 44
/*
 Função que verifica se uma relação contém um atributo
 */
André Machado's avatar
André Machado committed
45 46 47
int contem(relacao *r, atributo atributo){
  apAtt att;
  for(att=r->inicio->prox;att!=NULL;att=att->prox)
48 49 50
    if(strcmp(att->nome, atributo)==0)
      return TRUE;
  return FALSE;
51 52
}

53 54 55 56 57
/*
Saída do programa.
Assume que a relação nunca é vazia.
*/
void imprime_relacao(relacao r, uint id){
58
  apAtt aux=r.inicio->prox;
59 60
  printf("R%d(%s",id,aux->nome);
  for(aux=aux->prox;aux!=NULL;aux=aux->prox)
André Machado's avatar
André Machado committed
61 62
    if(strcmp("",aux->nome)!=0)
      printf(",%s", aux->nome);
63 64 65
  printf(")\n");
}

66 67 68 69 70 71
/*
Deverá ler o nome de um atributo.
Retornará o primeiro caracter após o nome.
Por padrão, esse caracter será:
',', '-' ou '\n'
*/
72 73
void le_nome(atributo nome,char *terminador){
  int i=0;
74 75 76
  do{
    nome[i]=getchar();
    if((nome[i]<'A')||((nome[i]>'Z')&&(nome[i]<'a'))||(nome[i]>'z')){
77
      *terminador=nome[i];
78 79
      nome[i]='\0';
    }
80 81
    ++i;
  }while(nome[i-1]!='\0');
82 83 84 85 86 87 88 89 90 91 92
  return;
}

/*
Insere um atributo na relação
*/
void insere_na_Relacao(char atributo[], relacao *r){
  apAtt no=cria_no_Att();
  sprintf(no->nome, "%s", atributo);
  insere_no_lAtt(r, no);
  return;
93 94
}

95
int main(){
96
  lDF *lista_DF=(lDF*)malloc(sizeof(lDF));
97 98
  apDF no_DF;
  apAtt atributo;
99 100
  relacao *R0=(relacao*)malloc(sizeof(relacao));
  cria_lAtt_vazia(R0);
101 102
  char terminador;
  //criação da lista de dependencias
103
  cria_lDF_vazia(lista_DF);
104
  do{
105 106 107
    no_DF = cria_no_DF();
    do{
      atributo = cria_no_Att();
108
      le_nome(atributo->nome, &terminador);
André Machado's avatar
André Machado committed
109
      if(!contem(R0, atributo->nome))
110
	insere_na_Relacao(atributo->nome, R0);
111
      //insere na lista X
112
      insere_no_lAtt(no_DF->X, atributo);
113
    }while(terminador == ',');
114
    //le o '>' da seta
115 116 117
    getchar();
    do{
      atributo = cria_no_Att();
118
      le_nome(atributo->nome, &terminador);
André Machado's avatar
André Machado committed
119
      if(!contem(R0, atributo->nome))
120
	insere_na_Relacao(atributo->nome, R0);
121
      //insere na lista Y
122
      insere_no_lAtt(no_DF->Y, atributo);
123
    }while(terminador == ',');
124
    insere_no_lDF(lista_DF, no_DF);
125
  }while(terminador != EOF);
126
  //Processamento & impressões
André Machado's avatar
André Machado committed
127
  imprime_relacao(*R0, 0);
128
  decompoe(R0, lista_DF->inicio->prox, 0);
129
  return 0;
130
}