#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAXWORD 40
#define ALPHABET 26
#define N 50000
struct anagramword
{
char word[MAXWORD];
unsigned short histo[ALPHABET];
};
// prototype
void pp(struct anagramword *, int );
void func3(struct anagramword *, int, int);
int cmp(unsigned short *, unsigned short *, int );
void pp(struct anagramword *a, int n)
{
int i;
while (n--)
{
for ( i = 0; i < ALPHABET; ++i)
printf(" word = %s\n", a
->word
); ++a;
}
}
void func3(struct anagramword *a, int from, int to)
{
int i;
if (from == to)return;
printf("The word \"%s\" %d anagrams : ", a
[from
].
word, to
- from
); for ( i = from + 1; i <= to; ++i)
{
}
}
int cmp(unsigned short *a, unsigned short *b, int n)
{
// int i;
// for ( i = 0; i < ALPHABET; ++i)
// printf("%d%d ", a[i], b[i]);
// putchar('\n');
while (n--)
{
// printf("a b = %d %d\n", *a,*b);
if (*a < *b)
return -1;
if (*a > *b)
return 1;
++a;
++b;
}
return 0;
}
int main(int argc, char const *argv[])
{
char buf[100],c;
struct anagramword *data;
struct anagramword tmp;
FILE *fp;
int i, j, k, dataCount;
data
= (struct anagramword
*)malloc(sizeof(struct anagramword
) * N
);
// 1. argv[1]を使い、Textファイルから単語を読み込む
// http://s...content-available-to-author-only...s.jp/~c_cpp_homework/cgi-bin/joyful/joyful.cgi?
// にテキストファイル2つアップしました。本来は一つのファイルですが、容量制限の為、分割してます。
// ヒストグラム(histo)をクリア
for ( i = 0; i < N; ++i)
for ( j = 0; j < ALPHABET; ++j)
data[i].histo[j] = 0;
fp
= fopen(argv
[1], "r"); i = 0;
while ((fgets(buf
, 100, fp
)) != NULL
) {
// printf("%d %s\n", i, buf);
// 2. 挿入ソートを使って、下記のような構造体に保管する
// struct anagramword {
// char word[MAXWORD];
// unsigned short histo[ALPHABET];
// };
for ( j = 0; buf[j]; ++j)
{
if ((c >= 'a') && (c <= 'z'))
data[i].histo[c - 'a']++;
}
for ( j = 0; j < i; ++j)
if (cmp(data[j].histo, data[i].histo, ALPHABET) == 1)break;
if (j < i) /* swap & shift */
{
tmp = data[i];
for ( k = i; k > j; --k)
data[k] = data[k - 1];
data[j] = tmp;
}
++i;
}
dataCount = i;
// printf("dataCount = %d\n", dataCount);
// 3. データをもとにアナグラムとその数を記したリストをtxtに出力
// 例)
// The word "ATM" 4 anagrams : ATM’s mast mat’s mats
// The word "evkl" 4 anagrams : evil, live, veil, vile
// …
// pp(data, dataCount);
int max = 0, maxi;
{
int from = 0;
for ( i = 0; i < dataCount - 1; ++i)
{
if (cmp(data[i].histo, data[i + 1].histo, ALPHABET) == 0)
{
continue;
}
func3(data, from, i);
if (max < i - from)
{
max = i - from;
maxi = from;
}
from = i + 1;
}
func3(data, from, i);
if (max < i - from)
{
max = i - from;
maxi = from;
}
}
// 4.最大値を持ったアナグラムとその最大値を出力
printf("最大値を持ったアナグラム = %s, 最大値 = %d\n" , data
[ maxi
].
word , max
);
return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8Y3R5cGUuaD4KCiNkZWZpbmUgTUFYV09SRCA0MAojZGVmaW5lIEFMUEhBQkVUIDI2CiNkZWZpbmUgTiA1MDAwMAoKc3RydWN0IGFuYWdyYW13b3JkCnsKICAgIGNoYXIgd29yZFtNQVhXT1JEXTsKICAgIHVuc2lnbmVkIHNob3J0IGhpc3RvW0FMUEhBQkVUXTsKfTsKCi8vIHByb3RvdHlwZQp2b2lkIHBwKHN0cnVjdCBhbmFncmFtd29yZCAqLCBpbnQgKTsKdm9pZCBmdW5jMyhzdHJ1Y3QgYW5hZ3JhbXdvcmQgKiwgaW50LCBpbnQpOwppbnQgY21wKHVuc2lnbmVkIHNob3J0ICosIHVuc2lnbmVkIHNob3J0ICosIGludCApOwoKCnZvaWQgcHAoc3RydWN0IGFuYWdyYW13b3JkICphLCBpbnQgbikKewogICAgaW50IGk7CiAgICB3aGlsZSAobi0tKQogICAgewogICAgICAgIGZvciAoIGkgPSAwOyBpIDwgQUxQSEFCRVQ7ICsraSkKICAgICAgICAgICAgcHJpbnRmKCIlZCIsIGEtPmhpc3RvW2ldKTsKICAgICAgICBwcmludGYoIiAgd29yZCA9ICVzXG4iLCBhLT53b3JkKTsKICAgICAgICArK2E7CiAgICB9Cn0KCnZvaWQgZnVuYzMoc3RydWN0IGFuYWdyYW13b3JkICphLCBpbnQgZnJvbSwgaW50IHRvKQp7CiAgICBpbnQgaTsKICAgIGlmIChmcm9tID09IHRvKXJldHVybjsKICAgIHByaW50ZigiVGhlIHdvcmQgXCIlc1wiICVkIGFuYWdyYW1zIDogIiwgYVtmcm9tXS53b3JkLCB0byAtIGZyb20pOwogICAgZm9yICggaSA9IGZyb20gKyAxOyBpIDw9IHRvOyArK2kpCiAgICB7CiAgICAgICAgcHJpbnRmKCIlcywgIiwgYVtpXS53b3JkKTsKICAgIH0KICAgIHB1dGNoYXIoJ1xuJyk7Cn0KCmludCBjbXAodW5zaWduZWQgc2hvcnQgKmEsIHVuc2lnbmVkIHNob3J0ICpiLCBpbnQgbikKewoKICAgIC8vIGludCBpOwogICAgLy8gZm9yICggaSA9IDA7IGkgPCBBTFBIQUJFVDsgKytpKQogICAgLy8gICBwcmludGYoIiVkJWQgIiwgYVtpXSwgYltpXSk7CiAgICAvLyBwdXRjaGFyKCdcbicpOwoKICAgIHdoaWxlIChuLS0pCiAgICB7CiAgICAgICAgLy8gcHJpbnRmKCJhIGIgPSAlZCAlZFxuIiwgKmEsKmIpOwogICAgICAgIGlmICgqYSA8ICpiKQogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgaWYgKCphID4gKmIpCiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICsrYTsKICAgICAgICArK2I7CiAgICB9CiAgICByZXR1cm4gMDsKfQoKaW50IG1haW4oaW50IGFyZ2MsIGNoYXIgY29uc3QgKmFyZ3ZbXSkKewogICAgY2hhciBidWZbMTAwXSxjOwogICAgc3RydWN0ICAgYW5hZ3JhbXdvcmQgKmRhdGE7CiAgICBzdHJ1Y3QgICBhbmFncmFtd29yZCB0bXA7CiAgICBGSUxFICpmcDsKICAgIGludCBpLCBqLCBrLCBkYXRhQ291bnQ7CgogICAgZGF0YSA9IChzdHJ1Y3QgYW5hZ3JhbXdvcmQgKiltYWxsb2Moc2l6ZW9mKHN0cnVjdCBhbmFncmFtd29yZCkgKiBOKTsKCiAgICAvLyAxLiBhcmd2WzFd44KS5L2/44GE44CBVGV4dOODleOCoeOCpOODq+OBi+OCieWNmOiqnuOCkuiqreOBv+i+vOOCgAogICAgLy8gaHR0cDovL3MuLi5jb250ZW50LWF2YWlsYWJsZS10by1hdXRob3Itb25seS4uLnMuanAvfmNfY3BwX2hvbWV3b3JrL2NnaS1iaW4vam95ZnVsL2pveWZ1bC5jZ2k/CiAgICAvLyDjgavjg4bjgq3jgrnjg4jjg5XjgqHjgqTjg6sy44Gk44Ki44OD44OX44GX44G+44GX44Gf44CC5pys5p2l44Gv5LiA44Gk44Gu44OV44Kh44Kk44Or44Gn44GZ44GM44CB5a656YeP5Yi26ZmQ44Gu54K644CB5YiG5Ymy44GX44Gm44G+44GZ44CCCgogICAgLy8g44OS44K544OI44Kw44Op44OgKGhpc3RvKeOCkuOCr+ODquOCogogICAgZm9yICggaSA9IDA7IGkgPCBOOyArK2kpCiAgICAgICAgZm9yICggaiA9IDA7IGogPCBBTFBIQUJFVDsgKytqKQogICAgICAgICAgICBkYXRhW2ldLmhpc3RvW2pdID0gMDsKCiAgICBmcCA9IGZvcGVuKGFyZ3ZbMV0sICJyIik7CiAgICBpID0gMDsKICAgIHdoaWxlICgoZmdldHMoYnVmLCAxMDAsIGZwKSkgIT0gTlVMTCkKICAgIHsKICAgICAgICBidWZbc3RybGVuKGJ1ZikgLSAxXSA9ICdcMCc7CgogICAgICAgIC8vIHByaW50ZigiJWQgJXNcbiIsIGksIGJ1Zik7CgogICAgICAgIC8vIDIuIOaMv+WFpeOCveODvOODiOOCkuS9v+OBo+OBpuOAgeS4i+iomOOBruOCiOOBhuOBquani+mAoOS9k+OBq+S/neeuoeOBmeOCiwogICAgICAgIC8vIHN0cnVjdCBhbmFncmFtd29yZCB7CiAgICAgICAgLy8gY2hhciB3b3JkW01BWFdPUkRdOwogICAgICAgIC8vIHVuc2lnbmVkIHNob3J0IGhpc3RvW0FMUEhBQkVUXTsKICAgICAgICAvLyB9OwoKICAgICAgICBzcHJpbnRmKGRhdGFbaV0ud29yZCwgIiVzIiwgYnVmKTsKCiAgICAgICAgZm9yICggaiA9IDA7IGJ1ZltqXTsgKytqKQogICAgICAgIHsKICAgICAgICAgICAgYyA9IHRvbG93ZXIoYnVmW2pdKTsKICAgICAgICAgICAgaWYgKChjID49ICdhJykgJiYgKGMgPD0gJ3onKSkKICAgICAgICAgICAgICAgIGRhdGFbaV0uaGlzdG9bYyAtICdhJ10rKzsKICAgICAgICB9CgogICAgICAgIGZvciAoIGogPSAwOyBqIDwgaTsgKytqKQogICAgICAgICAgICBpZiAoY21wKGRhdGFbal0uaGlzdG8sIGRhdGFbaV0uaGlzdG8sIEFMUEhBQkVUKSA9PSAxKWJyZWFrOwoKICAgICAgICBpZiAoaiA8IGkpICAgLyogc3dhcCAmIHNoaWZ0ICovCiAgICAgICAgewogICAgICAgICAgICB0bXAgPSBkYXRhW2ldOwogICAgICAgICAgICBmb3IgKCBrID0gaTsgayA+IGo7IC0taykKICAgICAgICAgICAgICAgIGRhdGFba10gPSBkYXRhW2sgLSAxXTsKICAgICAgICAgICAgZGF0YVtqXSA9IHRtcDsKICAgICAgICB9CiAgICAgICAgKytpOwogICAgfQogICAgZGF0YUNvdW50ID0gaTsKICAgIC8vIHByaW50ZigiZGF0YUNvdW50ID0gJWRcbiIsIGRhdGFDb3VudCk7CgogICAgLy8gMy4g44OH44O844K/44KS44KC44Go44Gr44Ki44OK44Kw44Op44Og44Go44Gd44Gu5pWw44KS6KiY44GX44Gf44Oq44K544OI44KSdHh044Gr5Ye65YqbCiAgICAvLyDkvospCiAgICAvLyBUaGUgd29yZCAiQVRNIiA0IGFuYWdyYW1zIDogQVRN4oCZcyBtYXN0IG1hdOKAmXMgbWF0cwogICAgLy8gVGhlIHdvcmQgImV2a2wiIDQgYW5hZ3JhbXMgOiBldmlsLCBsaXZlLCB2ZWlsLCB2aWxlCiAgICAvLyDigKYKCiAgICAvLyBwcChkYXRhLCBkYXRhQ291bnQpOwoKICAgIGludCBtYXggPSAwLCBtYXhpOwogICAgewogICAgICAgIGludCAgICBmcm9tID0gMDsKICAgICAgICBmb3IgKCBpID0gMDsgaSA8IGRhdGFDb3VudCAtIDE7ICsraSkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChjbXAoZGF0YVtpXS5oaXN0bywgZGF0YVtpICsgMV0uaGlzdG8sIEFMUEhBQkVUKSA9PSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBmdW5jMyhkYXRhLCBmcm9tLCBpKTsKICAgICAgICAgICAgaWYgKG1heCA8IGkgLSBmcm9tKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBtYXggPSBpIC0gZnJvbTsKICAgICAgICAgICAgICAgIG1heGkgPSBmcm9tOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZyb20gPSBpICsgMTsKICAgICAgICB9CiAgICAgICAgZnVuYzMoZGF0YSwgZnJvbSwgaSk7CiAgICAgICAgaWYgKG1heCA8IGkgLSBmcm9tKQogICAgICAgIHsKICAgICAgICAgICAgbWF4ID0gaSAtIGZyb207CiAgICAgICAgICAgIG1heGkgPSBmcm9tOwogICAgICAgIH0KICAgIH0KCiAgICAvLyA0LuacgOWkp+WApOOCkuaMgeOBo+OBn+OCouODiuOCsOODqeODoOOBqOOBneOBruacgOWkp+WApOOCkuWHuuWKmwogICAgcHJpbnRmKCLmnIDlpKflgKTjgpLmjIHjgaPjgZ/jgqLjg4rjgrDjg6njg6AgPSAlcywg5pyA5aSn5YCkID0gJWRcbiIgLCBkYXRhWyBtYXhpXS53b3JkICAgLCBtYXgpOwoKICAgIHJldHVybiAwOwp9Cg==