php 递归函数 求解

yangbenmu1988 易销科技 工程师  2012-10-01 10:41:12
本来按照想法,递归函数用测试数组返回来的应该是一个有2个值的二维数组。但值得到了一个数组,加红部分是不是不能这么写,那要怎么写呢?求解
================================代码如下所示=============================================================
<?php
$strr =array("周四301_菲尼克斯水星_芝加哥天空_主胜_2.10","周二302_明尼苏达山猫_印第安纳狂热_主胜_1.20","周二302_明尼苏达山猫_印第安纳狂热_客胜_2.92");

//这是分割数组的方法-----
function A($str){
//定义一个二维数组来存放根据逻辑分割出来的array
$newstr=array();
for($i=0;$i<count($str)-1;$i++){
$e1=explode("_",$str[$i]);
$e2=explode("_",$str[$i+1]);
if($e1[0].$e1[1].$e1[2]==$e2[0].$e2[1].$e2[2]){
//先分割成(两个)数组再在递归调用A($str)
A(array_splice($str,$i,$i));
A(array_splice($str,$i+1,$i+1));

}
}
array_push($newstr,$str);
return $newstr;
}
//------------------------
$back=A($strr);
print_r($back);
?>
==========================================================================================================
...全文
430 点赞 收藏 49
写回复
49 条回复
切换为时间正序
请发表友善的回复…
发表回复
yangbenmu1988 2012-10-03
明天晚上结贴:问题解决了,这里总结一下。
-----------可爱的分割线------------------
27楼是最佳答案41楼的代码是按照我的思路和代码写的,但没有去除二维数组里的多余项,我自己写了一个去除二维数组相等项的代码(array_unqie只能去除一维数组的相同项,所以要自己来实现),也实现了。
----------------------再分割一次-------
我多次测试了一下:时间效率和空间效率都是27楼的更佳;41楼次之。但由于我的需求不会处理大数据,所以都无所谓,关键看思路你喜欢哪个。
--》27:先分组,在排列。
--》41:先递归排序,再去重复项。
-----------------------------------------------
我最先想到的是27楼的方法,但处理起来没做到他那么简洁,所以开始的时候放弃了这种思路;
再者我就想到了递归,之后。。。。。。我就来这里问了。

谢谢大家的慷慨帮助
除了47楼广告党(鄙视)
午夜十二点
回复
yangbenmu1988 2012-10-02
[Quote=引用 43 楼 的回复:]
引用 40 楼 的回复:

围观27楼,问题解决了就好,感觉acabin是专业人士

我那个只能解决前三项整体为2项的数据,在压数组的时候没用循环,用了2句数组赋值,出来的结果里每项肯定只有2个子项

我也是PHP新手,呵呵,在这帖里学习到了不少东东,原来数组输出,直接用PRE修饰就很直观了

继续学习


其实我自己调试要输出结果的时候都是用var_dump的;xdebug……
[/Quote]
这里的xdebug能像myeclipse那样跟踪程序执行吗?我昨天晚上配置好了xdebug,不知道怎么用。
回复
acabin 2012-10-02
[Quote=引用 40 楼 的回复:]

围观27楼,问题解决了就好,感觉acabin是专业人士

我那个只能解决前三项整体为2项的数据,在压数组的时候没用循环,用了2句数组赋值,出来的结果里每项肯定只有2个子项

我也是PHP新手,呵呵,在这帖里学习到了不少东东,原来数组输出,直接用PRE修饰就很直观了

继续学习
[/Quote]

其实我自己调试要输出结果的时候都是用var_dump的;xdebug的var_dump比print_r好用很多。
推荐使用。
回复
acabin 2012-10-02
[Quote=引用 31 楼 的回复:]

引用 30 楼 的回复:
哪两个重复举例说明
你把strr替换回你原先的就知道我的程序是不是符合用例

比如1:array(a_1,a_2,b_1)------(经过函数调用后)---array(array(a_1,b_1),array(a_2,b_1))
以开头字母区分。
比如2:array(a_1,a_2,b_1,b_2,c_1))------(经过函数调用后)---……
[/Quote]
如果仅是这个需求的话,我上面的程序已经达到了
你仔细看看吧
回复
acabin 2012-10-02
[Quote=引用 41 楼 的回复:]
那只是你的数据给的不太适合,排一下序就可以了
我并不知道你想干什么!只是根据你的代码来猜测你的思路。要是离开你的整体构思,就没有意义了
PHP code
$str_2=array("a_a_a_1","a_a_a_2","b_b_b_1","b_b_b_2","c_c_c_1","a_a_a_3");
//------------------------
$back = A($str_2);……
[/Quote]
他的想法其实是这样的:
对每一场比赛,有两个赔率;
有多场比赛;
从每场比赛里面,抽出一个赔率,形成组合;
要求所有组合的可能性。

其实就是一个(每场比赛只抽出一个赔率,)对于赔率的全组合。
回复
xuzuning 2012-10-02
那只是你的数据给的不太适合,排一下序就可以了
我并不知道你想干什么!只是根据你的代码来猜测你的思路。要是离开你的整体构思,就没有意义了
$str_2=array("a_a_a_1","a_a_a_2","b_b_b_1","b_b_b_2","c_c_c_1","a_a_a_3");
//------------------------
$back = A($str_2);
print_r($back);

//这是分割数组的方法-----
function A($str){
sort($str); //排序,把相似的摆在一起
//定义一个二维数组来存放根据逻辑分割出来的array
$newstr = array();
for($i=0;$i<count($str)-1;$i++){
$e1 = explode("_",$str[$i]);
$e2 = explode("_",$str[$i+1]);
if($e1[0].$e1[1].$e1[2]==$e2[0].$e2[1].$e2[2]){
//先分割成(两个)数组再在递归调用A($str)
$t = $str;
array_splice($str,$i+1, 1);
$newstr = array_merge($newstr, A($str));
$str = $t;
array_splice($str,$i, 1);
$newstr = array_merge($newstr, A($str));
}
}
if(! $newstr) array_push($newstr,$str);
return $newstr;
}
Array
(
[0] => Array
(
[0] => a_a_a_1
[1] => b_b_b_1
[2] => c_c_c_1
)

[1] => Array
(
[0] => a_a_a_1
[1] => b_b_b_2
[2] => c_c_c_1
)

[2] => Array
(
[0] => a_a_a_3
[1] => b_b_b_1
[2] => c_c_c_1
)

[3] => Array
(
[0] => a_a_a_3
[1] => b_b_b_2
[2] => c_c_c_1
)

[4] => Array
(
[0] => a_a_a_3
[1] => b_b_b_1
[2] => c_c_c_1
)

[5] => Array
(
[0] => a_a_a_3
[1] => b_b_b_2
[2] => c_c_c_1
)

[6] => Array
(
[0] => a_a_a_2
[1] => b_b_b_1
[2] => c_c_c_1
)

[7] => Array
(
[0] => a_a_a_2
[1] => b_b_b_2
[2] => c_c_c_1
)

[8] => Array
(
[0] => a_a_a_3
[1] => b_b_b_1
[2] => c_c_c_1
)

[9] => Array
(
[0] => a_a_a_3
[1] => b_b_b_2
[2] => c_c_c_1
)

[10] => Array
(
[0] => a_a_a_3
[1] => b_b_b_1
[2] => c_c_c_1
)

[11] => Array
(
[0] => a_a_a_3
[1] => b_b_b_2
[2] => c_c_c_1
)

[12] => Array
(
[0] => a_a_a_2
[1] => b_b_b_1
[2] => c_c_c_1
)

[13] => Array
(
[0] => a_a_a_3
[1] => b_b_b_1
[2] => c_c_c_1
)

[14] => Array
(
[0] => a_a_a_2
[1] => b_b_b_2
[2] => c_c_c_1
)

[15] => Array
(
[0] => a_a_a_3
[1] => b_b_b_2
[2] => c_c_c_1
)

)

回复
yangbenmu1988 2012-10-02
[Quote=引用 47 楼 的回复:]
这个有点复杂, 看的不是太懂, 不过我这个网站里面好像有用到这个, 是模仿的别人的代码~~~~
请参看: www.yunying001.com
[/Quote]
你这是来打广告的吧,怎么你那么多其他的回帖里面都有这个网站。
回复
围观27楼,问题解决了就好,感觉acabin是专业人士

我那个只能解决前三项整体为2项的数据,在压数组的时候没用循环,用了2句数组赋值,出来的结果里每项肯定只有2个子项

我也是PHP新手,呵呵,在这帖里学习到了不少东东,原来数组输出,直接用PRE修饰就很直观了

继续学习
回复
fjyxian 2012-10-02
高手都是喜欢把简单的事情变复杂化……
回复
yangbenmu1988 2012-10-02
[Quote=引用 27 楼 的回复:]
发现还是不需要递归

PHP code

<?php
$strr =array("第一场301_菲尼克斯水星_芝加哥天空_主胜_2.10","第一场301_菲尼克斯水星_芝加哥天空_客胜_12.10","第二场301_菲尼克斯水星_芝加哥天空_主胜_2.10","第二场301_菲尼克斯水星_芝加哥天空_客胜_12.10","第三场302_明尼苏达山猫_印第安纳狂热_主胜_1.20","第……
[/Quote]
我惊喜的发现acabin在27楼的代码是正确的,测试了3组数据都OK。
大家可以去围观学习一下,这个不用递归的方法。
如果有递归正确的方法,欢迎告知。
回复
yangbenmu1988 2012-10-02
[Quote=引用 35 楼 的回复:]
人家要用递归,自然有人家的道理
为什么不用递归可以解决,用递归就不能解决呢?
并且楼主也意识到递归点有些问题了

PHP code
$strr =array(
"周四301_菲尼克斯水星_芝加哥天空_主胜_2.10",
"周二302_明尼苏达山猫_印第安纳狂热_主胜_1.20",
"周二302_明尼苏达山猫_印第安纳狂热_客胜_2.92",
);

//这是分割数……
[/Quote]
是的,之前我写的的确没return。但你现在写的递归也有问题,它只递归了一成。我觉得这里递归主要有一问题就是怎么分两半同时递归调用。
你的代码用$str_2=array("a_a_a_1","a_a_a_2","b_b_b_1","b_b_b_2","c_c_c_1","a_a_a_3");测试========》》》》结果。
Array
(
[0] => Array
(
[0] => a_a_a_1
[1] => b_b_b_1
[2] => c_c_c_1
[3] => a_a_a_3
)

[1] => Array
(
[0] => a_a_a_1
[1] => b_b_b_2
[2] => c_c_c_1
[3] => a_a_a_3
)

[2] => Array
(
[0] => a_a_a_2
[1] => b_b_b_1
[2] => c_c_c_1
[3] => a_a_a_3
)

[3] => Array
(
[0] => a_a_a_2
[1] => b_b_b_2
[2] => c_c_c_1
[3] => a_a_a_3
)

[4] => Array
(
[0] => a_a_a_2
[1] => b_b_b_1
[2] => c_c_c_1
[3] => a_a_a_3
)

[5] => Array
(
[0] => a_a_a_2
[1] => b_b_b_2
[2] => c_c_c_1
[3] => a_a_a_3
)

)
说明还没递归完全,里面还是有a_a_a相等的。
回复
yangbenmu1988 2012-10-02
[Quote=引用 33 楼 的回复:]
呵呵,睡醒了来上CSDN,看了一下你写的19楼的结果字符串,现在总结一下,看是不是这个意思:
原始数据里,前三项是一个整体,处理后,第一重数组里的前三项整体不能重复
原始数据简化如下:A_主胜_2.10 B_主胜_1.20 B_客胜_2.92,而这三项其实是一整体,不能分割,只能总体排列
要得到的输出结果为2组:
A_主胜_2.10
B_客胜_2.92

A_主胜_2.10
B_主……
[/Quote]
首先感谢终于有一个人明白我的意图了,你的代码我看了一下,没用递归我就知道一定不能达到我的要求。经测试:代码中foreach里notice(这里要强制转换成array或者判断is_array),还有忘了声明$result数组。在测试数组$str_1 =array("周四301_菲尼克斯水星_芝加哥天空_主胜_2.10","周二302_明尼苏达山猫_印第安纳狂热_主胜_1.20","周二302_明尼苏达山猫_印第安纳狂热_客胜_2.92");没有问题、、、、、
但测试数组$str_2=array("a_a_a_1","a_a_a_2","b_b_b_1","b_b_b_2","c_c_c_1","a_a_a_3");确出问题了。
PS:我确实是刚学php没多久,总觉得不得劲,之前学过点java,属于新手。acabin的代码确实小清新,但我觉得没用递归还是解决不了的,去研究一下他的代码先。
回复
xuzuning 2012-10-02
人家要用递归,自然有人家的道理
为什么不用递归可以解决,用递归就不能解决呢?
并且楼主也意识到递归点有些问题了
$strr =array(
"周四301_菲尼克斯水星_芝加哥天空_主胜_2.10",
"周二302_明尼苏达山猫_印第安纳狂热_主胜_1.20",
"周二302_明尼苏达山猫_印第安纳狂热_客胜_2.92",
);

//这是分割数组的方法-----
function A($str){
//定义一个二维数组来存放根据逻辑分割出来的array
$newstr = array();
for($i=0;$i<count($str)-1;$i++){
$e1 = explode("_",$str[$i]);
$e2 = explode("_",$str[$i+1]);
if($e1[0].$e1[1].$e1[2]==$e2[0].$e2[1].$e2[2]){
//先分割成(两个)数组再在递归调用A($str)
$t = $str;
array_splice($str,$i+1, 1);
$newstr = array_merge($newstr, A($str));
$str = $t;
array_splice($str,$i, 1);
$newstr = array_merge($newstr, A($str));
}
}
if(! $newstr) array_push($newstr,$str);
return $newstr;
}
//------------------------
$back = A($strr);
print_r($back);
Array
(
[0] => Array
(
[0] => 周四301_菲尼克斯水星_芝加哥天空_主胜_2.10
[1] => 周二302_明尼苏达山猫_印第安纳狂热_主胜_1.20
)

[1] => Array
(
[0] => 周四301_菲尼克斯水星_芝加哥天空_主胜_2.10
[1] => 周二302_明尼苏达山猫_印第安纳狂热_客胜_2.92
)

)
回复
最前面是原始数据定义:
$strr =array("周四301_菲尼克斯水星_芝加哥天空_主胜_2.10","周二302_明尼苏达山猫_印第安纳狂热_主胜_1.20","周二302_明尼苏达山猫_印第安纳狂热_客胜_2.92");

上面的没粘上
回复
呵呵,睡醒了来上CSDN,看了一下你写的19楼的结果字符串,现在总结一下,看是不是这个意思:
原始数据里,前三项是一个整体,处理后,第一重数组里的前三项整体不能重复
原始数据简化如下:A_主胜_2.10 B_主胜_1.20 B_客胜_2.92,而这三项其实是一整体,不能分割,只能总体排列
要得到的输出结果为2组:
A_主胜_2.10
B_客胜_2.92

A_主胜_2.10
B_主胜_1.20

呼,总算有点明白楼主要什么了,好难表达清楚...
上面9楼代码里,for循环那应该是count($str)而不是count($str)-1。从我们上面的结果入手 ,继续处理就好了,再加个数据比较的函数
看下面的,和你要的结果一样:
function B($str)
{
$newstr=array();
for($i=0;$i<count($str);$i++)
{
$e{$i}=explode("_",$str[$i]);
}
for($i=0;$i<count($str);$i++)
{
array_push($newstr,$e{$i});
}
return $newstr;
}
function C($str1, $str2)
{
if ($str1[0].$str1[1].$str1[2]==$str2[0].$str2[1].$str2[2])
{
return 0;
}
else
{
return 1;
}
}
$str2 = B($strr);
for ($i=0; $i<count($str2); $i++)
{
for ($j=$i+1; $j<count($str2); $j++)
{
$temp = array();
if (C($str2[$i], $str2[$j]))
{
$temp[]=$str2[$i];
$temp[]=$str2[$j];
$result[]=$temp;
}
}
}
echo "(<br>";
foreach($result as $key=>$value)
{
echo "    [".$key."]=><br>";
foreach($value as $key2=>$value2)
{
echo "        [".$key2."]=>";
print_r($value2);
echo "<br>";
}
}
echo ")";

输出结果:
(
[0]=>
[0]=>Array ( [0] => 周四301 [1] => 菲尼克斯水星 [2] => 芝加哥天空 [3] => 主胜 [4] => 2.10 )
[1]=>Array ( [0] => 周二302 [1] => 明尼苏达山猫 [2] => 印第安纳狂热 [3] => 主胜 [4] => 1.20 )
[1]=>
[0]=>Array ( [0] => 周四301 [1] => 菲尼克斯水星 [2] => 芝加哥天空 [3] => 主胜 [4] => 2.10 )
[1]=>Array ( [0] => 周二302 [1] => 明尼苏达山猫 [2] => 印第安纳狂热 [3] => 客胜 [4] => 2.92 )
)

PS:原来不搞PHP,写出来的代码其他风格较重,见谅呀,看acabin的代码就舒服多了。楼主也不是搞PHP的吧,上来就是for循环

另外,我坚持认为10楼就不是来帮人解决问题的,具体原因见本帖及这里,还有这里
回复
var_dump还不大懂,呵呵,不过我现在在用NetBeans IDE,跟踪调试很方便,就是调的xdebug,配置起来也很快,程序安装上,添加下面几句到php.ini中就可以用了
zend_extension = "D:/wamp/bin/php/php5.3.13/zend_ext/php_xdebug-2.2.0-5.3-vc9-x86_64.dll"

[xdebug]
xdebug.remote_enable=on
xdebug.remote_handler=dbgp
xdebug.remote_host=localhost
xdebug.remote_port=9000
回复
acabin 2012-10-02
[Quote=引用 44 楼 的回复:]
这里的xdebug能像myeclipse那样跟踪程序执行吗?我昨天晚上配置好了xdebug,不知道怎么用。
[/Quote]
xdebug支持某个debug协议(具体是哪个忘了)
在php.ini里面做好配置后可以与很多开发工具联调
回复
yangbenmu1988 2012-10-01
我想是我表达的不够准确:
我用测试数组想要得到的结果是一个二维数组里包涵两个一维数组:
Array([0]=>Array(),
[1]=>Array())
判断的依据是:“周二302_明尼苏达山猫_印第安纳狂热”相等,所以二维数组中包涵的一维数组的count()应该是2
回复
www_7di_net 2012-10-01
代碼如下:
<?PHP

$strr =array("周四301_菲尼克斯水星_芝加哥天空_主胜_2.10","周二302_明尼苏达山猫_印第安纳狂热_主胜_1.20","周二302_明尼苏达山猫_印第安纳狂热_客胜_2.92");


Foreach($strr as $k=>$v) {
$strr[$k]=Str2Arr($v,'_',False,False,False);//是否去除空arr項目,是否Trim掉外層,是否去除重複值
}

Print_r ($strr);


//函数:将字符串重新组合成1维数组
//参数:待重组的字符串,分隔符,是否去除空arr項目,是否Trim掉外層所有的指定符號和空格(不管有幾個),是否去除重複值
Function Str2Arr($Str,$Cod="|",$Filter=True,$Trim=True,$Chongfu=True){
$Arr=Array();
IF($Trim){
$Str=Trim($Str," ".$Cod."");
}Else{
$Str=(SubStr($Str,0,1)==$Cod)?SubStr($Str,1,(StrLen($Str)-1)):$Str;
$Str=(SubStr($Str,-1,1)==$Cod)?SubStr($Str,0,(StrLen($Str)-1)):$Str;
}
IF(!$Str){
Return $Arr;
}
$Arr=Explode($Cod,$Str);
IF($Filter){
$Arr=Array_Filter($Arr,'_nul');
}
IF($Chongfu){
$Arr=Array_Unique($Arr);
}
Return $Arr;
}



輸出結果如下:
Array
(
[0] => Array
(
[0] => 周四301
[1] => 菲尼克斯水星
[2] => 芝加哥天空
[3] => 主胜
[4] => 2.10
)

[1] => Array
(
[0] => 周二302
[1] => 明尼苏达山猫
[2] => 印第安纳狂热
[3] => 主胜
[4] => 1.20
)

[2] => Array
(
[0] => 周二302
[1] => 明尼苏达山猫
[2] => 印第安纳狂热
[3] => 客胜
[4] => 2.92
)

)
回复
yangbenmu1988 2012-10-01
[Quote=引用 30 楼 的回复:]
哪两个重复举例说明
你把strr替换回你原先的就知道我的程序是不是符合用例
[/Quote]
比如1:array(a_1,a_2,b_1)------(经过函数调用后)---array(array(a_1,b_1),array(a_2,b_1))
以开头字母区分。
比如2:array(a_1,a_2,b_1,b_2,c_1))------(经过函数调用后)---array(array(a_1,b_1,c_1),array(a_1,b_2,c_1),array(a_2,b_1,c_1),array(a_2,b_2,c_1))

我这样说能明白我的意思吗?只不过我之前的测试数组要求是“第一场301_菲尼克斯水星_芝加哥天空”前面这些相同为区别。
回复
发动态
发帖子
基础编程
创建于2007-09-28

2.1w+

社区成员

从PHP安装配置,PHP入门,PHP基础到PHP应用
申请成为版主
社区公告
暂无公告