-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
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
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 6724e1e
A program to Print words contained in a file in alphabetical order
RandyKdev 4306610
Apply suggestions from code review
RandyKdev 1dd47b8
appropriate comments added as suggested from code review
RandyKdev f1d970c
comments cleaned up
RandyKdev cfd31fe
updating DIRECTORY.md
2dda396
Apply suggestions from code review
RandyKdev 3063155
commenting re-worded
RandyKdev 6f8487b
Add link to algorithm
RandyKdev 6027970
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev e834557
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev 4e63c82
main function moved to the bottom and function prototypes deleted
RandyKdev a558776
uint64_t data type used for non negative values
RandyKdev 1f25229
uint8_t used
RandyKdev f3f2643
all int types fixed
RandyKdev ff80883
detailed explanation of algorithm added
RandyKdev 047b8b6
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev 4a1ea7c
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev 86ed08f
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev ef394db
tests and documentation added
RandyKdev 4247fd3
Merge branch 'TheAlgorithms:master' into master
RandyKdev eb8299f
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev 043dff5
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev 94a06bd
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev 49ae848
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev dbccc30
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev 2bea89d
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev 93eb37d
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev e659327
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev 4b32697
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev e8237a6
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev 21a9deb
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev 78645fd
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev 6c4cd9b
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev 64ef0bc
documentation added
RandyKdev 485c281
documentation added for functions
RandyKdev 3aebafc
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev 29991bb
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev e690967
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev a0e5928
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev 936dfa6
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev bbbfcdb
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev d54ea8b
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev 61782de
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev 0eb6e10
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev 86944aa
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev 452251b
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev 1112bb4
Update data_structures/binary_trees/words_alphabetical.c
RandyKdev 8b6c385
Apply suggestions from code review
RandyKdev be6e890
documentation added
RandyKdev a55fb05
Merge branch 'master' of https://github.com/RandyKdev/C
RandyKdev d6c98fb
Apply suggestions from code review
RandyKdev 1671dcd
Add documentation
RandyKdev File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
RandyKdev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* 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> | ||
RandyKdev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/** | ||
* Structure defining a node in the binary tree | ||
RandyKdev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
*/ | ||
struct Node | ||
{ | ||
char *word; | ||
unsigned int frequency; | ||
struct Node *left; | ||
struct Node *right; | ||
RandyKdev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}; | ||
|
||
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); | ||
RandyKdev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
int main() | ||
RandyKdev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
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 | ||
RandyKdev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
*/ | ||
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 | ||
RandyKdev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* @param file pointer to file to be closed | ||
RandyKdev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
*/ | ||
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 | ||
RandyKdev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* @param node pointer to node to free | ||
RandyKdev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
*/ | ||
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 | ||
} | ||
} | ||
|
||
RandyKdev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/** | ||
* Ending the program due to an error | ||
RandyKdev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* @param errorMessage This is the error message to be printed | ||
RandyKdev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
*/ | ||
void endProgramAbruptly(char *errorMessage) | ||
{ | ||
fprintf(stderr, "%s\n", errorMessage); | ||
exit(EXIT_FAILURE); | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.