获取一个数组的所有组合 [英] Get all combinations of an array

查看:128
本文介绍了获取一个数组的所有组合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前,我正在试图让,获取数组值的所有可能组合的功能。

我想出了一个非功能版本,但它仅限于3值,所以我试图做一个函数出它变得更加动态

我试了寻找,但没有找到什么,我试图做的,我能找到一个PHP版本PowerShell的例子,但我在我的PHP非常有限。

<一个href=\"http://stackoverflow.com/questions/10834393/php-how-to-get-all-possible-combinations-of-1d-array\">PHP:如何获得一维数组的所有可能的组合?

非功能脚本

  $ NAME ='第一','中','最后'$名单= @()的foreach($ C1在$名){
    的foreach($ C2在$名){
        的foreach($ C3在$名){
            如果(($ C1 -ne $ C2) - 和($ C2 -ne $ C3) - 和($ C3 -ne $ C1))
            {
                $列表+ =$ C1 $ C2 $ C3
            }
        }
    }
}

这给我的结果。

 中间名姓
一是去年中东
中东名姓
中东最后一
最后一中
最后中东第一

我不知道当我递归函数我将如何重新排列的价值观,这是我迄今为止:

 &LT;#
。概要
    简短的介绍
。描述
    长说明
。例
    如何使用此cmdlet例
。例
    如何使用此cmdlet另一个例子
#&GT;
函数获取组合
{
    [CmdletBinding()]
    [输出类型([INT])]
    参数
    (
        #参数1帮助说明
        [参数(强制性= $真实,
                   ValueFromPipelineByPropertyName = $真实,
                   位置= 0)]
        [字符串[]] $阵列,        #参数1帮助说明
        [参数(强制性= $假的,
                   ValueFromPipelineByPropertyName = $假的,
                   位置= 1)]
        [字符串] $温度,        #参数1帮助说明
        [参数(强制性= $假的,
                   ValueFromPipelineByPropertyName = $真实,
                   位置= 2)]
        [字符串[]] $返回
    )    开始
    {
        写详细的启动功能获取组合与参数`$ n`n($阵列|输出字符串)`N $ temp`n`n $($返回|输出字符串)        如果($温度)
        {
            $收益= $温度
        }        $ newArray =新的对象system.collections.arraylist
    }
    处理
    {
        写详细($返回|输出字符串)        对于($ I = 0; $ I $ -lt Array.Length; $ I ++)
        {
            #写详细$ I            $阵列|的foreach对象{$ newArray.Add($ _)}
            $ newArray.RemoveAt($ I)            写详细($ newArray |输出字符串)            如果($ newArray.Count -le 1)
            {
                获取组合-array $ newArray -Temp $温度-return $返回
            }
            其他
            {
                $收益= $温度
            }
        }
        $ newArray
    }
    结束
    {
        写详细退出函数获取组合
    }
}$组合= @(第一,First2,中,一个)$连击=获取组合-array $组合$连击

但我得到的输出是所有的地方

  First2
持续
First2
持续
第一
First2
中间
持续
第一
First2
中间
持续

28/08更新

越来越近,但仍然越来越怪异输出

 &LT;#
。概要
    简短的介绍
。描述
    长说明
。例
    如何使用此cmdlet例
。例
    如何使用此cmdlet另一个例子
#&GT;
函数获取组合
{
    [CmdletBinding()]
    [输出类型([INT])]
    参数
    (
        #参数1帮助说明
        [参数(强制性= $真实,
                    ValueFromPipelineByPropertyName = $真实,
                    位置= 0)]
        [字符串[]] $阵列,        #参数1帮助说明
        [参数(强制性= $假的,
                    ValueFromPipelineByPropertyName = $假的,
                    位置= 1)]
        [字符串] $温度,        #参数1帮助说明
        [参数(强制性= $假的,
                    ValueFromPipelineByPropertyName = $真实,
                    位置= 2)]
        [字符串[]] $返回
    )    开始
    {
        写详细的启动功能获取组合与参数`$ n`n($阵列|输出字符串)`N $ temp`n`n $($返回|输出字符串)        如果($温度)
        {
            $返回+ = $温度
        }        #$ newArray =新对象[System.Collections.ArrayList]
        #$阵列|的foreach对象{$ newArray.Add($ _)|外空}        [System.Collections.ArrayList] $ newArray = $阵列
    }
    处理
    {
        写详细回归 - &GT; $回归        对于($ I = 0; $ I $ -lt Array.Length; $ I ++)
        {
            写详细`$ I - &GT; $ I            $元= $ newArray [0]
            $ newArray.RemoveAt(0)            写详细`$ newArray - &GT; $ newArray
            写详细元素 - &GT; $元素            如果($ newArray.Count -gt 0)
            {
                获取组合-array $ newArray -Temp(($温度++ $元素).Trim())-return $返回
            }
            其他
            {
                $收益= $温度++ $元
            }
        }
        $收益
    }
    结束
    {
        写详细退出函数获取组合
    }
}$组合= @(第一,First2,中,一个)$收益率= @()$连击=获取组合-array $ -return组合收益$$连击

新建输出(是的,有是最后一个值前一个空格,没有我不知道为什么)

 首先First2中东尾
首先First2最后
中间名姓
名姓
First2中最后
First2最后
中东最后
 持续


解决方案

下面是我的解决方案:

 函数删除($元,$名单)
{
    $ newList = @()
    $清单| %{如果($ _ $ -ne元素){$ newList + = $ _}}    返回$ newList
}
功能追加($头,尾$)
{
    如果($ tail.Count -eq 0)
        {回报,$头}    $结果= @()    $尾巴| %{
        $ newList =,$头
        $ _ | %{$ newList + = $ _}
        $结果+ =,$ newList
    }    返回$结果
}
功能置换($名单)
{
    如果($ list.Count -eq 0)
        {返回@()}    $清单| %{
        $排列=置换(删除$ _ $名单)
        返回追加$ _ $排列
    }
}CLS$表=×,Y,Z,T,v的$排列= $重排列表
$排列| %{
    写主机([字符串] ::加入(,$ _))
}

编辑:在一个函数(置换)相同。这是作弊了一下,但是因为我更换蒙山lambda表达式纯函数。您可以用您自己处理堆栈递归调用,但是这将使得code unecessarily复杂...

 功能置换($名单)
{
    美元的全球:删除= {
        参数($元,$名单)        $ newList = @()
        $清单| %{如果($ _ $ -ne元素){$ newList + = $ _}}        返回$ newList
    }    美元的全球:追加= {
        参数($头,尾$)        如果($ tail.Count -eq 0)
            {回报,$头}        $结果= @()        $尾巴| %{
            $ newList =,$头
            $ _ | %{$ newList + = $ _}
            $结果+ =,$ newList
        }        返回$结果
    }    如果($ list.Count -eq 0)
        {返回@()}    $清单| %{
        $排列=置换($ remove.Invoke($ _,$清单))
        返回$ append.Invoke($ _,$排列)
    }
}CLS$表=×,Y,Z,T$排列= $重排列表$排列| %{
    写主机([字符串] ::加入(,$ _))
}

I'm currently trying to make a function that gets all possible combinations of array values.

I have come up with a non function version but it's limited to 3 values so i'm trying to make a function out of it to become more Dynamic

I tried searching SO but could not find a powershell example of what i was trying to do, i could find a PHP version but i'm very limited in my PHP

PHP: How to get all possible combinations of 1D array?

Non-function Script

$name = 'First','Middle','Last'

$list = @()

foreach ($c1 in $name) {
    foreach ($c2 in $name) {
        foreach ($c3 in $name) {
            if (($c1 -ne $c2) -and ($c2 -ne $c3) -and ($c3 -ne $c1))
            {
                $list += "$c1 $c2 $c3"
            }
        }
    }
} 

This gives me the result

First Middle Last
First Last Middle
Middle First Last
Middle Last First
Last First Middle
Last Middle First

I'm not sure how i would rearrange the values when i'm recursing the function, this is what i have so far:

<#
.Synopsis
    Short description
.DESCRIPTION
    Long description
.EXAMPLE
    Example of how to use this cmdlet
.EXAMPLE
    Another example of how to use this cmdlet
#>
function Get-Combinations
{
    [CmdletBinding()]
    [OutputType([int])]
    Param
    (
        # Param1 help description
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   Position=0)]
        [string[]]$Array,

        # Param1 help description
        [Parameter(Mandatory=$false,
                   ValueFromPipelineByPropertyName=$false,
                   Position=1)]
        [string]$Temp,

        # Param1 help description
        [Parameter(Mandatory=$false,
                   ValueFromPipelineByPropertyName=$true,
                   Position=2)]
        [string[]]$Return
    )

    Begin
    {
        Write-Verbose "Starting Function Get-Combinations with parameters `n`n$($Array | Out-String)`n$temp`n`n$($Return | Out-String)"

        If ($Temp)
        {
            $Return = $Temp
        }

        $newArray = new-object system.collections.arraylist
    }
    Process
    {
        Write-Verbose ($return | Out-String)

        For($i=0; $i -lt $Array.Length; $i++)
        {
            #Write-Verbose $i

            $Array | ForEach-Object {$newArray.Add($_)}
            $newArray.RemoveAt($i)

            Write-Verbose ($newArray | Out-String)

            if ($newArray.Count -le 1)
            {
                Get-Combinations -Array $newArray -Temp $Temp -Return $Return
            }
            else
            {
                $Return = $Temp
            }
        }
        $newArray
    }
    End
    {
        Write-Verbose "Exiting Function Get-Combinations"
    }
}

$combinations = @("First","First2","Middle","Last")

$Combos = Get-Combinations -Array $combinations

$Combos

But the output i'm getting is all over the place

First2
Last
First2
Last
First
First2
Middle
Last
First
First2
Middle
Last

28/08 Update

Getting closer but still getting weird output

<#
.Synopsis
    Short description
.DESCRIPTION
    Long description
.EXAMPLE
    Example of how to use this cmdlet
.EXAMPLE
    Another example of how to use this cmdlet
#>
function Get-Combinations
{
    [CmdletBinding()]
    [OutputType([int])]
    Param
    (
        # Param1 help description
        [Parameter(Mandatory=$true,
                    ValueFromPipelineByPropertyName=$true,
                    Position=0)]
        [string[]]$Array,

        # Param1 help description
        [Parameter(Mandatory=$false,
                    ValueFromPipelineByPropertyName=$false,
                    Position=1)]
        [string]$Temp,

        # Param1 help description
        [Parameter(Mandatory=$false,
                    ValueFromPipelineByPropertyName=$true,
                    Position=2)]
        [string[]]$Return
    )

    Begin
    {
        Write-Verbose "Starting Function Get-Combinations with parameters `n`n$($Array | Out-String)`n$temp`n`n$($Return | Out-String)"

        If ($Temp)
        {
            $Return += $Temp
        }

        #$newArray = new-object [System.Collections.ArrayList]
        #$Array | ForEach-Object {$newArray.Add($_) | Out-Null}

        [System.Collections.ArrayList]$newArray = $Array
    }
    Process
    {
        Write-Verbose "return -> $return"

        For($i=0; $i -lt $Array.Length; $i++)
        {
            Write-Verbose "`$i -> $i"

            $element = $newArray[0]
            $newArray.RemoveAt(0)

            Write-Verbose "`$newArray -> $newArray"
            Write-Verbose "Element -> $element"

            if ($newArray.Count -gt 0)
            {
                Get-Combinations -Array $newArray -Temp (($temp + " " +$element).Trim()) -Return $Return
            }
            else
            {
                $Return = $Temp + " " + $element
            }
        }
        $return
    }
    End
    {
        Write-Verbose "Exiting Function Get-Combinations"
    }
}

$combinations = @("First","First2","Middle","Last")

$return = @()

$Combos = Get-Combinations -Array $combinations -Return $return

$Combos

New output (Yes there is a space before the 'Last' value, no i have no idea why)

First First2 Middle Last
First First2 Last
First Middle Last
First Last
First2 Middle Last
First2 Last
Middle Last
 Last

解决方案

Here is my solution:

function Remove ($element, $list)
{
    $newList = @()
    $list | % { if ($_ -ne $element) { $newList += $_} }

    return $newList
}


function Append ($head, $tail)
{
    if ($tail.Count -eq 0)
        { return ,$head }

    $result =  @()

    $tail | %{
        $newList = ,$head
        $_ | %{ $newList += $_ }
        $result += ,$newList
    }

    return $result
}


function Permute ($list)
{
    if ($list.Count -eq 0)
        { return @() }

    $list | %{
        $permutations = Permute (Remove $_ $list)
        return Append $_ $permutations
    }
}

cls

$list = "x", "y", "z", "t", "v"

$permutations = Permute $list


$permutations | %{
    Write-Host ([string]::Join(", ", $_))
}

EDIT: the same in one function (Permute). This is cheating a bit, however since I replaced plain functions whith lambdas. You could replace recursive calls with a stack you handle yourself, but that would make the code unecessarily complex ...

function Permute ($list)
{
    $global:remove = { 
        param ($element, $list) 

        $newList = @() 
        $list | % { if ($_ -ne $element) { $newList += $_} }  

        return $newList 
    }

    $global:append = {
        param ($head, $tail)

        if ($tail.Count -eq 0)
            { return ,$head }

        $result =  @()

        $tail | %{
            $newList = ,$head
            $_ | %{ $newList += $_ }
            $result += ,$newList
        }

        return $result
    }

    if ($list.Count -eq 0)
        { return @() }

    $list | %{
        $permutations = Permute ($remove.Invoke($_, $list))
        return $append.Invoke($_, $permutations)
    }
}

cls

$list = "x", "y", "z", "t"

$permutations = Permute $list

$permutations | %{
    Write-Host ([string]::Join(", ", $_))
}

这篇关于获取一个数组的所有组合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆