1+ #include "anagram.h"
2+ #include <stddef.h>
3+ #include <string.h>
4+ #include <stdbool.h>
5+ #include <ctype.h>
6+
7+ static bool is_anagram (const char * subject , const char * candidate ) {
8+ size_t len = strlen (subject );
9+ // Count letter frequencies in subject
10+ int subject_count [26 ] = {0 };
11+ for (size_t i = 0 ; i < len ; i ++ ) {
12+ char c = tolower (subject [i ]);
13+ if (c >= 'a' && c <= 'z' ) {
14+ subject_count [c - 'a' ]++ ;
15+ }
16+ }
17+
18+ // Subtract letter frequencies from candidate
19+ for (size_t i = 0 ; i < len ; i ++ ) {
20+ char c = tolower (candidate [i ]);
21+ if (c >= 'a' && c <= 'z' ) {
22+ subject_count [c - 'a' ]-- ;
23+ }
24+ if (subject_count [c - 'a' ] < 0 ) {
25+ return false;
26+ }
27+ }
28+
29+ return true;
30+ }
31+
32+ /**
33+ * @description - determines if any of the words in candidate are anagrams
34+ * for subject. Contents of candidate structures may be modified.
35+ */
36+ void find_anagrams (const char * subject , struct candidates * candidates ) {
37+ size_t len = strlen (subject );
38+ for (size_t i = 0 ; i < candidates -> count ; i ++ ) {
39+ if (candidates -> candidate [i ].is_anagram == UNCHECKED ) {
40+ // check word length to avoid index out of bounds
41+ if (len != strlen (candidates -> candidate [i ].word )) {
42+ candidates -> candidate [i ].is_anagram = NOT_ANAGRAM ;
43+ continue ;
44+ }
45+ // identical words are not anagrams
46+ size_t j = 0 ;
47+ for (; j < len ; j ++ ) {
48+ if (tolower (subject [j ]) != tolower (candidates -> candidate [i ].word [j ])) {
49+ break ;
50+ }
51+ }
52+ if (j == len ) {
53+ candidates -> candidate [i ].is_anagram = NOT_ANAGRAM ;
54+ } else {
55+ // check if the words are anagrams
56+ if (is_anagram (subject , candidates -> candidate [i ].word )) {
57+ candidates -> candidate [i ].is_anagram = IS_ANAGRAM ;
58+ } else {
59+ candidates -> candidate [i ].is_anagram = NOT_ANAGRAM ;
60+ }
61+ }
62+ }
63+ }
64+ }
0 commit comments