您的位置:首页 > 其它

变位词问题

2015-10-16 17:54 197 查看
问题C
    给定一个英语词典,找出其中的所有变位词的集合。例如,“pots”、“stop”和“tops”互为变位词,因为每一个单词都可以通过改变其他单词中的字母的顺序来得到。
解答:
    最容易想到解决方法就是:对于每一个单词,找出其的所有排列,然后对词典进行遍历,如果其排序在词典中,那么此排序序列就是该词典中此单词的变位词。
    但是这种方法对于单词长度不是很长,且词典不是很大的时候,效率比较好;但是当单词变的很长,求其各个排列的时间、以及进行检索的时间将会很长,这种情况下,该方法不可取。

    那么,有没有一种比较效率比较高的方法呢?
    《编程珠玑》中给出一种效率比较高的方法,具体思路如下所示。
    (1)为每个单词生成一个标签,即对每个单词按字母序进行排序,这样使所有的变位词会有相同的标签;
    (2)根据标签对单词进行汇合,每个标签对应一个集合,这个集合包括其所有的变位词;
    每个单词的标签的生成:如上面所叙述的那样,把这个单词所包含的字母,按照字母序进行排序。这就可以使所有的变位词的标签就全相等了。

    下面是我实现这个程序的详细过程,记录下来,以进行交流和学习。
    (1)词典的获取
    为了获取词典,从网上随意的下载了一篇英语文章,然后进行相应的处理,从而获取了词典。
    在对文章进行处理的过程中,这里去除了标点符号等简单字符,同时也进行了去除重复。
    从网上获取的文章如下所示。
    


    
    (2)获取“标签 单词”
     通过对获取的文章进行处理,去除掉标点符号等以及去除重复过,然后对各个单词进行排序,进而获取了相应单词的“标签”,我们把标签和单词以“标签  单词”的格式保存到文件中。
    保存内容如下所示。

    


    (3)获取变位词集合
    获取变位词集合的方法同《编程珠玑》上讲述的类似,获取的内容如下所示。  

    


    
    完成的程序代码如下所示。

/*

 *        Author:梦醒潇湘

 *         Date :2013/6/9/19:55

 *        Place :Hit

 *        Email :9974771**@qq.com

 */

#include <iostream>

#include <set>

#include <stdio.h>

#include <sys/stat.h>

#include <fstream>

#include <map>

using namespace std;

#define SOURCEFILE "big.txt" //原文件,就是小说的一部分,为了抽取单词

#define DESTFILE "dict.txt"     //形成的词典
标签 单词

#define RESULTFILE "result.txt" //结果文件

#define MAXNUM 100             //单词的最大长度

#define DEBUG

set<string> dict;                 //保存处理好的字典

//需要删除的字符

const char delim[] = ".,:;`'/"+-_(){}[]<>*&^%$#@!?~/|=1234567890
tn";

/*

 * 函数功能:将字符串中的字符串全部转化为小写

 * 返回值 :转换后的字符串指针

 * 参数 :

 *    @prama *word 指向源字符串的指针

 */

static char *strtolower(char *word)

{

    char *s;

    if(word == NULL)

    {

        return NULL;

    }

    for(s = word; *s != ''; s++)

    {

        *s = tolower(*s);

    }

    return word;

}

/*

 * 函数功能:读取文件中的关键字

 * 返回值 :转化成功返回1;反之,返回0

 * 参数 :

 * @prama 无

 */

static int read_file()

{

    char *file, *word, *w;

    FILE *fp = fopen(SOURCEFILE, "r");

    struct stat sb;

    if(!fp)

    {

        return 0;

    }

    if(stat(SOURCEFILE, &sb))

    {

        return 0;

    }

    

    file = (char *)malloc(sb.st_size);

    if(!file)

    {

        fclose(fp);

        return 0;

    }

    fread(file, sizeof(char), sb.st_size, fp);

    word = strtok(file, delim);

    while(word != NULL)

    {

        w = strtolower(strdup(word));

        string str = w;

        dict.insert(str);

        

        word = strtok(NULL, delim);

    }

    free(file);

    fclose(fp);

    return 1;

}

/*

 * 函数功能:用于qsort()函数

 */

int comp(const void *a, const void *b)

{

    return *(char *)a - *(char *)b;

}

/*

 * 函数功能:将字典中的单词保存到文件中, 并且把标签给求解出来

 * 返回值 :保存成功,返1;反之,则返回0

 * 参数 :

 *     @prama 无

 *        

 *        保存格式:标签 单词

 *                 标签 单词

 *                 .... ....

 */

int SaveToFile()

{

    FILE *out;

    out = fopen(DESTFILE, "w");

    if(out == NULL)

    {

        cout << "fopen() error in SaveToFile()."
<< endl;

        return 0;

    }

    set::iterator iter = dict.begin();

    for( ; iter != dict.end(); iter++)

    {

        char tmpone[MAXNUM] = {''};

        char tmptwo[MAXNUM] = {''};

        strncpy(tmpone, (*iter).c_str(), MAXNUM);

        strncpy(tmptwo, (*iter).c_str(), MAXNUM);

                

        qsort(tmpone, strlen(tmpone), sizeof(char), comp);

        

        #ifdef DEBUG        

            cout << tmpone << " "<< *iter << endl;

        #endif

        fprintf(out, "%s %sn",
tmpone, tmptwo);

    }

    fclose(out);

    

    cout << "字典保存到文件成功."
<< endl;

    return 1;

}

/*

 * 函数功能:读取保存好的字典文件,进行压缩,获取最终的结果

 * 返回值 :读取成功,返回1;反之,返回0

 * 参数 :

 *     @prama 无

 */

int squasd()

{

    /*

    ifstream infile(DESTFILE, ios::in);

    ofstream outfile("Result.txt",ios::out);

    //assert(infile);

    //assert(outfile);

    if(infile == NULL || outfile == NULL)

    {

        return 0;

    }

    

    string sig, word;

    string sigone, wordone;

    infile >> sig >> word;

    outfile << sig << " " << word;

    while(infile >> sigone >> wordone)

    {

        if(strcmp(sigone.c_str(), sig.c_str()) == 0)

        {

            if(strcmp(wordone.c_str(), word.c_str()) == 0)

            {

                //the same word

                continue;

            }

            else

            {

                outfile << " " << wordone;

            }    

        }

        else

        {

            outfile << endl;

            outfile << sigone << " " << wordone;

            sig = sigone;

            word = wordone;

        }

    }

    infile.close();

    outfile.close();

    cout << "处理完毕."
<< endl;

    return 1;

    */

    //打开dict.txt文件

    ifstream infile(DESTFILE, ios::in);

    if(infile == NULL)

    {

        return 0;

    }

    

    //读取文件内容,保存到multimap中

    multimap res;

    string sig, word;

    while(infile >> sig >> word)

    {

        res.insert(make_pair(sig, word));

    }

    //打开保存最终结果的文件

    ofstream outfile(RESULTFILE, ios::out);

    if(outfile == NULL)

    {

        return 0;

    }

    

    //进行处理

    multimap::iterator iter = res.begin();

    if(iter == res.end())

    {        

        return 0;

    }

    outfile << iter->first << " " << iter->second;

    iter++;

    

    sig = iter->first;

    word = iter->second;

    for( ; iter != res.end(); iter++)

    {

        char tmpone[MAXNUM] = {''};

        char tmptwo[MAXNUM] = {''};

        

        strncpy(tmpone, (iter->first).c_str(), MAXNUM);

        strncpy(tmptwo, (iter->second).c_str(), MAXNUM);

    

        if(strcmp(sig.c_str(), tmpone) == 0)

        {

            if(strcmp(word.c_str(), tmptwo) == 0)

            {

                //same word here

                continue;

            }

            else

            {

                outfile << " " << tmptwo;

            }

        }

        else

        {

            outfile << endl;

            outfile << tmpone << " " << tmptwo;

            sig = tmpone;

            word = tmptwo;

        }

    }

    infile.close();

    outfile.close();

}

int main()

{

    //读取文件,创建词典

    if(!read_file())

    {

        return EXIT_FAILURE;

    }

    //保存字典到文件中

    if(!SaveToFile())

    {

        return EXIT_FAILURE;

    }

    //进行最后结果的出来

    if(!squasd())

    {

        return EXIT_FAILURE:

    }

    return EXIT_SUCCESS;

}

//上面的代码在粘贴的时候可能会有错误,附件为文件。

链接:http://blog.chinaunix.net/uid-26548237-id-3761073.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: