[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Uma solução para o EP3.



Olá pessoal.

  Apesar de eu ainda estar corrigindo os EPs 3 e 4, aqui vai uma
possível solução em C para o EP3 (para quem estiver interessado). O
Carlinhos vai ficar uma semana fora, quando ele voltar ele colocará esta
solução na página da disciplina.

  As notas dos EPs sairão no começo da semana que vem, mas só estarão
disponíveis para vocês quando o Carlinhos voltar de viagem (lá pelo dia
17/07).


Um abraço,
-- 
Félix Almeida
/******************************************
 *                                        *
 * MAC-115                           EP 3 *
 * Prof. Carlos Eduardo        07/06/2000 *
 * Félix Almeida <felix@linux.ime.usp.br> *
 *                                        *
 ******************************************/


/*
  Este programa procura pela ocorrência de uma dada proteína dentro de uma
  seqüência de genes, indicando, caso a encontre, a posição onde ela ocorre e
  as bases que a compõem. Note que a execução do programa é finalizada assim
  que a primeira ocorrência da proteína é encontrada.

  As proteínas são compostas por aminoácidos, que por sua vez são compostos por
  um trio de bases (também chamado de códon). A relação entre eles está
  discriminada na tabela abaixo:

     Aminoácido           | Códon
    ----------------------+-------------
     A (fenilanina)       | ttt, ttc
     B (leucina)          | tta, ttg, ctt, ctc, cta, ctg
     C (isoleucina)       | att, atc, ata
     D (metionina/início) | atg
     E (valina)           | gtt, gtc, gta, gtg
     F (serina)           | tct, tcc, tca, tcg, agt, agc
     G (prolina)          | cct, ccc, cca, ccg
     H (treonina)         | act, acc, aca, acg
     I (alanina)          | gct, gcc, gca, gcg
     J (tirosina)         | tat, tac
     K (fim)              | taa, tag, tga
     L (histidina)        | cat, cac
     M (glutamina)        | caa, cag
     N (aspargina)        | aat, aac
     O (lisina)           | aaa, aag
     P (ácido aspártico)  | gat, gac
     Q (cisteína)         | tgt, tgc
     R (triptófano)       | tgg
     S (arginina)         | cgt, cgc, cga, cgg, aga, agg
     T (glicina)          | ggt, ggc, gga, ggg
     U (ácido glutâmico)  | gaa, gag
*/


#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#define MAX_TAMANHO_DNA      5000 /* Tamanho máximo da seqüência de genes. */
#define MAX_TAMANHO_PROTEINA  500 /* Tamanho máximo da proteína. */
#define TAM_NOME              100 /* Tamanho máximo dos nomes dos arquivos. */


/* Lê toda a seqüência genética a partir de um arquivo e a armazena num vetor,
devolvendo o tamanho da seqüência lida. Devolve zero caso o arquivo indicado
não exista ou caso ele não contenha nenhuma letra. Supõe que os dados do
arquivo estejam bem formados, isto é, sejam formados apenas pelas letras 'a',
'c', 't' e 'g'. Caracteres que não sejam letras serão ignorados, e letras
maiúsculas serão convertidas para minúsculas automaticamente. */
int leia_seq_genetica(char dna[MAX_TAMANHO_DNA]) {
/* dna: vetor que contém a seqüência genética lida do arquivo. */

	FILE *arqseq;
	char nome[TAM_NOME], c;
	int cont = 0;
	/* arqseq: Apontador para o arquivo onde está a seqüência genética.
	   nome  : Nome do arquivo onde está a seqüência genética.
	   c     : Armazena o último caractere lido do arquivo.
	   cont  : Guarda o tamanho da seqüência lida.
	*/

	printf("Entre com o nome do arquivo que contem a sequencia genetica: ");
	scanf("%s", nome);

	if ((arqseq = fopen(nome, "r")) == NULL)
		printf("Arquivo %s nao foi encontrado!\n", nome);
	else {
		while ((c = getc(arqseq)) != EOF)
			if (isalpha(c)) dna[cont++] = tolower(c);
		fclose(arqseq);
	}

	return cont;

} /* leia_seq_genetica() */


/* Lê toda a proteína a partir de um arquivo e a armazena num vetor, devolvendo
o tamanho da proteína lida. Devolve zero caso o arquivo indicado não exista ou
caso ele não contenha nenhuma letra. Supõe que os dados do arquivo estejam bem
formados, isto é, sejam formados apenas pelas letras de 'A' até 'U'. Caracteres
que não sejam letras serão ignorados, e letras minúsculas serão convertidas
para maiúsculas automaticamente. */
int leia_proteina(char proteina[MAX_TAMANHO_PROTEINA]) {
/* proteina: vetor que contém a proteína lida do arquivo. */

	FILE *arqprot;
	char nome[TAM_NOME], c;
	int cont = 0;
	/* arqprot: Apontador para o arquivo onde está a proteína.
	   nome   : Nome do arquivo onde está a proteína.
	   c      : Armazena o último caractere lido do arquivo.
	   cont   : Guarda o tamanho da proteína lida.
	*/

	printf("Entre com o nome do arquivo que contem a proteina: ");
	scanf("%s", nome);

	if ((arqprot = fopen(nome, "r")) == NULL)
		printf("Arquivo %s nao foi encontrado!\n", nome);
	else {
		while ((c = getc(arqprot)) != EOF)
			if (isalpha(c)) proteina[cont++] = toupper(c);
		fclose(arqprot);
	}

	return cont;

} /* leia_proteina() */


/* Recebe um códon através de um vetor e devolve a letra associada ao
aminoácido correspondente. Assume que o códon esteja bem formado, isto é, seja
formado apenas pelas letras 'a', 'c', 't' e 'g'. A procura pelo aminoácido
associado ao códon passado é finalizada assim que ele estiver unicamente
determinado, não precisando para isso que sejam analisadas necessariamente
as três bases do códon. */
char codigo_aminoacido(char codon[3]) {
/* codon: vetor que contém o códon a ser analisado. */

	char c;
	/* c: Guarda a letra do aminoácido correspondente ao códon passado. */


	if	(codon[0] == 'a')
		if	(codon[1] == 'a')
			if	(codon[2] == 'a' || codon[2] == 'g')	c = 'O';
			else  /* codon[2] == 't' || codon[2] == 'c' */	c = 'N';
		else if (codon[1] == 'g')
			if	(codon[2] == 'a' || codon[2] == 'g')	c = 'S';
			else  /* codon[2] == 't' || codon[2] == 'c' */	c = 'F';
		else if (codon[1] == 't')
			if	(codon[2] == 'g')			c = 'D';
			else  /* codon[2] == 'a' || codon[2] == 't' ||
				 codon[2] == 'c' */			c = 'C';
		else  /* codon[1] == 'c' */				c = 'H';

	else if (codon[0] == 'g')
		if	(codon[1] == 'a')
			if	(codon[2] == 'a' || codon[2] == 'g')	c = 'U';
			else  /* codon[2] == 't' || codon[2] == 'c' */	c = 'P';
		else if (codon[1] == 'g')				c = 'T';
		else if (codon[1] == 't')				c = 'E';
		else  /* codon[1] == 'c' */				c = 'I';

	else if (codon[0] == 't')
		if	(codon[1] == 'a')
			if	(codon[2] == 'a' || codon[2] == 'g')	c = 'K';
			else  /* codon[2] == 't' || codon[2] == 'c' */	c = 'J';
		else if (codon[1] == 'g')
			if	(codon[2] == 'a')			c = 'K';
			else if (codon[2] == 'g')			c = 'R';
			else  /* codon[2] == 't' || codon[2] == 'c' */	c = 'Q';
		else if (codon[1] == 't')
			if	(codon[2] == 'a' || codon[2] == 'g')	c = 'B';
			else  /* codon[2] == 't' || codon[2] == 'c' */	c = 'A';
		else  /* codon[1] == 'c' */				c = 'F';

	else  /* codon[0] == 'c' */
		if	(codon[1] == 'a')
			if	(codon[2] == 'a' || codon[2] == 'g')	c = 'M';
			else  /* codon[2] == 't' || codon[2] == 'c' */	c = 'L';
		else if (codon[1] == 'g')				c = 'S';
		else if (codon[1] == 't')				c = 'B';
		else  /* codon[1] == 'c' */				c = 'G';

	return c;

} /* codigo_aminoacido() */


/* Função recursiva que verifica se a proteína dada combina com o pedaço da
   seqüência genética que começa na posição indicada. Devolve 1 caso a
   combinação seja perfeita, e devolve 0 caso contrário. Esta função deve ser
   chamada sempre com 0 no lugar do seu último parâmetro. */
int compara_proteina(int inicio, int tamanho_prot, char proteina[MAX_TAMANHO_PROTEINA], char dna[MAX_TAMANHO_DNA], int cont) {
/* inicio      : Indica a posição na seqüência de genes onde deve-se verificar
		 a presença da proteína.
   tamanho_prot: Guarda o tamanho da proteína lida.
   proteina    : vetor que contém a proteína lida do arquivo.
   dna         : vetor que contém a seqüência genética lida do arquivo.
   cont        : Indica quantos aminoácidos da proteína já foram analisados.
*/

	int achou = 0;
	char codon[3];
	/* achou: Indica se a proteína foi encontrada na seqüência genética.
	   codon: Vetor que contém o códon que está sendo comparado.
	*/

	if (cont < tamanho_prot) {
		codon[0] = dna[inicio + cont * 3];
		codon[1] = dna[inicio + cont * 3 + 1];
		codon[2] = dna[inicio + cont * 3 + 2];
		if (proteina[cont] == codigo_aminoacido(codon))
			achou = compara_proteina(inicio, tamanho_prot, proteina, dna, cont + 1);
	} else achou = 1;

	return achou;

} /* compara_proteina() */


/* Função principal do programa, é ela que solicita a leitura da proteína e da
   seqüência genética, verifica se os tamanhos das duas são compatíveis
   (proteína <= seqüência genética) e então tenta localizar a proteína dentro
   da seqüência genética através de alinhamentos sucessivos, mostrando os
   resultados no final. */
int main(void) {

	char proteina[MAX_TAMANHO_PROTEINA], dna[MAX_TAMANHO_DNA];
	int tamanho_prot, tamanho_seq, cont, cont2;
	/* proteina    : vetor que contém a proteína lida do arquivo.
	   dna         : vetor que contém a seqüência genética lida do arquivo.
	   tamanho_prot: Guarda o tamanho da proteína lida.
	   tamanho_seq : Guarda o tamanho da seqüência lida.
	   cont        : Contador usado na varredura da seqüência genética.
	   cont2       : Contador usado para mostrar as bases que compõem a
			 proteína encontrada.
	*/

	printf("\nMAC-115: EP3\nBusca de padroes\n\n");

	/* Lê os arquivos e termina o programa caso eles não existam. */
	if (!(tamanho_prot = leia_proteina(proteina)))
		exit(EXIT_FAILURE);
	if (!(tamanho_seq = leia_seq_genetica(dna)))
		exit(EXIT_FAILURE);

	printf("\n");
	/* Verifica se a proteína cabe dentro da seqüência genética. */
	if (tamanho_seq < tamanho_prot * 3)
		printf("A proteina nao foi encontrada na sequencia genetica.\n\n");
	else {
		/* Laço principal do programa, é ele que percorre a seqüência
		   genética procurando a proteína e, caso a encontre, mostra os
		   resultados. */
		for (cont = 0; cont <= tamanho_seq - tamanho_prot * 3; cont++)
			/* Verifica se a proteína está na posição atual da
			   seqüência genética. */
			if (compara_proteina(cont, tamanho_prot, proteina, dna, 0)) {
				printf("A proteina foi encontrada na posicao %d da sequencia genetica!\n", cont + 1);
				printf("Trecho correspondente: ");
				/* Mostra as bases que formam a proteína. */
				for (cont2 = 0; cont2 < tamanho_prot * 3; cont2++)
					printf("%c", dna[cont2 + cont]);
				printf("\n\n");
				break;
			}
		/* Verifica se o laço principal terminou porque encontrou a
		   proteína ou porque a seqüência genética terminou. */
		if (cont > tamanho_seq - tamanho_prot * 3)
			printf("A proteina nao foi encontrada na sequencia genetica.\n\n");
	}

	return EXIT_SUCCESS;

} /* main() */