-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathArvore.c
203 lines (171 loc) · 6.48 KB
/
Arvore.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
/*
Arvore.c
Trabalho II - Estrutura de Dados UFES 2020/2 - Patricia Dockhorn Costa
Alunos: Joao Gabriel de Barros e Tales Viana
Data: 28/04/2021
github: JoaoGBarros || Talesvf
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "Arvore.h"
struct arvore{
char* valor;
int id;
Arvore* direita;
Arvore* esquerda;
};
static char Busca(char c, char* string){
// Busca na string recebida o caracter c, caso o encontre, ele eh retornado, se nao eh retornado o char 'n'
for(int i = 0; i < strlen(string); i++){
if(c == string[i]){
return c;
}
}
return 'n';
}
static Arvore* CriaArvoreVazia(){
Arvore* arv;
arv = (Arvore*)malloc(sizeof(Arvore));
arv->valor = NULL;
arv->id = 0;
arv->direita = NULL;
arv->esquerda = NULL;
return arv;
}
//((((5)-(3))*((4)/(1)))+(10))
Arvore* CriaArvore(char* equacao, char* sinais, char* numeros, int* i, int *qtd){
Arvore *arvore;
int cont = 1;
char b;
char* a = (char*)malloc(5 * sizeof(char)); // Os algarismos da equacao so podem ter ate 5 digitos.
a[1] = '\0';
a[2] = '\0';
a[3] = '\0';
a[4] = '\0';
arvore = CriaArvoreVazia();
*qtd = *qtd + 1;
arvore->id = *qtd;
while(1){
//Toda vez q um parentese for aberto, eh criada uma nova arvore filha para a esquerda, caso ja existe alguma, para direita
if(equacao[*i] == '('){
*i = *i + 1;
if(!arvore->esquerda){
arvore->esquerda = CriaArvore(equacao, sinais, numeros, i, qtd);
}else{
arvore->direita = CriaArvore(equacao, sinais, numeros, i, qtd);
}
}
//Verifica se o caracter esta na string se sinais(+, -, *, /) e retorna qual deles eh, caso nao encontre, retorna 'n'.
a[0] = Busca(equacao[*i], sinais);
if(*a != 'n'){
*i = *i + 1;
arvore->valor = strdup(a);
}
//Verifica se o caracter esta na string de numeros de 0 a 9 e retorna qual deles eh, caso nao encontre, retorna 'n'.
a[0] = Busca(equacao[*i], numeros);
if(*a != 'n'){
*i = *i + 1;
while(1){
/*
* Caso encontre um numero, ele verifica nas proximas posicoes
*da string a existencia de mais numeros, e caso encontre,
* adiciona esse caracter na string, se nao, o loop eh quebrado
* e logo em seguida a string eh alocada no arvore->valor
*/
b = Busca(equacao[*i],numeros);
if(Busca(b, numeros) != 'n'){
a[cont] = b;
cont++;
*i = *i + 1;
}else{
break;
}
}
arvore->valor = strdup(a);
}
// Toda vez que um parentese eh fechado o loop while eh quebrado e a arvore eh retornada
if(equacao[*i] == ')') {
*i = *i + 1;
free(a);
break;
}
//Caso o indice seja maior ou igual ao tamanho da string da equacao, o loop while eh quebrado e a arvore eh retornada
if(*i >= strlen(equacao)-1){
free(a);
break;
}
}
return arvore;
}
float LeECalculaArvore(Arvore* a, float res, char* sinais){
int i;
if(Busca(*(a->valor), sinais) != 'n'){
//Se a arvore em questao for um sinal, eh verificado o sinal e eh chamada recursivamente a funcao, mandando dessa vez, a arvore esquerda e direita.
if(Busca(*(a->valor), sinais) == '+'){
res = LeECalculaArvore(a->esquerda, res, sinais) + LeECalculaArvore(a->direita, res, sinais);
}
else if(Busca(*(a->valor), sinais) == '-'){
res = LeECalculaArvore(a->esquerda, res, sinais) - LeECalculaArvore(a->direita, res, sinais);
}
else if(Busca(*(a->valor), sinais) == '*'){
res = LeECalculaArvore(a->esquerda, res, sinais) * LeECalculaArvore(a->direita, res, sinais);
}
else if(Busca(*(a->valor), sinais) == '/'){
res = LeECalculaArvore(a->esquerda, res, sinais) / LeECalculaArvore(a->direita, res, sinais);
}
}
else{
//Caso ela nao seja um sinal, e sim um numero, eh feita uma conversao para obter o valor da string em float.
for(i = 0;i < strlen(a->valor);i++){
res += (float)(a->valor[i] - '0') * pow(10, (strlen(a->valor) - i - 1));
}
}
return res;
}
void DestroiArvore(Arvore* a){
/*
*Caso a arvore exista faz a liberacao de seu valor, alocado pelo strdup,
*logo em seguida eh utilizada recursao para liberar as arvores pela esquerda e direita.
*Apos isso, a arvore eh liberada
*/
if(a){
free(a->valor);
DestroiArvore(a->esquerda);
DestroiArvore(a->direita);
free(a);
}
}
void ImprimeArvore(FILE *dot, Arvore* a, char* sinais, char* numeros, int *contador, int *qtd){
/* Foi utilizado um contador para fazer controle de prints especificos que marcam inicio e fim de certa arvore.
* Eh printado os dados da arvore e logo em seguida, utilizando recursao, eh printada informacoes das arvores à esquerda e direita,
* caso exista alguma, e o contador soma +1. Caso o contador for maior ou igual a qtd(quantidade de arvores) eh printado o "}", que marca o fim da arvore.
*/
if(a){
if(*contador == 0){
fprintf(dot, "strict graph {\n");
*contador += 1;
}
fprintf(dot, "no%d[label=", a->id);
if(Busca(*(a->valor), sinais) != 'n'){
fprintf(dot, "%c%s%c];\n", '"', a->valor, '"');
}
if(Busca(*(a->valor), numeros) != 'n'){
fprintf(dot, "%s];\n", a->valor);
}
if(a->esquerda){
fprintf(dot, "no%d--no%d;\n", a->id, a->esquerda->id);
ImprimeArvore(dot, a->esquerda, sinais, numeros, contador, qtd);
*contador += 1;
}
if(a->direita){
fprintf(dot, "no%d--no%d;\n", a->id, a->direita->id);
ImprimeArvore(dot, a->direita, sinais, numeros, contador, qtd);
*contador += 1;
}
if(*contador >= *qtd){
fprintf(dot, "}\n");
}
}
}