Skip to content

Instantly share code, notes, and snippets.

@zkxs
Created October 29, 2015 12:28
Show Gist options
  • Select an option

  • Save zkxs/bc623999b1dada26abb1 to your computer and use it in GitHub Desktop.

Select an option

Save zkxs/bc623999b1dada26abb1 to your computer and use it in GitHub Desktop.
Test case for a binary search function
#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