ruby中对数组的全排列

全排列,从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列
思路1:将一个数组拆分为前、后两部分,对后数组进行遍历,将遍历到的元素添加进前数组,并从后数组中删除,形成两个新的数组,以这两新数组为参数,进行下一步的递归。采用的是深度优先搜索算法
代码:
def dfs(pre, after)
    if after.length == 0
        yield(pre)
        return
    end
    after.each do |element|
        nextPre = pre.clone
        nextPre << element
        nextAfter = after.clone
        nextAfter.delete(element)
        dfs(nextPre, nextAfter) do |result|
            yield(result)
        end
    end
end

dfs([], [1, 2, 3, 4, 5]) do |result|
    print result
    print "\n"
end

思路2:在思路1的基础上进行优化,思路1的代码中,对pre和after的复制产生了额外的时间和空间开销,于是可以考虑将pre改为栈结构,after改为链表结构(在ruby中全都以数组来实现),在对after的遍历中,直接将after中的元素弹出给pre,递归结束后再将pre的头元素弹回到after的原位置,再进行下一次迭代:
def dfs(pre, after)
    if after.length == 0
        yield(pre)
        return
    end
    (0..after.length-1).each do |i|
        pre << after.delete_at(i)
        dfs(pre, after) do |result|
            yield(result)
        end
        after[i, 0] = pre.pop
    end
end

思路3:使用广度优先搜索算法,建立一个队列,队列中的元素为哈希表,哈希表由pre和after两个数组组成,队列初始只有一个哈希表,就是pre是空数组,after是原始数组,然后对after进行遍历,遍历中的操作跟前面类似,从after中弹出元素到pre,然后把新的pre和after装进一个新的哈希表,添加到队列末尾,遍历结束后,将队列头弹出,直到队列头的after长度为0,即表示全排列完成:
def bfs(queue)
    while queue.first['after'].length > 0       
        pre = queue.first['pre']
        after = queue.first['after']
        (0..after.length-1).each do |i|
            nextPre = pre.clone
            nextAfter = after.clone
            nextPre << nextAfter.delete_at(i)
            queue << Hash['pre' => nextPre, 'after' => nextAfter]
        end
        queue.shift
    end
    yield(queue)
end



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值