zoukankan      html  css  js  c++  java
  • Programming Pearls笔记之一

    Programming Pearls笔记之一

    Programming Pearls笔记之一

      这里是编程珠玑(Programming Pearls)第一部分(前五个专栏)的笔记.

    1 排序

    • 问题
      一个文件包含至多n个不大于n且无重复的正整数(n=10^7).要求排序之后输出.
      
    • 解答

        由于都是正整数且没有重复,可以用二进制串表示.对于二进制数组bit,如果整数i存在,则让bit[i]=1,否则bit[i]=0.例如集合{1,2,3,5,8,13}可以用二进制01110100100001000000来表示.

        下面分三步解决:

      /* phase 1: initialize set to empty */
          for i = [0, n)
              bit[i] = 0
      /* phase 2: insert present elements into the set */
          for each i in the input file    
              bit[i] = 1
      /* phase 3: write sorted output */
            for i = [0, n)
              if bit[i] == 1
                  write i on the output file
      

        由于不是基于比较的排序算法,时间复杂度为不受O(n log n)的局限,此时为O(n).对于存在重复数值的情况也可以使用这个算法,只是要用整型数组来表示,

    2 向量平移

    • 问题
      将一个长度为n的向量x左移i位.当n=8,i=3时,对于向量abcdefgh,左移之后为defghabc.
      
    • 解答

        记得在《数据结构》课上老师说过这是一个考研题目.下面给出两个时间复杂度为O(n),空间复杂度为O(1)的算法.方法一比较繁琐,方法二则比较优美.

      • 方法一

          先从x[0]开始,将x[0]保存到变量t中,将x[i]移到x[0]中,x[2*i]移到x[i]中...直到要从x[0]中取数据时,将t值取出移到相应位置.
        如果向量中还有数据没有移动,然后从X[1]开始,将x[1]保存到t中...
        直到x中所有的数据都移动过了,结束.

          对于n=12,i=3的示意图:

        http://images.cnblogs.com/cnblogs_com/Open_Source/201208/201208040813436402.png

        图一 i=3,n=12示意图

      • 方法二

          只用三步.

        reverse(0, i-1)    ⇒    /* cbadefgh */
        reverse(i, n-1)    ⇒    /* cbahgfed */
        reverse(0, n-1)    ⇒    /* defghabc */
        

    3 变位词查找

    • 问题
      给一个词典,从中查找所有的变位词(如pots,stop,tops,spot和post是变位词).
      
    • 解答

        由于变位词是由相同的字母重新排列组成的,所以可以将字母按字母序重排作为它的标识值(signature),题目中的例子的标识值即opst.然后按标识值对词典中的词进行排序,变位词由于标识值相同会相邻.这时只要比较相邻的词即可找出所有的变位词.

    4 电话簿软件

    • 问题
      上世纪70年代,贝尔实验室发明了一个电话簿软件.可以通过下图所示的标准键盘输入来查找号码.比如,对于Mike Lesk,输入"LESK*M*"(即"5375*6*")就可以找到他的号码.如何实现?
      

      http://images.cnblogs.com/cnblogs_com/Open_Source/201208/201208040813445878.png

      图二 标准电话键

    • 解答

        将名字的按键编码作为它的标识值,对于问题中的Mike Lesk,标识值为"5375*6*".然后将标识标识值作为第一关键字,名字作为第二关键字进行排序.当查找号码时利用二分查找即可.

    5 二分查找

    • 问题
      从有序列表中查找一个数值t.当t有多个时,返回第一个.   
      
    • 解答

        这个问题比较简单,可以先利用常规的二分查找找到其中的一个t,然后再向前查找第一个,但有个更简洁的方法.

      l = -1; u = n
        while l+1 !=u
            /* invariant: x[l] < t && x[u] >=t && l < u */
            m = (l + u) / 2
            if x[m] < t
                l = m
            else
                u = m
        /* assert l+1 =u && x[l] < t && x[u] >=t */
        p = u
        if p >=n || x[p] != t
            p = -1
      

        由于始终保持x[l]<t且x[u]>=t,又跳出循环时有l+1=u,故当x[u]=t时,一定是是第一个.

    6 程序终止性

    • 问题
      证明当x是正整数时下面的这个程序定能终止.
              
        while x != 1 do                       
            if even(x)
                x = x/2
            else
                x = 3*x+1
      
    • 解答

        这是一个数学难题,目前无解.

    Date: 2012-07-25 三

    Author: Hu Wenbiao

    Org version 7.8.11 with Emacs version 24

    Validate XHTML 1.0
  • 相关阅读:
    [转]Asp.Net MVC EF各版本区别
    web攻击之七:常见CDN回源问题总结
    web攻击之六:DNS攻击原理与防范
    web攻击之四:DOS攻击
    web攻击之五:上传漏洞
    web攻击之三:SQL注入攻击的种类和防范手段
    web攻击之二:CSRF跨站域请求伪造
    TCP洪水攻击(SYN Flood)的诊断和处理
    DDoS攻防战(三):ip黑白名单防火墙frdev的原理与实现
    DDoS攻防战(二):CC攻击工具实现与防御理论--删除
  • 原文地址:https://www.cnblogs.com/Open_Source/p/2622533.html
Copyright © 2011-2022 走看看