Project1

标题: 数组的一个排列算法问题,小鱼纠结了^求助 [打印本页]

作者: 幻の飞鱼    时间: 2008-3-30 01:21
标题: 数组的一个排列算法问题,小鱼纠结了^求助
现有一个数组p,由多个不确定SIZE的数组组成,P的SIZE也不确定

比如
p = [[0],[1],[2,3]]
希望通过一个算法,得到新的数组

x = [[0,1,2],[0,1,3]]
意思就是把,SIZE是2以上的数组拆开,和其他单个数组组合成新数组


如果
p = [[0],[1,3],[2,4]]

那么期望的数组就是
x = [[0,1,2],[0,1,4],[0,3,2],[0,3,4]]


对于期望数组里的X没有顺序要求,只需包含,不缺少,不多余就可以了

我纠结了好几个小时没找到一个良好的算法满足这个条件,求助求助 [LINE]1,#dddddd[/LINE]版务信息:本贴由楼主自主结贴~
作者: dbshy    时间: 2008-3-30 02:01
感觉像全排列,用DFS+剪枝,不知道到我理解对没有,不过时间复杂度好像有点高。
用BFS也可以,时间复杂度会减少,但空间会爆
作者: 幻の飞鱼    时间: 2008-3-30 02:18
我实际使用得数组的量不会太大
用什么方法应该都不会有太大问题
我现在就卡壳在了具体算法的实现上
作者: dbshy    时间: 2008-3-30 02:21
具体算法的实现上????
具体是哪实现有困难,你把你的思路讲一下
作者: 雷欧纳德    时间: 2008-3-30 02:27
把p = [[0],[1,3],[2,4]]
当成一个3维数组,套3层循环44
作者: 幻の飞鱼    时间: 2008-3-30 02:39
我套三层会套出类似0124,0324的组合
不知道怎么识别某个数组现在该放第届个数
因为数组的size都不确定
全是变量
作者: 幻の飞鱼    时间: 2008-3-30 02:48
应该这么说
现在p是三个数,三重循环就可以出

可p的size是未知,这循环套不出来阿
作者: dbshy    时间: 2008-3-30 02:54
我有一个想法,不知道我理解对没有

用循环的话,不能确定范围,还是要用到递归。

我的想法是原数组里含有1个的可以不管,反正要放到新数组每个元素中去,关键是
要怎样将大于2个的元素怎样排列。

用a表示每个原数组中的元素i的个数,b表示每个数组中的元素i是否在排列时都
用了。

既然数据范围小,就用dfs,
if a>1 then
在排列下一个
直到第一个a>1的元素的b为true时,就行了

上面的算法没用到剪枝
作者: 沉影不器    时间: 2008-3-30 03:37
提示: 作者被禁止或删除 内容自动屏蔽
作者: dbshy    时间: 2008-3-30 03:50
我的想法是原数组里含有1个的可以不管,反正要放到新数组每个元素中去,关键是
要怎样将大于2个的元素怎样排列。

用a表示每个原数组中的元素i的个数,b表示每个数组中的元素i是否在排列时都
用了。

既然数据范围小,就用dfs,
if a>1 then
在排列下一个
直到第一个a>1的元素的b为true时,就行了

上面的算法没用到剪枝

我刚才突发奇想,是不是可以用到图来解决或者dp,
LZ可以用图来想一下


作者: 幻の飞鱼    时间: 2008-3-30 05:51
刚头晕去吃夜宵了,我来思考下
作者: 美兽    时间: 2008-3-30 06:56
没测试,可能会有问题,但思路很清晰,回溯法。


@test = [[6,7,8,5],[2,3,5],[5,7,9,8,7]]

def get_new_arg(arg)
    @max = arg.size - 1
    @max_h = arg.last.size
    @arg = arg
    @w = -1
    @new_arg = Array.new
   
    find_list([], 0)
   
    return @new_arg
end  

def find_list(list, index)  
    @h = 0
    @test[index].each{|a|
        if index == @max
           @new_arg << (list + [a])     
           @h += 1
           if @h == @max_h
              return
           end
        else
           l = (list + [a]).clone
           find_list(l, index + 1)      
        end  
    }
end  
  
p get_new_arg(@test)
[LINE]1,#dddddd[/LINE]系统信息:本贴由楼主认可为正确答案,66RPG感谢您的热情解答~
作者: 幻の飞鱼    时间: 2008-3-30 07:02
以下引用美兽于2008-3-29 22:56:49的发言:

没测试,可能会有问题,但思路很清晰,回溯法。



@test = [[6,7,8,5],[2,3,5],[5,7,9,8,7]]

def get_new_arg(arg)
   @max = @test.size - 1
   @max_h = @test.last.size
   @arg = arg
   @w = -1
   @new_arg = Array.new
   
   find_list([], 0)
   
   return @new_arg
end  

def find_list(list, index)  
   @h = 0
   @test[index].each{|a|
       if index == @max
          @new_arg << (list + [a])     
          @h += 1
          if @h == @max_h
             return
          end
       else
          l = (list + [a]).clone
          find_list(l, index + 1)      
       end  
   }
end  

p get_new_arg(@test)


简单的测试下没问题,不过超级没看懂……
仔细研究研究
作者: 美兽    时间: 2008-3-30 07:02
简单的测试下没问题,不过超级没看懂……
仔细研究研究


从后至前,逆循环。

至于如何提出size == 1的组合,就不用赘述了吧。
作者: 沉影不器    时间: 2008-3-30 07:06
提示: 作者被禁止或删除 内容自动屏蔽
作者: 幻の飞鱼    时间: 2008-3-30 07:08
其实 << 的功能不是很懂
作者: 美兽    时间: 2008-3-30 07:11
以下引用幻の飞鱼于2008-3-29 23:08:03的发言:

其实 << 的功能不是很懂


[本贴由作者于 2008-3-29 23:09:23 最后编辑]


呵呵,确实那里漏了,<<是Array的方法,与Integer移位运算<<方法性质不同,尽管RUBY几乎完全面向对象。
作者: 幻の飞鱼    时间: 2008-3-30 07:19

<< 和直接用 = 的区别在哪??=。=

测试了几次没找出关键
作者: 美兽    时间: 2008-3-30 10:27
以下引用幻の飞鱼于2008-3-29 23:19:35的发言:


<< 和直接用 = 的区别在哪??=。=

测试了几次没找出关键


<<对于Array对象来说类似于push,顺路美化代码

@test = [[6,7,8,5],[2,3,5],[5,7,9,8,7]]

def get_new_arg(arg)
   @arg = arg
   @max = @arg.size - 1
   @max_h = @arg.last.size - 1
   @new_arg = Array.new
   
   find_list([], 0)
   
   return @new_arg
end  

def find_list(list, index)  
   @h = 0
   @arg[index].each{|a|
       if index == @max
          @new_arg << (list + [a])     
          @h += 1
          return if @h > @max_h
       end
       find_list(list + [a], index + 1)        
   }
end  

p get_new_arg(@test)
.


作者: 沉影不器    时间: 2008-3-30 18:41
提示: 作者被禁止或删除 内容自动屏蔽
作者: 美兽    时间: 2008-4-1 04:28
翻老帖,实际那个美化有问题— —
each本身即是遍历,@h也是多余。

终稿:
@test = [[6,7,8,5],[2,3,5],[5,7,9,8,7]]

def get_new_arg(arg)
    @arg = arg  
    @max = @arg.size - 1
    @new_arg = Array.new   
   
    find_list([], 0)  
   
    return @new_arg
end  

def find_list(list, index)  
    @arg[index].each{|a|      
        if index == @max
           @new_arg << (list + [a])
           next
        end   
        find_list(list + [a], index + 1)               
    }
end  

p get_new_arg(@test)


作者: 幻の飞鱼    时间: 2008-4-1 05:38
的确,EACH遍厉害后会自动结束
这次是……简化了
作者: bloblo    时间: 2008-4-1 09:23
好贴啊 不错啊 谢谢楼主分享 拉 (*^__^*) 嘻嘻……                
   
     
      
   
   
  
     
   
      
------------------------------------------------------------
域名注册就是网址,网址也叫中文域名,搞不懂!头晕~
作者: dna_7086    时间: 2008-7-4 09:33
提示: 作者被禁止或删除 内容自动屏蔽




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1