Skip to content

feat: Added a program that prints words in alphabetical order using binary tree data structure #841

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 53 commits into from
Jul 30, 2021
Merged
Changes from 2 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
ed56470
frequencies of words started
RandyKdev Jul 14, 2021
6724e1e
A program to Print words contained in a file in alphabetical order
RandyKdev Jul 14, 2021
4306610
Apply suggestions from code review
RandyKdev Jul 17, 2021
1dd47b8
appropriate comments added as suggested from code review
RandyKdev Jul 17, 2021
f1d970c
comments cleaned up
RandyKdev Jul 17, 2021
cfd31fe
updating DIRECTORY.md
Jul 17, 2021
2dda396
Apply suggestions from code review
RandyKdev Jul 18, 2021
3063155
commenting re-worded
RandyKdev Jul 18, 2021
6f8487b
Add link to algorithm
RandyKdev Jul 19, 2021
6027970
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev Jul 26, 2021
e834557
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev Jul 27, 2021
4e63c82
main function moved to the bottom and function prototypes deleted
RandyKdev Jul 27, 2021
a558776
uint64_t data type used for non negative values
RandyKdev Jul 27, 2021
1f25229
uint8_t used
RandyKdev Jul 27, 2021
f3f2643
all int types fixed
RandyKdev Jul 27, 2021
ff80883
detailed explanation of algorithm added
RandyKdev Jul 27, 2021
047b8b6
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev Jul 27, 2021
4a1ea7c
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev Jul 27, 2021
86ed08f
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev Jul 27, 2021
ef394db
tests and documentation added
RandyKdev Jul 28, 2021
4247fd3
Merge branch 'TheAlgorithms:master' into master
RandyKdev Jul 28, 2021
eb8299f
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev Jul 28, 2021
043dff5
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev Jul 28, 2021
94a06bd
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev Jul 28, 2021
49ae848
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev Jul 28, 2021
dbccc30
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev Jul 28, 2021
2bea89d
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev Jul 28, 2021
93eb37d
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev Jul 28, 2021
e659327
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev Jul 28, 2021
4b32697
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev Jul 28, 2021
e8237a6
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev Jul 28, 2021
21a9deb
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev Jul 28, 2021
78645fd
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev Jul 28, 2021
6c4cd9b
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev Jul 28, 2021
64ef0bc
documentation added
RandyKdev Jul 28, 2021
485c281
documentation added for functions
RandyKdev Jul 28, 2021
3aebafc
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev Jul 29, 2021
29991bb
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev Jul 29, 2021
e690967
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev Jul 29, 2021
a0e5928
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev Jul 29, 2021
936dfa6
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev Jul 29, 2021
bbbfcdb
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev Jul 29, 2021
d54ea8b
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev Jul 29, 2021
61782de
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev Jul 29, 2021
0eb6e10
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev Jul 29, 2021
86944aa
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev Jul 29, 2021
452251b
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev Jul 29, 2021
1112bb4
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev Jul 29, 2021
8b6c385
Apply suggestions from code review
RandyKdev Jul 29, 2021
be6e890
documentation added
RandyKdev Jul 29, 2021
a55fb05
Merge branch 'master' of https://github.com/RandyKdev/C
RandyKdev Jul 29, 2021
d6c98fb
Apply suggestions from code review
RandyKdev Jul 29, 2021
1671dcd
Add documentation
RandyKdev Jul 29, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
226 changes: 226 additions & 0 deletions data_structures/binary_trees/words_alphabetical.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
/**
* @file
* @brief Printing the words contained in a file "file.txt" in alphabetical
* order and also their frequencies in to another file "wordcount.txt"
*/
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/**
* Structure defining a node in the binary tree
*/
struct Node
{
char *word;
unsigned int frequency;
struct Node *left;
struct Node *right;
};

struct Node *readWordsInFileToTree(FILE *file, struct Node *root);
struct Node *addWordToTree(char *word, struct Node *currentNode);
void writeContentOfTreeToFile(struct Node *node, FILE *file);
char *getPointerToWord(char *word);
struct Node *allocateMemoryForNode();
void closeFile(FILE *file);
void freeTreeMemory(struct Node *node);
void endProgramAbruptly(char *errorMessage);

int main()
{
struct Node *root = NULL;
FILE *file = NULL;

file = fopen("file.txt", "r");
if (file == NULL)
endProgramAbruptly("file: 'file.txt' not found");

root = readWordsInFileToTree(file, root);
closeFile(file);

file = fopen("wordcount.txt", "a");
fprintf(file, "%-5s \t %9s \t %s \n", "S/N", "FREQUENCY", "WORD");
writeContentOfTreeToFile(root, file);
closeFile(file);

freeTreeMemory(root);

return 0;
}

/**
* Read words from file to binary tree
* @param file file to be read from
* @param root top node of tree
*/
struct Node *readWordsInFileToTree(FILE *file, struct Node *root)
{
char *inputString = (char *)malloc(46 * sizeof(char));
// longest english word = 45 chars
// +1 for '\0' = 46 chars
char inputChar;
bool isPrevCharAlpha = false;
int pos = 0;
while ((inputChar = fgetc(file)) != EOF)
{
if (pos > 0)
isPrevCharAlpha = isalpha(inputString[pos - 1]);

// check if character is letter
if (isalpha(inputChar))
{
inputString[pos++] = tolower(inputChar);
continue;
}

// check if char is ' or - and if it is preceded by a letter
// eg yours-not, persons' (valid)
if ((inputChar == '\'' || inputChar == '-') && isPrevCharAlpha)
{
inputString[pos++] = inputChar;
continue;
}

// making sure that there is something valid in inputString
if (pos == 0)
continue;

// if last character is not letter and is not ' then replace by \0
if (!isPrevCharAlpha && inputString[pos - 1] != '\'')
pos--;
inputString[pos] = '\0';
pos = 0;
isPrevCharAlpha = false;
root = addWordToTree(inputString, root);
}
// this is to catch the case for the EOF
// being immediately after the last letter or '
if (pos > 0)
{
if (!isPrevCharAlpha && inputString[pos - 1] != '\'')
pos--;
inputString[pos] = '\0';
root = addWordToTree(inputString, root);
}

free(inputString);
return root;
}

/**
* Adding words in to the correct position in the tree
* @param word word to be inserted in to the tree
* @param currentNode current node of the tree which we comparing against
*/
struct Node *addWordToTree(char *word, struct Node *currentNode)
{
if (currentNode == NULL)
{
struct Node *currentNode = allocateMemoryForNode();
currentNode->word = getPointerToWord(word);
currentNode->frequency = 1;
currentNode->left = NULL;
currentNode->right = NULL;
return currentNode;
}
int compared = strcmp(word, currentNode->word);

if (compared > 0)
currentNode->right = addWordToTree(word, currentNode->right);
else if (compared < 0)
currentNode->left = addWordToTree(word, currentNode->left);
else
{
currentNode->frequency++;
}
return currentNode;
}

/**
* Writes contents of the tree to another file alphabetically
* @param node current node to be printed to file
* @param file pointer to file to be written to
*/
void writeContentOfTreeToFile(struct Node *node, FILE *file)
{
static int i = 1;
if (node != NULL)
{
writeContentOfTreeToFile(node->left, file);
fprintf(file, "%-5d \t %-9u \t %s \n", i++, node->frequency,
node->word);
writeContentOfTreeToFile(node->right, file);
}
}

/**
* Stores a word and returns address to memory
* @param word word to be stored in memory
*/
char *getPointerToWord(char *word)
{
char *string = (char *)malloc((strlen(word) + 1) * sizeof(char));
// + 1 is for the '\0' character
if (string != NULL)
{
strcpy(string, word);
return string;
}
endProgramAbruptly(
"\n A problem occurred while reserving memory for word \n");
return NULL;
}

/**
* Reserves memory capable of storing a node and returns the address
*/
struct Node *allocateMemoryForNode()
{
struct Node *node = (struct Node *)malloc(sizeof(struct Node));
if (node != NULL)
return node;
endProgramAbruptly(
"\n A problem occured while reserving memory for structure \n");
return NULL;
}

/**
* Closes a file when the read or write process is done
* @param file pointer to file to be closed
*/
void closeFile(FILE *file)
{
int closed = fclose(file);
if (closed != 0)
endProgramAbruptly(" \n A Problem Occurred while closing a file \n");
}

/**
* Freeing memory when program is terminating
* @param node pointer to node to free
*/
void freeTreeMemory(struct Node *node)
{
if (node != NULL)
{
freeTreeMemory(node->left);
freeTreeMemory(node->right);
free(node->word);
// freeing node->word because memory was allocated using malloc
free(node);
// freeing node because memory was allocated using malloc
}
}

/**
* Ending the program due to an error
* @param errorMessage This is the error message to be printed
*/
void endProgramAbruptly(char *errorMessage)
{
fprintf(stderr, "%s\n", errorMessage);
exit(EXIT_FAILURE);
}