php用递归实现字符串的全排列?

td901105td 2015-06-27 01:48:20
我想在程序中实现打印字符串的全排列,代码如下

function output ($src_arr)
{
foreach ($src_arr as $key => $value) {
$temp_arr = $src_arr;
echo $value;
if (! empty($temp_arr)) {
array_splice($temp_arr, $key, 1);
output($temp_arr);
return;
} else {
echo "<br/>";
return;
}
}
}

$str = 'abc';
$src_arr = str_split($str);
output($src_arr);



但是结果只是打印abc,我想问一下究竟是什么原因,我感觉没什么问题,请大神指教!
...全文
271 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
xuzuning 2015-06-30
  • 打赏
  • 举报
回复
print_r($log_arr); print_r($const_src_arr); print_r(array_diff($log_arr, $const_src_arr)); 就可知道为什么是空的了
td901105td 2015-06-30
  • 打赏
  • 举报
回复
引用 5 楼 xuzuning 的回复:
对于主贴的 function output ($src_arr) { foreach ($src_arr as $key => $value) { $temp_arr = $src_arr; echo $value; if (! empty($temp_arr)) { array_splice($temp_arr, $key, 1); //这个将数组元素减少一个 output($temp_arr); return; //这里直接返回,就循环不到第二个元素 } else { echo "<br/>"; return; } } } 对于 #2 的改革版 你只要在入口处打印一下 $src_arr function output ($src_arr , $log_arr ,$const_src_arr) { print_r($src_arr); .... 就可看到 $src_arr 并没有按你期望的那样传入
Array
(
    [0] => a
    [1] => b
    [2] => c
)  //第一次进入是对的
Array
(
) //第二次进入怎么就是空的啦?应该有 b、c 两个吧
aArray
(
)
bArray
(
)
c
我也不清楚为啥第二次就是空的了,递归用不好就是很容易出现莫名的错误
free361 2015-06-30
  • 打赏
  • 举报
回复

$a = "abcdefgij";


function quan($s,$len=0,$lv=2,$out=array()){
	if ($len == 0) $len = strlen($s);
	if ($len <= 1) return $s;	
	if ($len < $lv) return $out;
	
	if ($lv == 2){
		$x = substr($s,0,-$lv);
		
		$a = substr($s,-2,1);
		$b = substr($s,-1,1);
		$out[] = $x.$a.$b;
		$out[] = $x.$b.$a;
	}else{
		//取倒数lv个,然后将lv后面的依次替换第lv个
		
		$y = substr($s,-$lv,1);//取第lv个元素
		
		$z = substr($s,1-$lv);//准备替换的元素
		
		for ($i=0;$i<strlen($z);$i++){
			foreach ($out as $k=>$v) {

				$pos1 = strpos($v, $z[$i]);	//第一个位置
				$pos2 = strpos($v, $y);		//要替换的位置

				$v[$pos1] = $y;
				$v[$pos2] = $z[$i];
				
				$t_out[] = $v;
				
			}
		}
		
		$out = array_merge($out,$t_out);
	}
	
	return quan($s,$len,++$lv,$out);
	
}

$t1 = microtime(true);
$m1 = memory_get_usage();
$b = quan($a);

$t2 = microtime(true);
$m2 = memory_get_usage();

print_r("<pre>");
print_r ($t2-$t1);
print_r ("<br>");
print_r (($m2-$m1)/1024/1024);
print_r ($b);
print_r ($t2);
print_r("</pre>");
xuzuning 2015-06-29
  • 打赏
  • 举报
回复
对于主贴的 function output ($src_arr) { foreach ($src_arr as $key => $value) { $temp_arr = $src_arr; echo $value; if (! empty($temp_arr)) { array_splice($temp_arr, $key, 1); //这个将数组元素减少一个 output($temp_arr); return; //这里直接返回,就循环不到第二个元素 } else { echo "<br/>"; return; } } } 对于 #2 的改革版 你只要在入口处打印一下 $src_arr function output ($src_arr , $log_arr ,$const_src_arr) { print_r($src_arr); .... 就可看到 $src_arr 并没有按你期望的那样传入
Array
(
    [0] => a
    [1] => b
    [2] => c
)  //第一次进入是对的
Array
(
) //第二次进入怎么就是空的啦?应该有 b、c 两个吧
aArray
(
)
bArray
(
)
c
td901105td 2015-06-29
  • 打赏
  • 举报
回复
引用 3 楼 xuzuning 的回复:
$a = array(1,2,3);
perm($a, 0, count($a)-1);

function perm($ar, $k, $m) {
  if($k == $m) echo join('',$ar), PHP_EOL;
  else {
    for($i=$k; $i<=$m; $i++) {
      swap($ar[$k], $ar[$i]);
      perm($ar, $k+1, $m);
    }
  }
}
function swap(&$a, &$b) {
  $c = $a;
  $a = $b;
  $b = $c;
}
如果按引用传递原始数组则
$a = array(1,2,3);
perm($a, 0, count($a)-1);

function perm(&$ar, $k, $m) {
  if($k == $m) echo join('',$ar), PHP_EOL;
  else {
    for($i=$k; $i<=$m; $i++) {
      swap($ar[$k], $ar[$i]);
      perm($ar, $k+1, $m);
      swap($ar[$k], $ar[$i]);
    }
  }
}
function swap(&$a, &$b) {
  $c = $a;
  $a = $b;
  $b = $c;
}
这个思路要比你的清晰吧?(移植的 C 代码)
的确很简单,但是我还是想搞清楚为什么我的程序循环只执行一次就停止了?
xuzuning 2015-06-28
  • 打赏
  • 举报
回复
$a = array(1,2,3);
perm($a, 0, count($a)-1);

function perm($ar, $k, $m) {
  if($k == $m) echo join('',$ar), PHP_EOL;
  else {
    for($i=$k; $i<=$m; $i++) {
      swap($ar[$k], $ar[$i]);
      perm($ar, $k+1, $m);
    }
  }
}
function swap(&$a, &$b) {
  $c = $a;
  $a = $b;
  $b = $c;
}
如果按引用传递原始数组则
$a = array(1,2,3);
perm($a, 0, count($a)-1);

function perm(&$ar, $k, $m) {
  if($k == $m) echo join('',$ar), PHP_EOL;
  else {
    for($i=$k; $i<=$m; $i++) {
      swap($ar[$k], $ar[$i]);
      perm($ar, $k+1, $m);
      swap($ar[$k], $ar[$i]);
    }
  }
}
function swap(&$a, &$b) {
  $c = $a;
  $a = $b;
  $b = $c;
}
这个思路要比你的清晰吧?(移植的 C 代码)
td901105td 2015-06-28
  • 打赏
  • 举报
回复
引用 1 楼 xuzuning 的回复:
你把第9行的 return 注释掉,就可知道问题的所在了
根据你的意见我把代码改成下面这样了
/*
 * 输出字符串的全排列
 * 先从数组中任意取出一个字母,然后再全排列剩下的字符串
 */
function output ($src_arr , $log_arr ,$const_src_arr)
{
    //(第一次的改进)根据17行,此处必须使用一个数组记录已经取出的数据,所以传递一个空数组参数进来
    foreach ($src_arr as $key => $value) {
        $temp_arr = $src_arr;
        $log_arr[] = $value;
        if (count($temp_arr) > 1) {
            //(第二次改进)
            //使用array_diff($log_arr, $temp_arr)时
            //第二次会出现temp_arr=array('b','c')
            //log_arr = array('a','b')
            //所以要传入第三个数组,是一个不会改变的数组,记录的是原始数组
            //echo $value . strval(output(array_diff($log_arr, $temp_arr) , $log_arr));
            echo $value . strval(output(array_diff($log_arr, $const_src_arr) , $log_arr , $const_src_arr));
        } else  if (count($temp_arr) == 1) {
                echo $temp_arr[0] . "<br/>";
        }
    }
}

$str = 'abc';

$src = str_split($str);
$record_arr = array();
output($src, $record_arr, $src);
但是还是只是打印abc,我想问一下为什么循环只执行了一次,按道理应该是最外面的三次,中间循环两次,一共是六次啊,是因为什么?
xuzuning 2015-06-27
  • 打赏
  • 举报
回复
你把第9行的 return 注释掉,就可知道问题的所在了

21,894

社区成员

发帖
与我相关
我的任务
社区描述
从PHP安装配置,PHP入门,PHP基础到PHP应用
社区管理员
  • 基础编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧