zoukankan      html  css  js  c++  java
  • 如何找出字典中的兄弟单词

    1. 给定一个单词a,如果通过交换单词中字母的顺序可以得到另外的单词b,那么定义b是a的兄弟单词,例如单词army和mary互为兄弟单词。现在给定一个字典,用户输入一个单词,如何根据字典找出这个单词有哪些兄弟单词?要求时间和空间效率尽可能的高。【2012年百度实习生招聘笔试题】

     

    思路一:使用trie树。

    在字典树的前缀中再存储一个vector结构的容器:

    Cpp代码  收藏代码
    1. struct word  
    2. {    
    3.     vector<string> brother;    // 用于保存每个单词的兄弟单词  
    4.     word *next[26];            // 字典树中每个节点代表一个字符,并指向下一个字符  
    5. };  

    如上述数据结构所示,字典树的建立是在预处理阶段完成的,首先根据字典中的单词来建立字典树,建立的时候,需要稍微特殊处理一下,就是比如pots、stop和tops互为兄弟单词,那么在字典中按照首字母顺序的话,应该先遇到pots单词,那么我首先对其进行排序,结果是opts,那么字典树中就分别建立4个节点,分别为o->p->t->s,当然这个是不同层次的,在节点s处的vector容器brother中添加单词pots,遇到stop的时候,同样的方法,排序是opts,此时发现这4个节点已经建立了,那么只需要在第四个节点s处的vector容器brother中添加单词stop,tops单词的处理方法是同样的。

         这样建立完字典树后,查询兄弟单词的效率就会很高了,比哈希的效率还要高;查到tops的兄弟的单词的时候,首先排序,那么就是opts,然后在字典树中查找opts,在s处将其vector容器brother中的的单词输出就是tops的所有兄弟单词。

     

    思路二:使用hash_map和链表。 

    首先定义一个key,使得兄弟单词有相同的key,不是兄弟的单词有不同的key。例如,将单词按字母从小到大重新排序后作为其key,比如bad的key为abd,good的key为dgoo。 
    使用链表将所有兄弟单词串在一起,hash_map的key为单词的key,value为链表的起始地址。 
    开始时,先遍历字典,将每个单词都按照key加入到对应的链表当中。当需要找兄弟单词时,只需求取这个单词的key,然后到hash_map中找到对应的链表即可。 
    这样创建hash_map时时间复杂度为O(n),查找兄弟单词时时间复杂度是O(1)。

     

    思路三:同样使用hash_map和链表。

    将每一个字母对应一个质数,然后让对应的质数相乘,将得到的值进行hash,这样兄弟单词的值就是一样的了,并且不同单词的质数相乘积肯定不同。

    使用链表将所有兄弟单词串在一起,hash_map的key为单词的质数相乘积,value为链表的起始地址。

    对于用户输入的单词进行计算,然后查找hash,将链表遍历输出就得到所有兄弟单词。

    这样创建hash_map时时间复杂度为O(n),查找兄弟单词时时间复杂度是O(1)。

  • 相关阅读:
    atitit.nfc 身份证 银行卡 芯片卡 解决方案 attilax总结
    atitit.php 流行框架 前三甲为:Laravel、Phalcon、Symfony2 attilax 总结
    Atitit.执行cmd 命令行 php
    Atitit. 图像处理jpg图片的压缩 清理垃圾图片 java版本
    atitit。企业组织与软件工程的策略 战略 趋势 原则 attilax 大总结
    atitit. 管理哲学 大毁灭 如何防止企业的自我毁灭
    Atitit.java的浏览器插件技术 Applet japplet attilax总结
    Atitit.jquery 版本新特性attilax总结
    Atitit. 软件开发中的管理哲学一个伟大的事业必然是过程导向为主 过程导向 vs 结果导向
    (转)获取手机的IMEI号
  • 原文地址:https://www.cnblogs.com/WayneZeng/p/3388300.html
Copyright © 2011-2022 走看看