Created
October 29, 2015 12:28
-
-
Save zkxs/bc623999b1dada26abb1 to your computer and use it in GitHub Desktop.
Test case for a binary search function
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
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| // a linked-list node | |
| struct node { | |
| char *word; | |
| struct node *next; | |
| }; | |
| // perform a binary search | |
| int binary_search(int n, char **dictionary, char *word) { | |
| int min = 0; | |
| int max = n; | |
| int mid; | |
| /* while loop for binary search */ | |
| while (max > min) { | |
| mid = (max + min) / 2; | |
| if(strcmp(word, dictionary[mid]) == 0) { | |
| return 0; // false | |
| } | |
| else if(strcmp(word, dictionary[mid]) >= 0) { | |
| min = mid + 1; | |
| } | |
| else { | |
| max = mid; | |
| } | |
| } | |
| return 1; // true | |
| } | |
| int main(int argc, char *argv[]) { | |
| FILE *fp; // file pointer | |
| char *line = NULL; // line read from file | |
| size_t len = 0; // size of line buffer | |
| ssize_t read; // length of a word, or -1 if error | |
| size_t wordLength; // length of a word | |
| unsigned int numberOfWords = 0; // number of words we've read | |
| struct node *rootWord; // head of linked list | |
| struct node *prevWord = NULL; // previous node | |
| struct node *currentWord; // current node | |
| char *filename; // filename of wordlist | |
| if (argc != 2) { | |
| printf("Syntax: ./binarysearch <wordlist>\n"); | |
| exit(EXIT_FAILURE); | |
| } | |
| else { | |
| filename = argv[1]; | |
| } | |
| // open file | |
| fp = fopen(filename, "r"); | |
| if (fp == NULL) { | |
| printf("Could not read file\n"); | |
| exit(EXIT_FAILURE); | |
| } | |
| // read each line from file | |
| while ((read = getline(&line, &len, fp)) != -1) { | |
| ++numberOfWords; | |
| wordLength = (size_t) read; | |
| // remove trailing line terminators | |
| if (line[wordLength - 2] == '\r') { | |
| line[wordLength - 2] = '\0'; | |
| wordLength -= 2; | |
| } | |
| else if (line[wordLength - 1] == '\n') { | |
| line[wordLength - 1] = '\0'; | |
| wordLength -= 1; | |
| } | |
| // make a copy of the line buffer | |
| char *lineCopy = strndup(line, wordLength); | |
| currentWord = malloc(sizeof(struct node)); | |
| currentWord->word = lineCopy; | |
| currentWord->next = NULL; | |
| //TODO: check for out of memory errors? | |
| if (prevWord == NULL) { // this is the first node | |
| rootWord = currentWord; | |
| } | |
| else { // this is not the first word | |
| prevWord->next = currentWord; | |
| } | |
| prevWord = currentWord; | |
| } | |
| fclose(fp); | |
| if (line) { | |
| free(line); | |
| } | |
| // show how many words were loaded | |
| printf("Read %u words.\n", numberOfWords); | |
| // transfer words from linked list to array, now that we know how many there are | |
| char *dictionary[numberOfWords]; | |
| int index = 0; | |
| currentWord = rootWord; | |
| while (currentWord != NULL) { | |
| dictionary[index++] = currentWord->word; | |
| prevWord = currentWord; | |
| currentWord = currentWord->next; | |
| free(prevWord); | |
| } | |
| // ensure wordlist was pre-sorted because I don't want to sort it myself | |
| for (index = 0; index < numberOfWords - 1; index++) { | |
| if (strcmp(dictionary[index], dictionary[index + 1]) >= 0) { | |
| printf("Wordlist not sorted\n"); | |
| exit(EXIT_FAILURE); | |
| } | |
| } | |
| // prompt for words and search for them. break on empty string. | |
| char word[256]; | |
| while(1) { | |
| printf("> "); // show a prompt | |
| fgets(word, 256, stdin); | |
| if (word[0] == '\r' || word[0] == '\n') { | |
| break; | |
| } | |
| else { | |
| size_t len = strlen(word); | |
| // remove trailing line terminators | |
| if (word[len - 2] == '\r') { | |
| word[len - 2] = '\0'; | |
| } | |
| else if (word[len - 1] == '\n') { | |
| word[len - 1] = '\0'; | |
| } | |
| // search for result | |
| int result = binary_search(numberOfWords, dictionary, word); | |
| // not sure why you return true if a word wasn't found, but whatever | |
| if (result) { | |
| printf("\"%s\" not found.\n", word); | |
| } | |
| else { | |
| printf("\"%s\" found.\n", word); | |
| } | |
| } | |
| } | |
| // free dictionary from heap | |
| for (index = 0; index < numberOfWords; index++) { | |
| free(dictionary[index]); | |
| } | |
| printf("done.\n"); | |
| exit(EXIT_SUCCESS); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment