user
4 years ago
commit
7d2ee1a0e5
2 changed files with 164 additions and 0 deletions
@ -0,0 +1,4 @@
@@ -0,0 +1,4 @@
|
||||
GCC = gcc -O2
|
||||
|
||||
default: main.c |
||||
$(GCC) main.c -o anagram
|
@ -0,0 +1,160 @@
@@ -0,0 +1,160 @@
|
||||
#include <stdio.h> |
||||
#include <string.h> |
||||
#include <stdlib.h> |
||||
#include <ctype.h> |
||||
|
||||
// for string qsort
|
||||
int compar(const void * l1, const void *l2) { |
||||
return *(char *)l1 > *(char*)l2; |
||||
} |
||||
|
||||
#define LINELENGTH 200 |
||||
|
||||
void make_lowercase(char *word) { |
||||
int j = 0; |
||||
while (word[j] != '\0') { |
||||
if (isupper(word[j])) { |
||||
word[j] = tolower(word[j]); |
||||
} |
||||
j++; |
||||
} |
||||
} |
||||
|
||||
int *count_char(char *word) { |
||||
make_lowercase(word); |
||||
int* counts = calloc(27, sizeof(int)); |
||||
|
||||
int j = 0; |
||||
while (word[j] != '\0') { |
||||
if (word[j] > 'z' || word[j] < 'a') { |
||||
free(counts); |
||||
return 0; |
||||
} |
||||
counts[word[j] - 'a'] += 1; |
||||
j++; |
||||
} |
||||
return counts; |
||||
} |
||||
|
||||
int get_minimum_match(char *word, int added) { |
||||
FILE *wfile = fopen("/usr/share/dict/words", "r"); |
||||
char line[LINELENGTH]; |
||||
int err; |
||||
int len = strlen(word); |
||||
int *min_letter_counts = count_char(word); |
||||
if (!min_letter_counts) { |
||||
fclose(wfile); |
||||
return 1; |
||||
} |
||||
|
||||
do { |
||||
err = fscanf(wfile, "%s\n", line); |
||||
if (err == EOF) { |
||||
break; |
||||
} |
||||
|
||||
int line_len = strlen(line); |
||||
if (line_len < len || line_len > (len + added)) { |
||||
continue; |
||||
} |
||||
|
||||
int* word_counts = count_char(line); |
||||
if (!word_counts) { |
||||
continue; |
||||
} |
||||
|
||||
int match = 1; |
||||
|
||||
for (int i = 0; i < 26; i++) { |
||||
if (min_letter_counts[i] > word_counts[i]) { |
||||
match = 0; |
||||
} |
||||
} |
||||
|
||||
if (match) { |
||||
printf("%s +", line); |
||||
for (int i = 0; i < 26; i++) { |
||||
int diff = word_counts[i] - min_letter_counts[i]; |
||||
if (diff > 0) { |
||||
printf(" %d%c", diff, i + 'a'); |
||||
} |
||||
} |
||||
printf("\n"); |
||||
} |
||||
|
||||
} while (err != EOF); |
||||
|
||||
free(min_letter_counts); |
||||
fclose(wfile); |
||||
return 0; |
||||
} |
||||
|
||||
int get_exact_anag(char *word) { |
||||
FILE *wfile = fopen("/usr/share/dict/words", "r"); |
||||
make_lowercase(word); |
||||
|
||||
char line[LINELENGTH]; |
||||
int err; |
||||
int len = strlen(word); |
||||
// sort line
|
||||
qsort(word, len, sizeof(char), compar); |
||||
|
||||
do { |
||||
err = fscanf(wfile, "%s\n", line); |
||||
if (err == EOF) { |
||||
break; |
||||
} |
||||
if (strlen(line) != len) { |
||||
continue; |
||||
} |
||||
make_lowercase(line); |
||||
|
||||
char nline[LINELENGTH]; |
||||
memcpy(nline, line, (sizeof(char) * LINELENGTH)); |
||||
|
||||
// sort line
|
||||
qsort(line, len, sizeof(char), compar); |
||||
|
||||
if (!strcmp(line, word)) { |
||||
printf("%s\n", nline); |
||||
} |
||||
|
||||
} while (err != EOF); |
||||
|
||||
fclose(wfile); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
int main (int argc, char **argv) { |
||||
|
||||
char word[LINELENGTH]; |
||||
|
||||
if (argc <= 2) { |
||||
printf("cmd min <word> numdiff\ncmd exact <word>\n"); |
||||
return 1; |
||||
} |
||||
|
||||
if (argv[1][0] == 'e') { |
||||
if (argc != 3) { |
||||
fprintf(stderr, "Wrong args.\n"); |
||||
return 1; |
||||
} |
||||
strcpy(word, argv[2]); |
||||
get_exact_anag(word); |
||||
} else if (argv[1][0] == 'm') { |
||||
if (argc != 4) { |
||||
fprintf(stderr, "Wrong args.\n"); |
||||
return 1; |
||||
} |
||||
int num = atoi(argv[2]); |
||||
strcpy(word, argv[3]); |
||||
if (num == 0) { |
||||
get_exact_anag(word); |
||||
} else { |
||||
get_minimum_match(word, num); |
||||
} |
||||
} else { |
||||
printf("cmd min <word> numdiff\ncmd exact <word>\n"); |
||||
} |
||||
} |
Loading…
Reference in new issue