29 同位词的统计
2016-01-23 20:33
453 查看
前言
本博文部分图片, 思路来自于剑指offer 或者编程珠玑问题描述
思路
同位词 : 如果一个单词可以通过交换任意字符的位置进行重新组合 得到另外一个单词, 那么 这两个单词互为同位词思路 : 对于该问题, 我们可以发现每一组同位词有一个相同的地方, 组成他们的字符的字符大小, 字符个数 都相同, 这就是 我们的突破口, 我们可以为每一个单词定义一个label, 该label为该字符串中的所有字符进行排序之后的结果
比如 : “dfs” 的label为”dfs”, “sfd” 的label为”dfs”
然后 遍历给定输入的各个单词, 进行统计, 将label相同的单词 放入相同过的容器, 详细过程详见代码
参考代码
[code]/** * file name : Test27IsAnagram.java * created at : 9:12:40 PM Jun 11, 2015 * created by 970655147 */ package com.hx.test05; public class Test27IsAnagram { // 解析同位词 public static void main(String []args) { String path = System.getProperty("user.dir") + "\\tmp\\Test27IsAnagram.txt"; try { resolveAnagram(path); } catch (IOException e) { e.printStackTrace(); } } // 每一个同位词集合的初始容量 static int INTIAILZE_SIZE = 4; // 解析同位词, 为每一个同位词生成一个标签, 然后将条目添加到dict中 // 思路 : 解析出输入的每一个单词, 然后创建一个key为 单词以英文排序, value为该单词的条目, 然后添加到dict中 public static void resolveAnagram(String path) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(path)) ); Map<String, HashSet<String>> dict = new HashMap<String, HashSet<String>>(); try { String line = null; while((line = br.readLine()) != null) { if(line == null || line.trim().length() == 0) { continue ; } line = prepare(line); String[] words = line.split("\\s+"); for(String word : words) { putWordIntoDict(word, dict); } } } finally { if(br != null) { br.close(); } } for(Map.Entry<String, HashSet<String>> entry : dict.entrySet()) { Log.log(entry.getKey() + " -> " + entry.getValue() ); } } // 将word放入dict // 先获取word对应的label, 然后将其添加到dict中 private static void putWordIntoDict(String word, Map<String, HashSet<String>> dict) { char[] chars = word.toCharArray(); Arrays.sort(chars); String label = new String(chars); HashSet<String> tuple = dict.get(label); if(tuple == null) { tuple = new HashSet<String>(INTIAILZE_SIZE); dict.put(label, tuple); } tuple.add(word); } // 常量数据 static char COMMON = ','; static char DOT = '.'; static char QUES = '?'; static char INV_REF = '\''; static char LINK = '-'; static char SPACE = ' '; static char A = 'A', Z = 'Z'; static int CAPITAL_MASK = 1 << 5; // 预处理line, 替换",", "."等 为空格, 将大写转换为小写 private static String prepare(String line) { char[] chars = line.toCharArray(); for(int i=0; i<chars.length; i++) { if(chars[i] == COMMON || chars[i] == DOT || chars[i] == QUES) { chars[i] = SPACE; } // if(chars[i] == INV_REF) { // chars[i] = LINK; // } if(chars[i] >= A && chars[i] <= Z) { chars[i] |= CAPITAL_MASK; } } return new String(chars); } }
效果截图
总结
从这个案例中 可以看出, 对于数据的性质的分析, 对于设计算法来说是很重要的下面 我贴一下编程珠玑上面, 关于这个问题, 关于置换各个字母的方式的解析的一段图片
注 : 因为作者的水平有限,必然可能出现一些bug, 所以请大家指出!
相关文章推荐
- poj2255——Tree Recovery(应用二叉树)
- SPFA随手写,容易理解的
- 【Best Coder】Baby Ming and Weight lifting(水)
- Python使用Requests第三方库自动登陆知乎
- js基础教程学习笔记
- MongoDB基本操作(增删改查)
- 全局变量引发的链接时的LNK2005xxx already defined in yyyy.obj
- xwiki6.X版本升级日志
- leetcode--Palindrome Number
- c++中类对象分配内存大小与虚继承的一些问题
- 关于cisco网络设备访问控制列表ACL中IN、OUT的理解
- 玩诈欺的小杉【推荐】
- PAT1076 Forwards on Weibo
- eclipse环境搭建之三:Python
- 几种经典的网络服务器架构模型的分析与比较
- 关于Struts2.xml的配置
- leetcode--Unique Paths && Unique Paths ii
- hadoop-2.6.0分布式环境搭建详细过程
- ZOJ2588 Burning Bridges(割边模板)
- 【C语言】写一个函数,实现字符串内单词逆序