0

Stuck on speller, especially check, but load has some problems too. I am using a trie, but I kind of regret choosing it, because it has been very tough. I believe my problem is with the use of *next in the check section, but I do not know how to fix the problem. Hopefully someone can give me some hints so I can fix the problems in my code and make the program work.

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

#include "dictionary.h"

typedef struct trie
{
    bool is_word;
    struct trie *children[27];
}
trie;

trie *root;
unsigned int counter;

bool check(const char *word)
{
    trie *cursur = root;

    for (int i = 0, j = strlen(word); i < j; i++)
    {
        if (cursur -> *next == NULL)
        {
            return false;
        }

        else
        {
            cursur = cursur -> *next;
        }
    }

    if (cursur -> is_word == true)
    {
        return true;
    }

    return false;
}

bool load(const char *dictionary)
{
    FILE *df = fopen(dictionary, 'r');

    if (df == NULL)
    {
        printf("Could not open the file\n");
        return false;
    }

    root = calloc(sizeof(trie));
    counter = 0;
    int c;
    trie *cursur = root;

    while (c == fgetc(df) != EOF)
    {
        if (cursur -> children[c - 'a'] == NULL)
        {
            trie *next = calloc(sizeof(trie));
            cursur -> children[c - 'a'] = next;
            cursur = next;
        }

        if (cursur -> children[c - 'a'] != NULL)
        {
            cursur = cursur -> children[c - 'a'];
        }

        if (c == '\'')
        {
            trie *next = calloc(sizeof(trie));
            cursur -> children[26] = next;
            cursur = next;
        }

        if (cursur -> children[26] != NULL)
        {
            cursur = cursur -> children[26];
        }

        if (c == '\n')
        {
            is_word = true;
            counter++;
            cursur = root;
        }
    }

    if (fgetc(df) == EOF)
    {
        fclose(df);
        return true;
    }
}

unsigned int size(void)
{
    return counter;
}

bool unload(void)
{
    trie *cursur = root;
    free(cursur);
    return true;
}
0

I don't understand what you mean with *next, you don't declare that in check. Like in load, you probably meant something like children[word[i] - 'a'].

But that one is not a solution.

First, determine an index. Could be like

int index = isalpha(word[i]) ? tolower(word[i]) - 'a' : 26;

And only then use like cursor -> children[index]. Means you have the letter/apostrophe difference in one place, and everything else uses the same code.

condition ? value1 : value2 is the ternary operator/conditional operator, think of it like an if-else that's an expression, if the condition evaluates truthy, the expression evaluates to the first value, if the condition evaluates to something that can be cast to zero, the second value is returned instead. You could have an if-else with separate assignments instead, like

int index;
if (isalpha(word[i]))
{
    index = tolower(word[i]) - 'a';
}
else
{
    index = 26;
}

In load, you should use a similar structure. Pick the version you think best fits your code.

| improve this answer | |
  • Thanks, this helped a ton! – Jamie Olsen Mar 8 '18 at 13:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .