问题描述
给定一本英语单词词典,请找出所有的变位词集。例如,因为“pots”、“stop”、“tops”相互之间都是由另一个词的各个字母改变序列而构成的,因此这些词相互之间就是变位词。
解决思路
将该程序组织成三段式的“管道”结构,其中一个程序的输出文件将是下一个程序的输入文件。第一个程序对单词进行签名,第二个程序对已签名的文件进行排序,而第三个程序则将同一个变位词类中的各个单词挤压到同一行中。下面是在具有六个单词的词典中进行处理时的情形。
签名程序(sign)
#include
#include
#include
#define WORD_MAX 100
int charcomp(char *x, char *y) {return *x - *y;}
int main(int argc, char **argv)
{
char word[WORD_MAX], sig[WORD_MAX];
while(scanf("%s", word) != EOF)
{
strcpy(sig, word);
qsort(sig, strlen(sig), sizeof(char), charcomp);
printf("%s %s\n", sig, word);
}
return 0;
}
-bash-3.00$ ./sign
pans //in
anps pans //out
pots //in
opst pots //out
opt //in
opt opt //out
snap //in
anps snap //out
stop //in
opst stop //out
tops //in
opst tops //out
EOF while循环一次将一个字符串读到word中,直到读到文件末尾时为止。strcpy函数将输入单词复制到单词sig中,随即调用C语言标准库中的qsort函数对里面的字符进行排序。最后printf语句依次输出签名、单词本身和换行。
排序(sort)
系统sort程序将具有相同签名的单词全部整理在一起。
-bash-3.00$ ./sign | sort
pans
pots
opt
snap
stop
tops
anps pans
anps snap
opst pots
opst stop
opst tops
opt opt
挤压(squash)
#include
#include
#include
#define WORD_MAX 100
int main(int argc, char **argv)
{
char word[WORD_MAX], sig[WORD_MAX], oldsig[WORD_MAX];
int linenum = 0;
strcpy(oldsig, "");
while(scanf("%s %s", sig, word) != EOF)
{
if(strcmp(oldsig, sig) != 0 && linenum > 0)
{
printf("\n");
}
strcpy(oldsig, sig);
linenum++;
printf("%s ", word);
}
printf("\n");
return 0;
}
-bash-3.00$ ./sign | sort | ./squash
pans
pots
opt
snap
stop
tops
pans snap
pots stop tops
opt 大部分的工作将由第二个printf语句来完成;对于每一个输入行,它都要输出第二个字段和一个空格。if 语句判断签名之间的变化:假如sig与oldsig(当前值)不同的话,随即输出换行(只要该记录不是文件中的第一条记录)。最后一个printf输出最后一个换行符。