“《编程珠玑》(第2版)第2章”:C题(查找变位词,排序)
C题是这样子的:
给定一个英语字典,找出其中的所有变位词集合。例如,“pots”、“stop”和“tops”互为变位词,因为每一个单词都可以通过改变其他单词中字母的顺序来得到。
下段分析摘自该书(P16):
解决这个问题的许多方法都出奇地低效和复杂。任何一种考虑单词中所有字母的排列的方法都注定了要失败。单词“cholecystoduodenostomy”有22!种排列,少量的乘法运算表明22!约等于1.124*10^21。即使假设以闪电一样的速度百亿分之一秒执行一种排列,这也要消耗1.1*10^9秒。经验法则“pi秒就是一个纳世纪”(见7.1节)指出1.1*10^9秒是数十年。而比较所有单词对的任何方法在我的机器上运行至少要花费一整夜的时间——在我使用的字典里大约230 000个单词,而即使是一个简单的变位词比较也将至少1微秒的时间,因此,总时间估算起来就是:
230 000单词 * 230 000比较/单词 * 1微秒/比较 = 52 900*10^6微秒=52 900秒,约等于14.7小时。
对于该问题,上述的方法很明显不可采取的,那有什么更好的方法吗?
作者在书中提到了一个更为高效的算法:基于排序的标识。这种方法是对单词内的字母进行排序,从而使得同一个变位词类中的单词具有标准型。
这种方法的核心就在于,对于每一个输入的单词,我们都会对其单词内的字母进行排序,使得其具有一个标准型。如pots,排完序后就是opst。另外,stop、tops的标准型也都是opst,因此可以将这三个单词归类到标准型opst下。适宜实现这种数据结构的是map类型,即关键字“标准型”对应着一堆有相同标准型的单词。至于单词内排序,直接借助sort函数即可。
下边我个人实现的程序,与作者提供的程序不一样(主要是采用的数据结构不一样):
#include<iostream>
#include <string>
#include <algorithm>
#include <fstream>
#include <map>
#include <vector>
using namespace std; int main()
{
ifstream rfile("words.txt", ios::in);
if (!rfile)
{
cout << "The file can not be opened!" << endl;
exit();
} // core session
string line;
map<string, vector<string> > seqWords;
while (getline(rfile, line))
{
string tempStr = line;
sort(line.begin(), line.end()); map<string, vector<string> >::iterator itr = seqWords.find(line);
if (itr == seqWords.end())
{
vector<string> tmpVec;
tmpVec.push_back(tempStr);
seqWords.insert(pair<string, vector<string> >(line, tmpVec));
}
else
{
seqWords[line].push_back(tempStr);
}
} // print all the elments in seqWords
cout << "************************************************" << endl;
map<string, vector<string> >::iterator itrMap = seqWords.begin();
for (; itrMap != seqWords.end(); itrMap++)
{
cout << itrMap->first << ": " << endl;
vector<string> tempVec = itrMap->second;
vector<string>::iterator itrVec = tempVec.begin();
for (; itrVec != tempVec.end(); itrVec++)
{
cout << *itrVec << " ";
}
cout << endl << endl;
}
cout << "************************************************" << endl; return ;
}
程序输入文件words.txt为:
pans
pots
opt
snap
stop
tops
程序输出如下:

“《编程珠玑》(第2版)第2章”:C题(查找变位词,排序)的更多相关文章
- 《编程珠玑(第2版)》【PDF】下载
<编程珠玑(第2版)>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230382225 内容简介 书的内容围绕程序设计人员面对的一系列实 ...
- java编程思想第四版第十一章习题
第一题 package net.mindview.holding.test1; import java.util.ArrayList; import java.util.List; /** * 沙鼠 ...
- java编程思想第四版第六章总结
1. 代码重构 为什么f要代码重构 第一次代码不一定是完美的, 总会发现更优雅的写法. 代码重构需要考虑的问题 类库的修改不会破坏客户端程序员的代码. 源程序方便扩展和优化 2. 包 创建一个独一无二 ...
- Java编程思想第四版*第七章*个人练习
欢迎加群:239063848 成团的笔记:该组仅用于技术共享和交流,问题和答案公布 潘基聊天.禁止广告.禁止招聘-- 练习1:(2)创建一个简单的类.第二个类中,将一个引用定义为第一个类的对象.运用惰 ...
- java编程思想第四版第五章习题
创建一个类, 它包含一个未初始化的String引用.验证该引用被Java初始化成了null package net.mindview.initialization; public class Test ...
- java编程思想第四版第六章习题
(略) (略) 创建两个包:debug和debugoff,他们都包含一个相同的类,该类有一个debug()方法,第一个版本显示发送给控制台的String参数,而第二版本什么也不做,使用静态import ...
- java编程思想 第四版 第六章 个人练习
欢迎加群:239063848 进群须知:本群仅用于技术分享与交流.问题公布与解答 禁止闲聊.非诚勿扰 练习1:(1)在某个包中创建一个类,在这个类所处的包的外部创建该类的一个实例. import mi ...
- java编程思想第四版第9章
练习3: public class MainTest { public static void main(String args[]){ Bcycle b=new Bcycle(); b.print( ...
- Java编程思想第四版 *第五章 个人练习
练习3:(1)创建一个带默认构造器(即无參构造器)的类.在构造器中打印一条消息.为这个类创建一个对象.P116 public class Test{ public Test(){ System.out ...
随机推荐
- git中status指令总是提示内容被修改的解决
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 最近在用git提交项目修改时发现一个问题,就是多次 git a ...
- Eclipse打jar包,资源文件的读取
最近的工作中需要将java程序打一个jar包,然后在Linux中供调用.程序中需要读取一个配置文件.遇到了三个问题.第一个是依赖的第三方Jar包打成Jar包后找不到:第二个问题是资源文件所在的文件夹打 ...
- Struts2处理流程性需求的一种解决方案
在应用程序设计中,经常出现如下的需求. 查看用户填写的数据,而且数据是分页填写. 看下面这个情况 用户的信息有三页,分别是Form abc. 现在的问题是,后面的逻辑该如何设计. 如果把,FormAB ...
- 01 Android修改新建虚拟机存放的位置
创建的Android虚拟机(即AVD)的位置是在C盘的当前用户文件夹下(C:\Users\用户名\.android\avd) 这一默认设置不怎么好,特别是C盘空间吃紧的话. 这里提供2个解决办法(分2 ...
- Android初级教程XUtils实现“断点续传”下载
对于"断电续传",在任何开发中都显得很重要.xutils对此封装的很好了,可以很简单的实现很多下载功能,其中就包括"断点续传" 主要代码如下: package ...
- 通过邮件找回密码功能的Java实现
1.有个需求就是,忘记密码后通过邮箱找回.现在的系统在注册的时候都会强制输入邮箱,其一目的就是 通过邮件绑定找回,可以进行密码找回.通过java发送邮件的功能我就不说了,重点讲找回密码. 2.参考别人 ...
- Linux 基于IPC机制实现进程间的共享内存处理
今天学习了相关于IPC(InterProcess Communication ,进程间通信)的相关知识.就做个笔记,一来让大家检查一下我的理解方面是不是有错误,二来也为了能让更多的博友们了解到相关的知 ...
- Android进阶(三)android httpClient 支持HTTPS的访问方式
项目中Android https请求地址遇到了这个异常(无终端认证): javax.net.ssl.SSLPeerUnverifiedException: No peer certificate 是S ...
- 安装配置Kafka
1,下载kafka安装包,解压缩,tar -zxvf kafka_2.10-0.8.2.1.tgz 2,修改/etc/profile文件,增加KAFKA_HOME变量 3,进入KAFKA_HOME/c ...
- xml解析之sax解析原理图和技术介绍
SAX解析工具- Sun公司提供的.内置在jdk中.org.xml.sax.* 核心的API: SAXParser类: 用于读取和解析xml文件对象 parse(File f,DefaultHand ...