Back to list of problems
Anagram checker
148.c
/* 148 - Anagram checker */ #include <stdio.h> #include <string.h> #include <stdlib.h> #define BS 64 /* Begin: Fri, 21 May 2010 12:09:08 +0200 */ /* End: Fri, 21 May 2010 14:14:59 +0200 */ int nwords; char **words; int ntwords; char **twords; char * phrase; char sorted[1024]; int letters[26]; void check(int pos, int left, char * result) { int i; int ok; if (left==0) { if (strcmp(result, sorted) != 0) { printf("%s =%s\n", phrase, result); } return; } if (pos==ntwords) { return; } for (i=0; i<strlen(twords[pos]); i++) { letters[twords[pos][i]-'A']--; } ok = 1; for (i=0; i<26; i++) { if (letters[i] < 0) { ok = 0; break; } } if (ok) { strcat(result, " "); strcat(result, twords[pos]); check(pos+1, left-strlen(twords[pos]), result); result[strlen(result)-strlen(twords[pos])-1] = 0; } for (i=0; i<strlen(twords[pos]); i++) { letters[twords[pos][i]-'A']++; } check(pos+1, left, result); } static int cmpstringp(const void *p1, const void *p2) { return strcmp(* (char * const *) p1, * (char * const *) p2); } int main(void) { char buf[BS]; char word[BS]; while (fgets(buf, BS, stdin)) { if (buf[0]=='#') { break; } if (sscanf(buf, "%s", word) != 1) { abort(); } else { int l = strlen(word); words = realloc(words, (nwords+1)*sizeof(char*)); words[nwords] = malloc(l+1); strcpy(words[nwords], word); nwords++; } } twords = malloc((nwords+1)*sizeof(char*)); #if DEBUG { int i; for (i=0; i<nwords; i++) { printf("WORD[%d]: \"%s\"\n", i, words[i]); } } #endif while (fgets(buf, BS, stdin)) { int i,j; int ok; int nletters = 0; char result[1024]; if (buf[0]=='#') { break; } buf[strlen(buf)-1] = 0; phrase = buf; { int ntt = 0; char **tt = NULL; char copy[1024]; char *s, *t; strcpy(copy, phrase); t = copy; while ((s = strtok(t, " \t\r\n"))) { t = NULL; tt = realloc(tt, (ntt+1)*sizeof(char *)); tt[ntt++] = s; } qsort(tt, ntt, sizeof(char*), cmpstringp); sorted[0] = 0; for (i=0; i<ntt; i++) { strcat(sorted, " "); strcat(sorted, tt[i]); } } memset(letters, 0, sizeof(letters)); for (i=0; i<strlen(buf); i++) { if (buf[i] >= 'A' && buf[i] <= 'Z') { letters[buf[i]-'A']++; nletters++; } } ntwords=0; for (i=0; i<nwords; i++) { ok=1; for (j=0; j<strlen(words[i]); j++) { if (!letters[words[i][j]-'A']) { ok = 0; break; } } if (ok) { twords[ntwords++] = words[i]; } } #if DEBUG { int i; printf("ntwords=%d\n", ntwords); printf("%s =", buf); for (i=0; i<ntwords; i++) { printf(" %s", twords[i]); } printf("\n"); } #endif result[0] = 0; check(0, nletters, result); #if DEBUG printf("%s = ", buf); for (i=0; i<26; i++) { for (j=0; j<letters[i]; j++) { printf("%c", 'A'+i); } } printf("\n"); #endif } return 0; }