Skip to content

Instantly share code, notes, and snippets.

@douglasb78
Last active September 12, 2024 23:11
Show Gist options
  • Save douglasb78/8f3d57078bdc6c8db5415f608c076674 to your computer and use it in GitHub Desktop.
Save douglasb78/8f3d57078bdc6c8db5415f608c076674 to your computer and use it in GitHub Desktop.
Implementação da pesquisa binária em arquivo (TDE - exercício avaliativo)
#include <stdio.h>
#include <stdlib.h> // malloc()
#include <string.h> // strcat()
#include <ctype.h> // isdigit()
#include <conio.h> // getch()
#include <locale.h> // acentuação
#include "bstree_movie.h"
#define pause() getch()
/*
arqMovies.txt = movieID;title;releaseYear;url;directorID
*/
void percursoEscreveBinario(NodeMovie *node, FILE *fileptr){
if(node!=NULL){
percursoEscreveBinario(node->esquerda, fileptr);
//fwrite(void *buffer,int numero_de_bytes,int count,FILE *fp);
int teste = fwrite(node->filme, 1, sizeof(struct movie), fileptr);
percursoEscreveBinario(node->direita, fileptr);
}
}
int binwrite(TreeMovie *arvoreFilmes){
FILE *fileptr = fopen("arqMovies_b.bin", "wb");
if(fileptr == NULL){
printf("Erro ao criar o arquivo binário.\nDelete o arquivo (se ele já existe) e coloque o programa em uma pasta que não seja a \"Downloads\"! (UAC)\n");
return 1;
}
percursoEscreveBinario(arvoreFilmes->raiz, fileptr);
fclose(fileptr);
return 0;
}
int binarySearchFile(char title[]){
int low = 0, mid = 0, high = 0;
Movie *movieAux = (Movie*)malloc(sizeof(struct movie));
movieAux->directorID = -1;
movieAux->movieID = -1;
movieAux->movieYear = -1;
memset(movieAux->movieTitle, '\0', sizeof(movieAux->movieTitle));
memset(movieAux->movieURL, '\0', sizeof(movieAux->movieURL));
FILE *fileptr = fopen("arqMovies_b.bin", "rb");
if(fileptr == NULL){
printf("Erro ao abrir o arquivo binário.\nCertifique-se dele ter sido gerado!\n");
return 1;
}
fseek(fileptr, 0, SEEK_END);
high = ftell(fileptr)/sizeof(struct movie);
while(strcmp(title, movieAux->movieTitle) != 0){
mid = low+(high-low)/2;
fseek(fileptr, mid*sizeof(struct movie), SEEK_SET);
fread(movieAux, 1, sizeof(struct movie), fileptr);
printf("teste: %s > %s | low: %d | mid: %d | high: %d\n", movieAux->movieTitle, title, low, mid, high);
if(strcmp(title, movieAux->movieTitle) > 0){
low = mid;
} else {
high = mid;
}
}
return 0;
}
int main(){
FILE *file;
char charAux = '\n', strAux[2] = {'\0'};
int newline = 1, linearg = 0, aux = 0, countrepetido = 0;
setlocale(LC_ALL, "Portuguese");
/*===========================================
*
* Leitura Filmes:
*
*===========================================*/
char title[128] = {'\0'}, url[512] = {'\0'};
int movieid = -1, year = -1, directorid = -1;
int countsemdiretor = 0, countfilmes = 0;
countrepetido = 0;
TreeMovie *arvoreFilmes = (TreeMovie*)malloc(sizeof(struct treeMovie));
arvoreFilmes->raiz = NULL;
file = fopen("arqMovies.txt", "r");
if(file == NULL){
printf("Erro ao abrir o arquivo de filmes.\nColoque-o na mesma pasta do programa!\n");
return 1;
}
printf("Lendo o arquivo de filmes...\n");
while((charAux = fgetc(file)) != EOF){
// Linha nova, preparar para o filme ser criado na árvore:
if(newline){
if(isdigit(charAux) == 1 && movieid != -1 && year != -1){
//printf("movieid %d | year %d | directorid %d\n | title %s | url %s\n", movieid, year, directorid, title, url);
if(inserirBST(criarNode(movieid, title, year, url, directorid), arvoreFilmes) == 0){
countrepetido++;
}
if(directorid == -1) countsemdiretor += 1;
countfilmes++;
}
newline=0;
linearg = 0;
movieid = -1;
year = -1;
directorid = -1;
memset(url, '\0', sizeof(url));
memset(title, '\0', sizeof(title));
// se a linha não começar com dígito, ler a próxima.
if(isdigit(charAux) == 0){
while(charAux != '\n')
charAux = fgetc(file);
linearg = 5;
}
}
// Próximo parâmetro da linha:
if(charAux == ';'){
linearg ++;
}
// Ler parâmetro da linha:
// movieID;title;releaseYear;url;directorID
switch(linearg){
case 0: // movieID
if(isdigit(charAux) == 0) break;
if(movieid == -1) movieid = 0;
aux = charAux - 48;
movieid *= 10;
movieid += aux;
break;
case 1: // title
if(charAux == ';') break;
// string temporária com o char:
strAux[0]=charAux;strAux[1]='\0';
strcat(title, strAux);
break;
case 2: // releaseYear
if(isdigit(charAux) == 0) break;
if(year == -1) year = 0;
aux = charAux - 48;
year *= 10;
year += aux;
break;
case 3: // url
if(charAux == ';') break;
// string temporária com o char:
strAux[0]=charAux;strAux[1]='\0';
strcat(url, strAux);
break;
case 4: // directorID
if(isdigit(charAux) == 0) break;
if(directorid == -1) directorid = 0;
aux = charAux - 48;
directorid *= 10;
directorid += aux;
break;
}
newline = (charAux == '\n') ? 1 : 0;
}
// último filme, fora do laço while:
if(movieid != -1){
inserirBST(criarNode(movieid, title, year, url, directorid), arvoreFilmes);
if(directorid == -1) countsemdiretor += 1;
}
fclose(file);
printf("* %d linhas não especificam o diretor.\n", countsemdiretor);
printf("* %d filmes repetidos.\n", countrepetido);
printf("* %d filmes carregados na memória. (árvore binária de busca)\n", countfilmes-countrepetido);
printf("\nAperte qualquer tecla para continuar:\n> ");
pause();
/*===========================================
*
* Escrita em arquivo binário:
*
*===========================================*/
printf("\nGuardando os filmes em um arquivo binário...\n");
binwrite(arvoreFilmes);
printf("* Arquivo binário criado. *\n");
printf("\nAperte qualquer tecla para continuar:\n> ");
pause();
/*===========================================
*
* Pesquisa binária no arquivo binário:
*
*===========================================*/
binarySearchFile("Star Trek: First Contact");
printf("\n* Fim. *\n");
pause();
return 0;
}
@douglasb78
Copy link
Author

douglasb78 commented Sep 7, 2024

#ifndef BSTREE_MOVIE_H
#define BSTREE_MOVIE_H

typedef struct movie {
	int movieID;
	char movieTitle[128];
	int movieYear;
	char movieURL[512];
	int directorID;
} Movie;

typedef struct nodeMovie {
	struct movie *filme;
	struct nodeMovie *esquerda; // em direção ao inicio
	struct nodeMovie *direita; //  em direção ao fim
} NodeMovie;

typedef struct treeMovie {
	struct nodeMovie *raiz;
} TreeMovie;

NodeMovie* criarNode(int movieid, char title[], int year, char url[], int directorid);
NodeMovie* procurarBST(char title[], NodeMovie *node);

int inserirBST(NodeMovie *node, TreeMovie *arvore);
void percursoCentral(NodeMovie *node);
void percursoCentralDiretor(NodeMovie *node, int directorid);

#endif
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <string.h>
#include "bstree_movie.h"
#define ESQUERDA 0
#define DIREITA 1

NodeMovie* criarNode(int movieid, char title[], int year, char url[], int directorid){
	NodeMovie *nodeAux = (NodeMovie*)malloc(sizeof(NodeMovie));
	Movie *movieAux = (Movie*)malloc(sizeof(Movie));
	movieAux->movieID = movieid;
	movieAux->movieYear = year;
	movieAux->directorID = directorid;
	memcpy(movieAux->movieTitle, title, sizeof(movieAux->movieTitle));
	memcpy(movieAux->movieURL, url, sizeof(movieAux->movieURL));
	nodeAux->filme = movieAux;
	nodeAux->direita = NULL;
	nodeAux->esquerda = NULL;
	return nodeAux;
}

int inserirBST(NodeMovie *node, TreeMovie *arvore){
	NodeMovie *nodeAux = arvore->raiz;
	NodeMovie *nodeInserir;
	int direcao;
	while(1){
		if(arvore->raiz == NULL){
			//printf("raiz nula\n");
			arvore->raiz = node;
			break;
		} else {
			if(strcmp(node->filme->movieTitle, nodeAux->filme->movieTitle) < 0){
				if(nodeAux->esquerda == NULL){
					//printf("esquerda nula\n");
					nodeAux->esquerda = node;
					break;
				} else {
					//printf("esquerda valor\n");
					nodeAux = nodeAux->esquerda;
				}
			} else if(strcmp(node->filme->movieTitle, nodeAux->filme->movieTitle) > 0){
				if(nodeAux->direita == NULL){
					//printf("direita nula\n");
					nodeAux->direita = node;
					break;
				} else {
					//printf("direita valor\n");
					nodeAux = nodeAux->direita;
				}
			} else {
				printf("* Linha ignorada: o filme %s já foi inserido.\n", node->filme->movieTitle); return 0;
			}
		}
	}
	return 1;
}

NodeMovie* procurarBST(char title[], NodeMovie *node){
	while(node != NULL){
		if(strcmp(title, node->filme->movieTitle) > 0){
			node = node->direita;
		} else if (strcmp(title, node->filme->movieTitle) < 0) {
			node = node->esquerda;
		} else {
			return node;
		}
	}
	return NULL;
}

void percursoCentral(NodeMovie *node){
	if(node!=NULL){
		percursoCentral(node->esquerda);
		printf("%s ", node->filme->movieTitle);
		percursoCentral(node->direita);
	}
}

void percursoCentralDiretor(NodeMovie *node, int directorid){
	if(node!=NULL){
		percursoCentralDiretor(node->esquerda, directorid);
		if(node->filme->directorID == directorid){
			printf("* %s\n", node->filme->movieTitle);
		}
		percursoCentralDiretor(node->direita, directorid);
	}
}

@douglasb78
Copy link
Author

#include <stdio.h>
#include <stdlib.h> // malloc()
#include <string.h> // strcat()
#include <ctype.h> // isdigit()
#include <conio.h> // getch()
#include <locale.h> // acentuação
#include <time.h> // benchmark
#include "bstree_movie.h"
#include "clock_timer.h"
#define pause() getch()

/*
arqMovies.txt = movieID;title;releaseYear;url;directorID
*/

void percursoEscreveBinario(NodeMovie *node, FILE *fileptr){
	if(node!=NULL){
		percursoEscreveBinario(node->esquerda, fileptr);
		//fwrite(void *buffer,int numero_de_bytes,int count,FILE *fp);
		int teste = fwrite(node->filme, 1, sizeof(struct movie), fileptr);
		percursoEscreveBinario(node->direita, fileptr);
	}
}

int binwrite(TreeMovie *arvoreFilmes){
	FILE *fileptr = fopen("arqMovies_b.bin", "wb");
	if(fileptr == NULL){
		printf("Erro ao criar o arquivo binário.\nDelete o arquivo (se ele já existe) e coloque o programa em uma pasta que não seja a \"Downloads\"! (UAC)\n");
		return 1;
	}
	percursoEscreveBinario(arvoreFilmes->raiz, fileptr);
	fclose(fileptr);
	return 0;
}

int binarySearchFile(char title[]){
	double start_time = 0.0, end_time = 0.0;
	int low = 0, mid = 0, high = 0, comparisons = 0;
	Movie *movieAux = (Movie*)malloc(sizeof(struct movie));
	movieAux->directorID = -1;
	movieAux->movieID = -1;
	movieAux->movieYear = -1;
	memset(movieAux->movieTitle, '\0', sizeof(movieAux->movieTitle));
	memset(movieAux->movieURL, '\0', sizeof(movieAux->movieURL));
	FILE *fileptr = fopen("arqMovies_b.bin", "rb");
	if(fileptr == NULL){
		printf("Erro ao abrir o arquivo binário.\nCertifique-se dele ter sido gerado!\n");
		return 1;
	}
	
	printf("Busca binária em arquivo:\n");
	fseek(fileptr, 0, SEEK_END);
	start_time = get_time();
	high = ftell(fileptr)/sizeof(struct movie);
	
	while(strcmp(title, movieAux->movieTitle) != 0){
		comparisons += 1;
		
		mid = low+(high-low)/2;
		
		fseek(fileptr, mid*sizeof(struct movie), SEEK_SET);
		fread(movieAux, 1, sizeof(struct movie), fileptr);
		printf("teste: %s > %s | low: %d | mid: %d | high: %d\n", movieAux->movieTitle, title, low, mid, high);
		if(strcmp(title, movieAux->movieTitle) > 0){
			low = mid;
		} else {
			high = mid;
		}
	}
	end_time = get_time();
	printf("* %d comparações.\n", comparisons);
	printf("* %lf segundos.\n", end_time-start_time);
	
	printf("Copiando arquivo para memória...");
	low = 0;
	fseek(fileptr, 0, SEEK_END);
	high = ftell(fileptr)/sizeof(struct movie);
	Movie *movieBuffer[high]; // -std=c99
	for(int i=0; i<high; i++){
		movieBuffer[i] = (Movie*)malloc(sizeof(struct movie));
		fseek(fileptr, i*sizeof(struct movie), SEEK_SET);
		fread(movieBuffer[i], 1, sizeof(struct movie), fileptr);
	}
	
	return 0;
}

int main(){
	FILE *file;
	char charAux = '\n', strAux[2] = {'\0'};
	int newline = 1, linearg = 0, aux = 0, countrepetido = 0;
	setlocale(LC_ALL, "Portuguese");
	
	/*===========================================
	*
	*	Leitura Filmes:
	*
	*===========================================*/
	char title[128] = {'\0'}, url[512] = {'\0'};
	int movieid = -1, year = -1, directorid = -1;
	int countsemdiretor = 0, countfilmes = 0;
	countrepetido = 0;
	TreeMovie *arvoreFilmes = (TreeMovie*)malloc(sizeof(struct treeMovie));
	arvoreFilmes->raiz = NULL;
	
	file = fopen("arqMovies.txt", "r");
	if(file == NULL){
		printf("Erro ao abrir o arquivo de filmes.\nColoque-o na mesma pasta do programa!\n");
		return 1;
	}
	
	printf("Lendo o arquivo de filmes...\n");
	while((charAux = fgetc(file)) != EOF){
		// Linha nova, preparar para o filme ser criado na árvore:
		if(newline){
			if(isdigit(charAux) == 1 && movieid != -1 && year != -1){
				//printf("movieid %d | year %d | directorid %d\n | title %s | url %s\n", movieid, year, directorid, title, url);
				if(inserirBST(criarNode(movieid, title, year, url, directorid), arvoreFilmes) == 0){
					countrepetido++;
				}
				if(directorid == -1) countsemdiretor += 1;
				countfilmes++;
			}
			newline=0;
			linearg = 0;
			movieid = -1;
			year = -1;
			directorid = -1;
			memset(url, '\0', sizeof(url));
			memset(title, '\0', sizeof(title));
			// se a linha não começar com dígito, ler a próxima.
			if(isdigit(charAux) == 0){
				while(charAux != '\n')
					charAux = fgetc(file);
				linearg = 5;
			}
		}
		// Próximo parâmetro da linha:
		if(charAux == ';'){
			linearg ++;
		}
		// Ler parâmetro da linha:
		// movieID;title;releaseYear;url;directorID
		switch(linearg){
			case 0: // movieID
				if(isdigit(charAux) == 0) break;
				if(movieid == -1) movieid = 0;
				aux = charAux - 48;
				movieid *= 10;
				movieid += aux;
				break;
			case 1: // title
				if(charAux == ';') break;
				// string temporária com o char:
				strAux[0]=charAux;strAux[1]='\0';
				strcat(title, strAux);
				break;
			case 2: // releaseYear
				if(isdigit(charAux) == 0) break;
				if(year == -1) year = 0;
				aux = charAux - 48;
				year *= 10;
				year += aux;
				break;
			case 3: // url
				if(charAux == ';') break;
				// string temporária com o char:
				strAux[0]=charAux;strAux[1]='\0';
				strcat(url, strAux);
				break;
			case 4: // directorID
				if(isdigit(charAux) == 0) break;
				if(directorid == -1) directorid = 0;
				aux = charAux - 48;
				directorid *= 10;
				directorid += aux;
				break;
		}

		newline = (charAux == '\n') ? 1 : 0;
	}
	// último filme, fora do laço while:
	if(movieid != -1){
		inserirBST(criarNode(movieid, title, year, url, directorid), arvoreFilmes);
		if(directorid == -1) countsemdiretor += 1;
	}
	fclose(file);
	printf("* %d linhas não especificam o diretor.\n", countsemdiretor);
	printf("* %d filmes repetidos.\n", countrepetido);
	printf("* %d filmes carregados na memória. (árvore binária de busca)\n", countfilmes-countrepetido);
	printf("\nAperte qualquer tecla para continuar:\n> ");
	pause();
	/*===========================================
	*
	*	Escrita em arquivo binário:
	*
	*===========================================*/
	printf("\nGuardando os filmes em um arquivo binário...\n");
	binwrite(arvoreFilmes);
	printf("* Arquivo binário criado. *\n");
	printf("\nAperte qualquer tecla para continuar:\n> ");
	pause();
	printf("\n");
	/*===========================================
	*
	*	Pesquisa binária no arquivo binário:
	*
	*===========================================*/
	binarySearchFile("Star Trek: First Contact");
	
	printf("\n* Fim. *\n");
	pause();
	return 0;
}```

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment