算一个数组的所有组合方式

目的:给一个数字数组,算出这个数组的所有组合方式。

例子:比如给一个数组为{234456}(这里为了能列举出所有的组合方式,所以选择一个长度较小的数组),那么我们所要得到的结果为6组数:{234456}{235644}{442356}{445623}{562344}{564423}。这三个数所能组成的数组方式不会再有第七种。

不考虑的问题:本文没有考虑类似这样的情况:给定的数组中的数有同值,比如,{232356},从而得到的组合方式除去冗余数据后,并没有6组。

关键词:

数组:本文指一个长度至少为1的数字数组对象。如{112244}

数组元素:文本指数组中的单个数值,如{112244}中有三个数组元素分别为:112244

数组长度:本文指一个数组中数组元素的个数。

组合方式:本文指数组元素在本数组中出现的顺序。

基本算法思想:

如果数组的长度为1如下:

11

那么,返回的数组的组合方式自然是一种,其值为11

但是我在此基础上加了一个数,长度为2,如下:

11

22

那么,返回的数组是两个组合方式,如下:

11

22

22

11

以此类推,如果我再加入一个元素,使数组长度为3,那么所能组合成的数组也就如同前文提到的6个:

11

22

33

11

33

22

22

11

33

22

33

11

33

11

22

33

22

11

那么下面就可以说规律性的东西了。

当数组长度为1时,返回的组合方式只有1种,就是它本身。当新加一个数组元素时,这个新元素就会与原来的每一种组合方式中的每个数组元素发成关系,表现为:新数组元素在原来的每一种组合方式中的各个位置分别插入一次,这样就出现更多的组合方式,而这所有的组合方式的合集,就是加入新元素后的新数组的所有组合方式,如图:

11

这个数组只有一个数组元素,我们然后新添加一个数组元素,值为22,那么:

22

11

22插入到11之前

11

22

22插入到11之后。那么{2211}{1122}就是加入了22这个新数组元素后的所有组合方式了。

如果再加入新组数元素33,那么:

33

22

11

22

33

11

22

11

33

33

11

22

11

33

22

11

22

33

前三行分别是把新数组元素33插入到上文所得到的第一个组合方式{2211}中,后三行分别是把新数组元素33插入到上文所得到的第二个组合方式{1122}中。形成的组合方式就是上图所画的6种组合方式,而它也是数组{112233}的所有组合方式了。

 

实现:实现这个算法,那么免不了要用到递归了。下面先看一下递归的示例图:

 

代码: 

 

ExpandedBlockStart.gif 代码
     public   static  List < int [] >  GetDataArray( int [] data)
        {        
            List
< int [] >  list  =   new  List < int [] >  ();            
            
if (data  == null )
                
return  list;
            
if  (data.Length  ==   1 )        // 如果长度为1,那么返回它的组合方式,即它本身。
            {           
                list.Add(data);                
            }
            
else    // 否则,引入新的数组元素,并插入到原有的组合方式的各个位置,形成新的组合方式。
            {
                
int [] dataSub  =   new   int [data.Length  -   1 ];
                
for  ( int  i  =   0 ; i  <  data.Length  -   1 ; i ++ )
                {
                    dataSub[i] 
=  data[i  +   1 ];
                }
                List
< int [] >  listOld  =  GetDataArray(dataSub);   // 获取原有的组合方式
                
                
                
int  newNum  =  data[ 0 ];
                
int [] newData  =   null ;
                
for  ( int  i  =   0 ; i  <  listOld.Count; i ++ )            // 遍历每一种原有的组合方式
                {
                    
for  ( int  j  =   0 ; j  <=  listOld[i].Length; j ++ )   // 遍历组合方式中的每个位置
                    {
                        newData 
=   new   int [listOld[i].Length  +   1 ];
                        newData[j] 
=  newNum;
                        
int  currentIndex  =   0 ;
                        
for  ( int  n  =   0 ; n  <  listOld[i].Length; n ++ )
                        {
                            
if  (currentIndex  ==  j)
                                currentIndex
++ ;
                            newData[currentIndex] 
=  listOld[i][n];
                            currentIndex
++ ;

                        }
                        list.Add(newData);
                    }
                }
                
            }
            
return  list;

        }

 

 

结论:这是我为一个朋友的实际需求而写的一个算法,当时时间仓促,算法不免有许多不足之处,抛出来供大家参考,大家如果有好的算法也希望写出来一块学习。

转载于:https://www.cnblogs.com/shiyuxinglan/archive/2010/04/27/1721880.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果你想将多个数组合并成一个数组,可以使用 PHP 中的 array_merge() 函数。这个函数可以将多个数组合并成一个新的数组,其中相同的键名的元素会被后面的数组覆盖。 例如,假设你有两个数组 $arr1 和 $arr2,你可以使用下面的代码将它们合并成一个新的数组: ```php $arr1 = ['a' => 1, 'b' => 2]; $arr2 = ['c' => 3, 'd' => 4]; $merged = array_merge($arr1, $arr2); print_r($merged); ``` 输出结果为: ``` Array ( [a] => 1 [b] => 2 [c] => 3 [d] => 4 ) ``` 需要注意的是,如果数组中存在相同的键名,后面的数组会覆盖前面的数组。如果你想保留所有元素,可以使用 array_merge_recursive() 函数。这个函数会递归地将数组合并成一个新的数组,其中相同的键名的元素会被合并成一个数组。 例如,假设你有两个数组 $arr1 和 $arr2,其中都包含一个键名为 'a' 的元素,你可以使用下面的代码将它们合并成一个新的数组: ```php $arr1 = ['a' => 1, 'b' => 2]; $arr2 = ['a' => 3, 'd' => 4]; $merged = array_merge_recursive($arr1, $arr2); print_r($merged); ``` 输出结果为: ``` Array ( [a] => Array ( [0] => 1 [1] => 3 ) [b] => 2 [d] => 4 ) ``` 需要注意的是,array_merge_recursive() 函数会将相同键名的元素合并成一个数组,即使这些元素的值不是数组类型。如果你不希望这样,可以使用 array_replace_recursive() 函数。这个函数会将相同键名的元素替换成后面的数组的值,而不是将它们合并成数组。 例如,假设你有两个数组 $arr1 和 $arr2,其中都包含一个键名为 'a' 的元素,你可以使用下面的代码将它们合并成一个新的数组: ```php $arr1 = ['a' => 1, 'b' => 2]; $arr2 = ['a' => 3, 'd' => 4]; $merged = array_replace_recursive($arr1, $arr2); print_r($merged); ``` 输出结果为: ``` Array ( [a] => 3 [b] => 2 [d] => 4 ) ``` 在使用这些函数时,需要注意不同的函数对于相同键名的元素的处理方式。根据你的需求选择合适的函数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值