I need to calculate the height of a trie tree in C
the node struct is as follows:
struct trie_cel {
char type; // 'I': internal / 'P': letter
struct trie_cel *child [HEIGHT_ALPHABET]; // use the function CHAR_TO_INDEX to get child node of each letter
};
typedef struct trie_cel no;
i'm trying to use recursion
if(r == NULL) return -1;
if(!r) return 0;
int alt = 0;
int heightM = 0;
no** i = r->child;
no** fim = i + (sizeof(r->child) / sizeof(no *));
while(i != end){
alt = height(r->child[i])+1;
if(alt > heightM){
heightM = alt;
}
}
return heightM;
However, my code is presented with the following problem, could anyone help me?
trie.cpp: In function ‘int altura(no*)’:
trie.cpp:146:32: error: invalid types ‘trie_cel* [27][no** {aka trie_cel**}]’ for array subscript
alt = height(r->child[i])+1;
^
chmod: cannot access 'vpl_execution': No such file or directory
I was able to calculate using "int" but i'd like to learn how to calculate using pointers
Maybe use the pointer directly 'height(*i)'. Or use pointer arithmetics to convert to integer type: 'i - r->child'
I believe this is how you should approach:
int trie_height(no *root) {
if (root == NULL) return -1;
int i, h = 0;
for (i = 0; i < HEIGHT_ALPHABET; i++) {
int res = 1 + trie_height(root->child[i]);
if (res > h)
h = res;
}
return h;
}
Since child is an array, you can't adress it's elements anything other than an integer. i isn't an integer in your code, so it wouldn't work. Also, you're doing nothing with fim after assigning it, so it's useless there.
Related
I am actually trying to implement a breadth-first-search algorithm in C, as an input I take any graph from a file and store all nodes and vertices in a structure.
Then I create an adjacency matrix, and run through all columns, push encountered nodes on a stack, pop them and so on till I have all the paths.
Still I have problems storing those paths in a linked list, and by problem I mean that sometimes, from some specific cases, I lose the last value of my stored path (one int array per link), which is quite surprising as it occurs only on paths of length 5 (I cannot test all lengths but up to 12 it seems OK).
It's weird, because these values are lost at function exit (I tried debugging using LLDB and in the function that creates the link, the last byte exists, but once I leave the function, it does not) and not all the time (1 out 10 execution all is fine).
To me this is a malloc issue, so I checked every single malloc of my program in order to solve (unsuccessfully) the problem. Checked all the variables and all seems fine, except for this 5 length case (I assume my program has a 'defect' that is only apparent in this case, but why ?).
I would gladly accept some help, as I just ran out of things to check.
Here is the code of the main BFS function :
void bfs(t_lemin *e)
{
t_path *save;
//set needed variables
set_bfs_base_var(e);
save = e->p;
while (paths_remain(e))
{
//Special Start-End case
if (e->map[e->nb_start][e->nb_end] == 1)
{
create_single(e);
break ;
}
e->x = e->nb_start;
reset_tab(e);
while (e->x != e->nb_end)
{
e->y = 0;
while (e->y < e->nb_rooms)
{
if (e->map[e->x][e->y] == 1 && !e->visited[e->y])
##push_on_stack the nodes
push_stack(e);
e->y++;
}
//go_to first elem on stack
e->x = e->stack[0];
if (e->x == e->nb_end || is_stack_empty(e->stack, e->nb_rooms - 1))
break ;
e->visited[e->x] = 1;
//set_it as visited than pop it
pop_stack(e, e->nb_rooms);
}
if (is_stack_empty(e->stack, e->nb_rooms - 1))
break ;
e->find_new[add_path(e)] = 1;
discover_more_paths(e, save);
}
print_paths(e, save);
e->p = save;
}
And here the 2 functions that stores the paths in a linked list :
void create_path(t_lemin *e, int *pa, int len)
{
int j;
j = 1;
//create_new_node if required
if (e->p->path)
{
if (!(e->p->next = malloc(sizeof(t_path))))
return ;
e->p = e->p->next;
}
//create_the_array_for_path_storing
e->p->path = malloc(sizeof(int) * len + 2);
e->p->next = NULL;
e->p->size_path = len + 2;
//copy_in_it
while (--len >= 0)
{
e->p->path[j++] = pa[len];
}
//copy_end_and_start_at_end_and_start
e->p->path[e->p->size_path - 1] = e->nb_end;
e->p->path[0] = e->nb_start;
e->nb_paths++;
}
int add_path(t_lemin *e)
{
int i;
int save;
int *path;
int next_path;
i = 0;
if (!(path = malloc(sizeof(int) * e->nb_rooms)))
exit(-1);
save = e->nb_end;
//in_order_to_save_the_path_i store the previous value of each node so I can find the path by iterating backward
next_path = -1;
while (e->prev[save] != e->nb_start)
{
path[i] = e->prev[save];
save = e->prev[save];
next_path = next_path == -1 && get_nb_links(e, path[i])
> 2 ? path[i] : -1;
i++;
}
//path_contains all values of the path except for start and end
save = i;
while (i < e->nb_rooms)
{
path[i] = 0;
i++;
}
create_path(e, path, save);
i = next_path == -1 ? path[0] : next_path;
//ft_printf("to_block : %d\n", i);
return (next_path == -1 ? path[0] : next_path);
}
If needed here is a clone of the entire repository, the issue can be seen running the program with maptest in the main directory : https://github.com/Caribou123/bfs_agesp.git
Make && ./lem_in < maptest
All paths must end by the last room, whereas in this case the value of the last room becomes 0. So the program outputs "start->room1->room2->....->start as the index value of start is 0.
Here is a look at my 'e', the main structure. (it's quite huge, don't be scared) :
typedef struct s_lemin
{
int x;
int y;
char *av;
int nb_ants;
int st;
int nd;
int nb_rooms;
int nb_paths;
int max_sizep;
int nb_links;
int nb_start;
int nb_end;
int **map;
int *stack;
int *visited;
int *prev;
int *find_new;
int maxy;
int maxx;
int minx;
int conti;
int miny;
char ***saa;
struct s_rooms *r;
struct s_ants *a;
struct s_rooms **table_r;
struct s_links *l;
struct s_hash **h;
struct s_rooms *start;
struct s_rooms *end;
struct s_info *i;
struct s_path *p;
struct s_path *select_p;
}
Thank you in advance for your help, and sorry if it's some stupid malloc that I somehow missed.
Artiom
typedef struct veri{
int k[9],v[10];
}v;
v a[27];
int h(int x){
return x%27;
}
int put (v data){
if(a[h(data.k)].k == -1){
a[h(data.k)] = data;
return 1;
}
else {
int donusSayisi =0;
int indis = h(data.k);
while(a[indis].k != data.k && a[indis].k!=-1){
//printf("%d %d %d \n",a[indis].k, data.k, indis);
indis ++;
if(indis>=27){
if(donusSayisi>=1){
printf("hashtable dolu\n");
return -1;
}
indis = indis %27;
donusSayisi++;
}
}
a[indis].v[indis]= data.v[indis];
a[indis].k[indis] = data.k[indis];
}
}
ı am trying create hash table with array .But ı cant add it .I cant put it and get it.Where is my mistake.I am getting crazy because of this errors.This not my all code just a part..
if(a[h(data.k)].k == -1){
passing argument 1 of 'h ' makes integer from pointer without a cast
comparison between pointer and integer
return a[indis].v;
return makes integer from pointer without cast
In my binary search tree I want to create a function that can get all words starting with a prefix and store all words in an array called results
this is my tree
struct BinarySearchTree_t
{
char *mot,*def;
struct BinarySearchTree_t *left;
struct BinarySearchTree_t *right;
};
typedef struct BinarySearchTree_t BinarySearchTree;
my function :
size_t findWordsByPrefix(BinarySearchTree* tree, char* prefix, char*** results)
{
BinarySearchTree *tmp;
tmp=tree;
static int size=0;
if (!tmp)
return 0;
else if (strncmp(tmp->mot,prefix,strlen(prefix))==0)
{
(*results)= realloc(*results,(1+size)*sizeof(*(*results)));
(*(*results+size))= malloc(strlen(tmp->mot)*sizeof(char));
strcpy((*results)[size],tmp->mot);
size++;
return (1 + findWordsByPrefix(tmp->left,prefix, &results) + findWordsByPrefix(tmp->right,prefix, &results));
}
else
return (strncmp(tmp->mot,prefix,strlen(prefix))<0)?findWordsByPrefix(tmp->right,prefix, &results):findWordsByPrefix(tmp->left,prefix, &results) ;
}
This function should return a number of words starting with the given prefix.
my problem is that the program crash when it is run , and I don't how to resize my array results
so every time I found a word I should increase the size of the results array .
and I would know how exacly manipulate the pointer of pointer of pointer given in arg of this function (char ***results) : what exactly means?
If I simply compile your code, I get severe compiler warnings including:
1>binarysearchtree.c(98) : warning C4047: 'function' : 'char ***' differs in levels of indirection from 'char ****'
1>binarysearchtree.c(98) : warning C4024: 'findWordsByPrefix' : different types for formal and actual parameter 3
This alone will cause a crash -- you are calling your own function recursively with the wrong arguments.
Next, I believe you need to allocate one more than the length of the string, to hold a copy of a string:
malloc((strlen(tmp->mot) + 1 )*sizeof(char))
Next, you're passing around an array of strings of variable size -- and storing the size in a static variable. It's impossible to know if this will work, so don't do it.
Instead, if you want to use a dynamic array of strings, I suggest extracting out a struct to hold them, like so:
struct ResultTable_t
{
int size;
char **results;
};
typedef struct ResultTable_t ResultTable;
void InitializeResults(ResultTable *p_table)
{
p_table->size = 0;
p_table->results = NULL;
}
void AddResult(ResultTable *p_table, char *result)
{
if (result == NULL)
return;
p_table->size++;
p_table->results = realloc(p_table->results, p_table->size * sizeof(*p_table->results));
p_table->results[p_table->size-1] = malloc((strlen(result) + 1) * sizeof(**p_table->results));
strcpy(p_table->results[p_table->size-1], result);
}
void FreeResults(ResultTable *p_table)
{
if (p_table->results != NULL)
{
int i;
for (i = 0; i < p_table->size; i++)
{
free(p_table->results[i]);
}
free(p_table->results);
}
p_table->size = 0;
p_table->results = NULL;
}
(As an improvement, you might consider using geometric growth instead of linear growth for your table of results.)
Then your function becomes:
size_t findWordsByPrefix(BinarySearchTree* tree, char* prefix, ResultTable *p_table)
{
if (!tree)
return 0;
else if (strncmp(tree->mot,prefix,strlen(prefix))==0)
{
AddResult(p_table, tree->mot);
return (1 + findWordsByPrefix(tree->left,prefix, p_table) + findWordsByPrefix(tree->right,prefix, p_table));
}
else if (strncmp(tree->mot,prefix,strlen(prefix))<0)
{
return findWordsByPrefix(tree->right,prefix, p_table);
}
else
{
return findWordsByPrefix(tree->left,prefix, p_table);
}
}
And you would use it like:
ResultTable results;
InitializeResults(&results);
// Get some prefix to search for.
char prefix = GetSomePrefix();
int size = findWordsByPrefix(tree, prefix, &results);
// Do something with the results
// Free all memory of the results
FreeResults(&results);
Update
If the ResultTable is distasteful for some reason, you can pass the dynamic array and array sizes in directly:
void AddResult(char ***p_results, int *p_size, char *word)
{
if (word == NULL)
return;
(*p_size)++;
(*p_results) = realloc(*p_results, ((*p_size)+1) * sizeof(**p_results));
(*p_results)[(*p_size)-1] = malloc((strlen(word) + 1) * sizeof(***p_results));
strcpy((*p_results)[(*p_size)-1], word);
}
void FreeResults(char ***p_results, int *p_size)
{
int i;
if (p_results == NULL || *p_results == NULL)
return;
for (i = 0; i < (*p_size); i++)
{
free ((*p_results)[i]);
}
free (*p_results);
*p_results = NULL;
*p_size = 0;
}
size_t findWordsByPrefix(BinarySearchTree* tree, char* prefix, char ***p_results, int *p_size)
{
if (!tree)
return 0;
else if (strncmp(tree->mot,prefix,strlen(prefix))==0)
{
AddResult(p_results, p_size, tree->mot);
return (1 + findWordsByPrefix(tree->left,prefix, p_results, p_size) + findWordsByPrefix(tree->right,prefix, p_results, p_size));
}
else if (strncmp(tree->mot,prefix,strlen(prefix))<0)
{
return findWordsByPrefix(tree->right,prefix, p_results, p_size);
}
else
{
return findWordsByPrefix(tree->left,prefix, p_results, p_size);
}
}
and use like:
char **results = NULL;
int tablesize = 0;
// Get some prefix to search for.
char prefix = GetSomePrefix();
int size = findWordsByPrefix(tree, prefix, &results, &tablesize);
// Do something with the results
// Free all memory of the results
FreeResults(&results, &tablesize);
I am working on implementation of strongly connected component using Tarjan's algorithm. I am giving input as a linked list of nodes and edges. However, gcc compiler gives segmentation fault every time in the recursive function(where in the while loop I am checking for adjacent nodes of a vertex).
Any idea what's wrong in this code?
void strongconnect(int Vertex)
{
struct sc_node * Ver;
Ver = search_node(Vertex);
Ver->sc_index = ind; //accessing the index information of node
Ver->sc_lowlink = ind; // accessing the link information of node
//Ver->visited = 1;
ind++;
int w;
push(Vertex);
struct sc_node * to_link, *to_link1;
int to_lowlink,to_index;
int flowlink;
int min;
int from_index;
edge_trav = edge_head;
while(edge_trav != NULL) //accessing linked list of edges
{
if(edge_trav->from_vertex == Vertex)
{
to_link = search_node(edge_trav->to_vertex);
to_lowlink = to_link->sc_lowlink;
to_index = to_link->sc_index;
to_link1 = search_node(Vertex);
flowlink = to_link1->sc_lowlink;
from_index = to_link1->sc_index;
if(to_index == 0)
{ Vertex = to_link->sc_data;
printf("INSIDE RECURSION");
strongconnect(Vertex); // recursive loop
min = minimum(flowlink,to_lowlink);
to_link1->sc_lowlink = min;
}
else
{
min = minimum(flowlink, from_index);
to_link1->sc_lowlink = min;
} }
edge_trav = edge_trav->next;
}
Ver = search_node(Vertex);
if(Ver->sc_lowlink == Ver->sc_index)
{
do
{
w = pop();
printf("%d\t",w);
}while(w != Vertex);
}
}
I suggest you compile you program with gcc's -s and then run your program with valgrind. It's very useful memory leak checker. With it, you can figure out by yourself with is you program accessing an illegal memory position. As #Dogbert pointed, it looks you are dereferencing an NULL pointer.
I have an array which has a key and info for each index in the array.
This builds the array
table_t *table_construct (int table_size, int probe_type)
{
int i;
table_t *hash;
if(table_size < 1) return NULL;
hash = malloc(sizeof(table_t));
hash->table = malloc(sizeof(list_t*) * table_size);
for(i=0; i < table_size - 1; i++)
{
hash->table[i] = NULL;
//hash->table[i]->next = NULL;
}
hash->size = table_size;
hash->probing_type = probe_type;
return hash;
}
So I have the list_t and the table_t structures. I have the following line in my code that is not working correctly:
hash->table[item]->K = K;
It can be seen in this part of my code:
int dec, item, hold;
item = hashing(hash,K);
hold = item;
if(hash->table[item] == NULL)
{
hash->table[item]->K = K;
hash->table[item]->I = I;
return 0;
}
When I GDB it, K is a number.
So what is happening here is, I have my table which is indexed with item. Then I add K to the key of the index. When ever this line comes up anywhere in my program I get a seg Fault.
Can you see anything Ive done wrong here?
You verified your pointer is null, so before you can reference off it you need to assign it something:
if(hash->table[item] == NULL)
{
hash->table[item] = malloc(sizeof(list_t)); // you were missing this.
hash->table[item]->K = K;
hash->table[item]->I = I;
return 0;
}
According to what you posted in your table_construct function, the elements of table array are null pointers. You are not allowed to perform any kind of access through null pointers.
And this just doesn't make sense
if(hash->table[item] == NULL)
{
hash->table[item]->K = K;
hash->table[item]->I = I;
return 0;
}
Here you make an explicit attempt to write data through a null pointer.
You have to make sure a pointer points to a valid object before you make any attempts to access anything (write or read) through that pointer.
In your function table_construct,when you malloc hash->table,you should do it like this.
hash->table = (list_t **)malloc(sizeof(list_t*) * table_size);
for (i=0;i<table_size;i++)
{
hash->table[i] = (list_t *)malloc(sizeof(list_t));
}
You do that made then null,if you want to do like this.
memset(hash->table[i],0,sizeof(list_t));
Then you can use this judgment statement.
if(hash->table[item] != NULL)
{
hash->table[item]->K = K;
hash->table[item]->I = I;
return 0;
}