【编程珠玑】学习笔记[2]——变位词

来源:互联网 发布:网络信息安全概述 编辑:程序博客网 时间:2024/05/20 04:28

变位词:相同字母和字母数量,不同的组合顺序。如单词“stop”、“tops”就是变位词。

  • 个人比较喜欢的解法——采用C++关联容器map
思路:以单词的“签名”为键,以具有该键的单词为值。

实现:

#include<iostream>

#include<map>

#include<iterator>

#include<string>

#include<fstream>

#include<algorithm>

using namespace std;

map<string,string>  anagram;

//签名用到的比较函数,按升序排列

bool  cmp(const  char &x, const char &y)

{

          return x<y;

}

//对词典中的单词进行签名,生成map对象

void sign(const  string &infile)

{

         ifstream  in(infile);

         if(!in)

         {

                   cout <<"Unable to open the dictionary."<<endl;

         }

         string  word;  

         while(in >> word)

         {

                  string sig(word);

                  sort(sig.begin(), sig.end(), cmp);   //签名

                  word[sig] += word;   //添加到具有“sig”签名的单词集的值中

          }

          in.close();

}

void squash(const string &outfile)

{

          ofstream  out(outfile);

          map<string,string>::iterator  it = anagram.begin();

          while(it != anagram.end())

          {

                    out << it->second<<endl;

                    it++;

          }

          out.close();

}

int main(int argc, char **argv)

{

         string infile;

         string outfile;

         cout << "Please input the filename of dictionary: "<<endl;

         cin >>infile;

         cin.clear();

cout << "Please input the filename for storing anagram: "<<endl;

         cin >>outfile;

         cin.clear();

         sign(infile);

         squash(outfile);

return 0;

}

  • 编程珠玑上的解法——三段式“管道”结构
这里所谓的“管道”结构就是一个成程序的输出作为另一个程序的输入,应用到本例就是sign的输出作为sort的输入,sort的输出作为squash的输入。

sign -> sort -> squash(其中sort采用系统的sort程序)。

//签名

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

#define WORDMAX 100

int compare(const void *a,const void *b)
{
        return *(char *)a - *(char *)b;
}  

int main()
{
       char word[WORDMAX], sig[WORDMAX];
       while (scanf("%s", word) != EOF)
       {
               strcpy(sig, word);
               qsort(sig, strlen(sig), sizeof(char), compare);
               printf("%s %s\n", sig, word);
       }
       return 0;
}

//写入文件

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

#define WORDMAX 100

int main()
{

         char word[WORDMAX], sig[WORDMAX], oldsig[WORDMAX];
         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;
}

将生成的可执行文件放到同一个目录下,在命令行中用命令:sign <word.txt | sort | squash >anagram.txt 执行。其中,word.txt为要检测的字典, anagram.txt为排序后输出的,变位词在同一行。


附:关于sort和qsort函数

  • sort
函数原型:void sort( RandomIt first, RandomIt last, Compare comp );

其中:

first为第一个元素位置;

last为最后一个元素位置;

comp为自定义比较函数(省略时,按升序进行排序)。

如对一个字符串(string  str)进行排序:

sort(str.begin(), str.end(), comp)

bool  comp(const char &x, const char &y)

{

retrun x<y;    //升序

//return x>y;   //降序

}

  • qsort
函数原型: void _cdecl  qsort (void *base, size_t num, size_t width, int (__cdecl *comp)(const void *, const void* ))

其中:

base是待排序的一个集合

num是这个数组元素的个数;

width是一个元素的大小(占用的字节数);

comp是一个自定义的比较函数。

比如:对一个长为1000的数组int a[1000])进行排序, 那么base应为a,num应为 1000,width应为 sizeof(int),comp函数随自己的命名。即:qsort(a,1000,sizeof(int),comp);

其中comp函数可以为:

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

{

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

}

上面是由小到大排序,若改为:return *(int *)b - *(int *)a; 为由大到小排序。


0 0
原创粉丝点击