Anagram checker
Source : UVA - V1 Time limit : 1 sec Memory limit : 32 M
Submitted : 18, Accepted : 9
It is often fun to see if rearranging the letters of a name gives an amusing anagram. For example, the letters of `WILLIAM SHAKESPEARE' rearrange to form `SPEAK REALISM AWHILE'.
Write a program that will read in a dictionary and a list of phrases and determine which words from the dictionary, if any, form anagrams of the given phrases. Your program must find all sets of words in the dictionary which can be formed from the letters in each phrase. Do not include the set consisting of the original words. If no anagram is present, do not write anything, not even a blank line.
Source : UVA - V1 | |||
Time limit : 1 sec | Memory limit : 32 M |
Submitted : 18, Accepted : 9
It is often fun to see if rearranging the letters of a name gives an amusing anagram. For example, the letters of `WILLIAM SHAKESPEARE' rearrange to form `SPEAK REALISM AWHILE'.
Write a program that will read in a dictionary and a list of phrases and determine which words from the dictionary, if any, form anagrams of the given phrases. Your program must find all sets of words in the dictionary which can be formed from the letters in each phrase. Do not include the set consisting of the original words. If no anagram is present, do not write anything, not even a blank line.
Input
Input will consist of two parts. The first part is the dictionary, the second part is the set of phrases for which you need to find anagrams. Each part of the file will be terminated by a line consisting of a single #. The dictionary will be in alphabetic order and will contain up to 2000 words, one word per line. The entire file will be in upper case, and no dictionary word or phrase will contain more than 20 letters. You cannot assume the language being used is English.
Input will consist of two parts. The first part is the dictionary, the second part is the set of phrases for which you need to find anagrams. Each part of the file will be terminated by a line consisting of a single #. The dictionary will be in alphabetic order and will contain up to 2000 words, one word per line. The entire file will be in upper case, and no dictionary word or phrase will contain more than 20 letters. You cannot assume the language being used is English.
Output
Output will consist of a series of lines. Each line will consist of the original phrase, a space, an equal sign (=), another space, and the list of words that together make up an anagram of the original phrase, separated by exactly one space. These words must appear in alphabetic sequence.
Output will consist of a series of lines. Each line will consist of the original phrase, a space, an equal sign (=), another space, and the list of words that together make up an anagram of the original phrase, separated by exactly one space. These words must appear in alphabetic sequence.
Sample input
ABC
AND
DEF
DXZ
K
KX
LJSRT
LT
PT
PTYYWQ
Y
YWJSRQ
ZD
ZZXY
#
ZZXY ABC DEF
SXZYTWQP KLJ YRTD
ZZXY YWJSRQ PTYYWQ ZZXY
#
ABC AND DEF DXZ K KX LJSRT LT PT PTYYWQ Y YWJSRQ ZD ZZXY # ZZXY ABC DEF SXZYTWQP KLJ YRTD ZZXY YWJSRQ PTYYWQ ZZXY #
Sample output
SXZYTWQP KLJ YRTD = DXZ K LJSRT PTYYWQ
SXZYTWQP KLJ YRTD = DXZ K LT PT Y YWJSRQ
SXZYTWQP KLJ YRTD = KX LJSRT PTYYWQ ZD
SXZYTWQP KLJ YRTD = KX LT PT Y YWJSRQ ZD
SXZYTWQP KLJ YRTD = DXZ K LJSRT PTYYWQ SXZYTWQP KLJ YRTD = DXZ K LT PT Y YWJSRQ SXZYTWQP KLJ YRTD = KX LJSRT PTYYWQ ZD SXZYTWQP KLJ YRTD = KX LT PT Y YWJSRQ ZD
#include<algorithm>
#include<iostream>
#include<cstring>
#include<string.h>
#include<string>
#include<vector>
#include<cassert>
using namespace std;
#define eps 1e-8
#define LL long long
int cnt[30] , n;
char dict[2010][30] , in[1000] , sort_in[1000] ;
int cost[2010][30];
int ans[2010] , top;
bool vis[2010];
int cmp(const void * s1 , const void * s2)
{
return strcmp((char*)s1,(char*)s2);
}
void sort_input()
{
char buffer[2010][200];
char in_tmp[1000];
strcpy(in_tmp,in);
char * p = strtok(in_tmp," ");
int sz = 0;
while (p)
{
strcpy(buffer[sz],p);
++sz;
p = strtok(NULL," ");
}
qsort(buffer,sz,sizeof(buffer[0]),cmp);
sort_in[0] = 0;
for (int i = 0 ; i < sz ; ++i)
{
strcat(sort_in," ");
strcat(sort_in,buffer[i]);
}
}
void init()
{
memset(cost,0,sizeof(cost));
top = 0;
}
void input()
{
while (scanf("%s",dict[n]))
{
if (dict[n][0]=='#')
{
gets(dict[n]);
break;
}
for (int i = 0 ; i < strlen(dict[n]) ; ++i)
++cost[n][dict[n][i]-'A'];
++n;
}
}
bool canput(int j)
{
for (int i = 0 ; i < 26 ; ++i) if (cnt[i] < cost[j][i])
return false;
return true;
}
void dfs(int rest,int cur)
{
if (rest==0)
{
char buffer[1000];
buffer[0] = 0;
for (int i = 0 ; i < top ; ++i)
{
strcat(buffer," ");
strcat(buffer,dict[ans[i]]);
}
sort_input();
if (strcmp(sort_in,buffer))
printf("%s =%s\n",in,buffer);
return;
}
for (int i = cur ; i < n ; ++i) if (!vis[i] && canput(i))
{
for (int j = 0 ; j < 26 ; ++j)
{
cnt[j] -= cost[i][j];
rest -= cost[i][j];
}
ans[top++] = i;
vis[i] = true;
dfs(rest,i+1);
vis[i] = false;
--top;
for (int j = 0 ; j < 26 ; ++j)
{
cnt[j] += cost[i][j];
rest += cost[i][j];
}
}
}
void solve()
{
while (gets(in))
{
if (in[0]=='#') return;
memset(cnt,0,sizeof(cnt));
memset(vis,0,sizeof(vis));
int sum = 0;
for (int i = 0 ; i < strlen(in) ; ++i) if (isalpha(in[i]))
++cnt[in[i]-'A'] , ++sum;
dfs(sum,0);
}
}
int main()
{
n = 0;
while (scanf("%s",dict[n])==1)
{
init();
for (int i = 0 ; i < strlen(dict[n]) ; ++i)
++cost[n][dict[n][i]-'A'];
++n;
input();
solve();
n = 0;
}
}