Words from neighbour ones: Difference between revisions
Content added Content deleted
(C++ code efficiency improvement) |
(C - revert to previous version) |
||
Line 76: | Line 76: | ||
</pre> |
</pre> |
||
=={{header|C}}== |
=={{header|C}}== |
||
<lang c>#include < |
<lang c>#include <stdio.h> |
||
#include <stdio.h> |
|||
#include <stdlib.h> |
#include <stdlib.h> |
||
#include <string.h> |
#include <string.h> |
||
Line 84: | Line 83: | ||
#define MIN_LENGTH 9 |
#define MIN_LENGTH 9 |
||
#define WORD_SIZE (MIN_LENGTH + 1) |
#define WORD_SIZE (MIN_LENGTH + 1) |
||
#define BUFFER_SIZE (MIN_LENGTH + 1) |
|||
void fatal(const char* message) { |
|||
fprintf(stderr, "%s\n", message); |
|||
exit(1); |
|||
} |
} |
||
void* xmalloc(size_t n) { |
|||
struct word_buffer { |
|||
void* ptr = malloc(n); |
|||
if (ptr == NULL) |
|||
fatal("Out of memory"); |
|||
⚫ | |||
⚫ | |||
}; |
|||
void word_buffer_init(struct word_buffer* buffer) { |
|||
⚫ | |||
buffer->end = 0; |
|||
} |
} |
||
void* xrealloc(void* p, size_t n) { |
|||
void word_buffer_append(struct word_buffer* buffer, const char* word) { |
|||
void* ptr = realloc(p, n); |
|||
⚫ | |||
if (ptr == NULL) |
|||
buffer->end = (buffer->end + 1) % BUFFER_SIZE; |
|||
fatal("Out of memory"); |
|||
if (buffer->start == buffer->end) |
|||
⚫ | |||
buffer->start = (buffer->start + 1) % BUFFER_SIZE; |
|||
} |
} |
||
int word_compare(const void* p1, const void* p2) { |
|||
return ( |
return memcmp(p1, p2, WORD_SIZE); |
||
} |
} |
||
const char* word_buffer_get(const struct word_buffer* buffer, size_t index) { |
|||
return buffer->words[(index + buffer->start) % BUFFER_SIZE]; |
|||
} |
|||
bool word_buffer_contains(const struct word_buffer* buffer, const char* word) { |
|||
const size_t n = word_buffer_size(buffer); |
|||
⚫ | |||
if (word_compare(word, word_buffer_get(buffer, i)) == 0) |
|||
⚫ | |||
⚫ | |||
} |
|||
// The input file must consist of one word per line in alphabetical order. |
|||
int main(int argc, char** argv) { |
int main(int argc, char** argv) { |
||
const char* filename = argc < 2 ? "unixdict.txt" : argv[1]; |
const char* filename = argc < 2 ? "unixdict.txt" : argv[1]; |
||
Line 133: | Line 115: | ||
} |
} |
||
char line[MAX_WORD_SIZE]; |
char line[MAX_WORD_SIZE]; |
||
size_t size = 0, capacity = 1024; |
|||
struct word_buffer words; |
|||
⚫ | |||
word_buffer_init(&words); |
|||
⚫ | |||
int count = 0; |
|||
while (fgets(line, sizeof(line), in)) { |
while (fgets(line, sizeof(line), in)) { |
||
size_t len = strlen(line) - 1; // last character is newline |
size_t len = strlen(line) - 1; // last character is newline |
||
Line 142: | Line 122: | ||
continue; |
continue; |
||
line[len] = '\0'; |
line[len] = '\0'; |
||
if (size == capacity) { |
|||
capacity *= 2; |
|||
words = xrealloc(words, WORD_SIZE * capacity); |
|||
} |
|||
⚫ | |||
++size; |
|||
} |
|||
fclose(in); |
|||
qsort(words, size, WORD_SIZE, word_compare); |
|||
⚫ | |||
⚫ | |||
⚫ | |||
char word[WORD_SIZE] = { 0 }; |
char word[WORD_SIZE] = { 0 }; |
||
for (size_t |
for (size_t j = 0; j < MIN_LENGTH; ++j) |
||
word[ |
word[j] = words[(i + j) * WORD_SIZE + j]; |
||
if (word_compare(word, prev_word) == 0) |
if (word_compare(word, prev_word) == 0) |
||
continue; |
continue; |
||
if ( |
if (bsearch(word, words, size, WORD_SIZE, word_compare)) |
||
printf("%2d. %s\n", ++count, word); |
printf("%2d. %s\n", ++count, word); |
||
memcpy(prev_word, word, WORD_SIZE); |
memcpy(prev_word, word, WORD_SIZE); |
||
} |
} |
||
free(words); |
|||
return EXIT_SUCCESS; |
return EXIT_SUCCESS; |
||
}</lang> |
}</lang> |