逝者如斯,不舍昼夜

尘世中一个迷途小书童,读书太少,想得太多
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

算法篇——字母重排

Posted on 2015-08-29 15:51  SteveWang  阅读(1797)  评论(0编辑  收藏  举报

 

  来源:《算法竞赛入门经典》例题5.3.2

  题目:输入一个字典(用******结尾),然后再输入若干单词。每输入一个单词w,你都需要在字典中找出所有可以用w的字母重排后得到的单词,并按照字典序从小到大的顺序在一行中输出(  如果不存在,输出:(  )。输入单词之间用空格或空行隔开,且所有输入单词都由不超过6个小写字母组成。注意,字典中的单词不一定按字典序排列。

  样例输入
  tarp given score refund only trap work earn course pepper part
  ******
  resco nfudre aptr sett oresuc
  样例输出
  score
  refund
  part trap trap
  :(
  course

  分析

  如何判断两个单词是否可以通过重排得到呢?稍微思考就会发现:把两个单词分别按字母顺序排序,然后直接比较即可。同时,原题要求我们把符合条件的单词“按照字典序从小到大的顺序在一行中输出”,这个字典序指的是广义上的标准字典的顺序(按首字母及其后字母进行排序的得到的顺序),并不是我们输入这个字典的顺序,这里往往会引起误会,所以我们在“对单词按字母顺序进行排序”之前要“对字典按单词顺序进行排序

  源码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

char word[2000][10],sorted[2000][10];    //word用来保存字典的原始输入

int cmp_char(const void* _a,const void* _b)    //字符比较函数
{
    char* a =(char*)_a;
    char* b =(char*)_b;
    return *a - *b;
}

int cmp_string(const void* _a,const void* _b)//字符串比较函数
{
    char* a =(char*)_a;
    char* b =(char*)_b;
    return strcmp(a,b);
}

int main()
{
    int i,n=0,found=0;    //found为查找成功标志
    char w[10];           //w为用户输入字典后需要查找的单词
    while(1)              //输入字典
    {
        scanf("%s",word[n]);            //一个单词一个单词的输入
        if(word[n][0] == '*')    break; //遇到结束标志就终止循环
        n++;                            //最后一次输入******不计数
    }
    qsort(word,n,sizeof(word[0]),cmp_string);//给字典中所有单词排序(先按首字母,首字母相同按下一个字母,以此类推),即标准字典序
    for(i=0;i<n;i++)
    {
        strcpy(sorted[i],word[i]);        //把经过单词排序的字典word复制到stored
        qsort(sorted[i],strlen(sorted[i]),sizeof(char),cmp_char);//把sorted中每个单词按字母顺序重排
    }
    while(scanf("%s",w)==1)        //持续读取到文件结尾
    {
        qsort(w,strlen(w),sizeof(char),cmp_char);//把输入的单词s也按字母顺序重排
        for(i=0;i<n;i++)              //循环比较重排后的输入和重排后的字典
            if(strcmp(sorted[i],w)==0)//找到
            {
                found=1;
                printf("%s ",word[i]);//输出原始字典中对应的单词(顺序是标准字典序,即sorted中的顺序,单词是原始字典中的单词,而不是排序后的)
            }
        if(!found)    printf(":(");
        printf("\n");
    }

    return 0;
}