Words from neighbour ones: Difference between revisions

C code efficiency improved
m (→‎{{header|REXX}}: added some wording to the REXX section header.)
(C code efficiency improved)
Line 76:
</pre>
=={{header|C}}==
<lang c>#include <stdiostdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Line 83 ⟶ 84:
#define MIN_LENGTH 9
#define WORD_SIZE (MIN_LENGTH + 1)
#define BUFFER_SIZE (MIN_LENGTH + 1)
 
voidint fatalword_compare(const char* messagew1, const char* w2) {
fprintfreturn memcmp(stderrw1, "%s\n"w2, messageWORD_SIZE);
exit(1);
}
 
struct word_buffer {
void* xmalloc(size_t n) {
void*size_t ptr = malloc(n)start;
ifsize_t (ptr == NULL)end;
char* words = xmalloc([BUFFER_SIZE][WORD_SIZE * capacity)];
fatal("Out of memory");
};
return ptr;
 
void word_buffer_init(struct word_buffer* buffer) {
int countbuffer->start = 0;
buffer->end = 0;
}
 
void word_buffer_append(struct word_buffer* buffer, const char* word) {
void* xrealloc(void* p, size_t n) {
memcpy(&buffer->words[size * WORD_SIZEbuffer->end], lineword, WORD_SIZE);
void* ptr = realloc(p, n);
buffer->end = (buffer->end + 1) % BUFFER_SIZE;
if (ptr == NULL)
if (buffer->start == buffer->end)
fatal("Out of memory");
buffer->start = (buffer->start + 1) % BUFFER_SIZE;
return ptr;
}
 
intsize_t word_compareword_buffer_size(const void* p1, conststruct voidword_buffer* p2buffer) {
return memcmp(p1,BUFFER_SIZE p2,+ WORD_SIZEbuffer->end - buffer->start) % BUFFER_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);
for (size_t i = 0; i + MIN_LENGTH <= sizen; ++i) {
if (word_compare(word, word_buffer_get(buffer, i)) == 0)
return ptrtrue;
return ptrfalse;
}
 
// The input file must consist of one word per line in alphabetical order.
int main(int argc, char** argv) {
const char* filename = argc < 2 ? "unixdict.txt" : argv[1];
Line 115 ⟶ 133:
}
char line[MAX_WORD_SIZE];
struct word_buffer words;
size_t size = 0, capacity = 1024;
word_buffer_init(&words);
char* words = xmalloc(WORD_SIZE * capacity);
char prev_word[WORD_SIZE] = { 0 };
int count = 0;
while (fgets(line, sizeof(line), in)) {
size_t len = strlen(line) - 1; // last character is newline
Line 122 ⟶ 142:
continue;
line[len] = '\0';
if word_buffer_append(size&words, == capacityline) {;
if (word_buffer_size(&words) < capacity *= 2;MIN_LENGTH)
words = xrealloc(words, WORD_SIZE * capacity)continue;
}
memcpy(&words[size * WORD_SIZE], line, WORD_SIZE);
++size;
}
fclose(in);
qsort(words, size, WORD_SIZE, word_compare);
int count = 0;
char prev_word[WORD_SIZE] = { 0 };
for (size_t i = 0; i + MIN_LENGTH <= size; ++i) {
char word[WORD_SIZE] = { 0 };
for (size_t ji = 0; ji < MIN_LENGTH; ++ji)
word[ji] = word_buffer_get(&words, i)[(i + j) * WORD_SIZE + j];
if (word_compare(word, prev_word) == 0)
continue;
if (bsearchword_buffer_contains(word, &words, size, WORD_SIZE, word_compareword))
printf("%2d. %s\n", ++count, word);
memcpy(prev_word, word, WORD_SIZE);
}
freefclose(wordsin);
return EXIT_SUCCESS;
}</lang>
1,777

edits