where the amazing happens

          全排列和其他

          昨天上午去面試的一道題,當(dāng)場(chǎng)沒想出來,回來花了點(diǎn)時(shí)間補(bǔ)完了下發(fā)回去.

          原題要求用java,用python只是為了方便。用回溯法快,但是還是堅(jiān)持用遍歷森林來寫,這也是面試時(shí)沒想完的思路,呵呵,我就是自找麻煩的硬石頭性格。

          最先想到用無向連通圖進(jìn)行深度優(yōu)先搜索,但是沒有考慮到結(jié)束條件。對(duì)于N個(gè)待排列的數(shù)字,每個(gè)節(jié)點(diǎn)都有N-1個(gè)出口和入口,而用樹狀結(jié)構(gòu)每個(gè)節(jié)點(diǎn)只有一個(gè)父節(jié)點(diǎn),存在遞歸返回的條件。但是這個(gè)方法的實(shí)用性只限制在當(dāng)排列數(shù)很少(N < 8)時(shí)。當(dāng)N>8時(shí)算法消耗的時(shí)間明顯增加(一共8*7*6*5*4*3*2*1=40320種組合),當(dāng)N>1000時(shí)(當(dāng)然,這種情況是不敢想像的)就會(huì)達(dá)到python的遞歸極限。所以真正如果要干點(diǎn)什么的話(當(dāng)然,高中生都知道全排列拿52張撲克牌出來排一下結(jié)果集就是個(gè)天文數(shù)字),這顯然不是個(gè)好算法。


          #coding=utf-8

          # 數(shù)字全排列
          #
          Chris Zheng 2007-06-05

          import sys, os


          #待排列的數(shù)字
          NUMS = [1,2,3,4,5,6]

          #結(jié)果集合
          results = []

          EXCLUDES
          = (
          lambda a,b,nums:abs(nums.index(a) - nums.index(b)) == 1, #a,b是否相鄰
          lambda a,b,idx_a,idx_b,nums:nums.index(a) == idx_a and nums.index(b) \
          == idx_b #a,b是否同時(shí)符合特定位置
          )

          # 3和4不能相鄰 當(dāng)2在第1時(shí)6不能在第7
          EXT_PARAMS = (
          (
          3,4,NUMS),(2,6,1,7,NUMS)
          )

          #檢查排除條件
          def __check_conditions(nums):
          matchs
          = False
          for f in EXCLUDES:
          for params in EXT_PARAMS:
          try:
          params[
          -1] = nums
          matchs
          = f(*params)
          if matchs: return matchs
          except Exception:continue
          return matchs

          #樹節(jié)點(diǎn)
          class node(object):
          def __init__(self, n):
          self.value
          = n
          self.parent
          = None
          self.children
          = []
          def __eq__(self,other):
          return self.value == other.value
          def __str__(self):return str(self.value)

          #主方法
          def get_all(nums):
          trees
          = []
          for n in nums:
          trees.append(create_tree(node(n)))
          for t in trees:
          walk_tree(t)
          global results
          #過濾條件
          return (r for r in results if not __check_conditions(r))

          #生成結(jié)果樹
          def create_tree(root):
          parent_elements
          = __parents(root)
          if len(parent_elements) == len(NUMS)+1:return root
          nums
          = (nums for nums in NUMS if node(nums) not in parent_elements)
          for k in nums:
          c
          = node(k)
          c.parent
          = root
          root.children.append(create_tree(c))
          return root

          def __parents(node):
          parent_elements
          = [node]
          while node.parent:
          parent_elements.append(node.parent)
          node
          = node.parent
          return parent_elements

          #遍歷結(jié)果樹
          def walk_tree(root):
          if root.children:
          for n in root.children:
          walk_tree(n)
          else:
          k
          = [root.value]
          p
          = root.parent
          while p:
          k.append(p.value)
          p
          = p.parent
          k.reverse()
          results.append(k)

          #測(cè)試輸出
          if __name__=='__main__':
          rs
          = get_all(NUMS)
          f
          = open('results.txt','w')
          for k in rs:
          f.write(str(k)
          +'\n')
          f.close()


          .


          posted on 2007-06-05 14:47 where the amazing happens 閱讀(433) 評(píng)論(0)  編輯  收藏 所屬分類: 算法&數(shù)據(jù)結(jié)構(gòu)


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           

          公告

          點(diǎn)擊這里給我發(fā)消息

          導(dǎo)航

          <2007年6月>
          272829303112
          3456789
          10111213141516
          17181920212223
          24252627282930
          1234567

          統(tǒng)計(jì)

          常用鏈接

          留言簿(3)

          隨筆分類(18)

          隨筆檔案(17)

          文章分類

          相冊(cè)

          其他我的blog

          技術(shù)Blog

          最新隨筆

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 来凤县| 高密市| 那曲县| 宁阳县| 仪征市| 手机| 遂平县| 清河县| 新乡县| 喀喇| 宁夏| 富蕴县| 开原市| 公安县| 咸丰县| 苍南县| 新丰县| 修文县| 潼关县| 贵德县| 河曲县| 甘孜| 刚察县| 金昌市| 镇原县| 梅州市| 双辽市| 西吉县| 将乐县| 高邮市| 潼南县| 泰州市| 盐津县| 松江区| 独山县| 濉溪县| 万宁市| 米脂县| 兰州市| 临泽县| 磴口县|