#php #permutation
#php #перестановка
Вопрос:
Привет, я создал рекурсивную функцию перестановки для класса, но мой вывод менее благоприятен. http://codepad.org/DOaMP9oc
function permute($arr) {
$out = array();
if (count($arr) > 1) {
$i = 0;
foreach($arr as $r => $c) {
$n = $arr;
unset($n[$r]);
$out[$c] = permute($n);
}
}
else
return array_shift($arr);
return $out;
}
Если ввод array(1,2,3,4,5)
, вывод:
Array
(
[1] => Array
(
[2] => Array
(
[3] => Array
(
[4] => 5
[5] => 4
)
[4] => Array
(
[3] => 5
[5] => 3
)
[5] => Array
(
[3] => 4
[4] => 3
)
)
ETC......................
Все правильно, вы можете прочитать это так key.key.key.key.value или 12345
, 12354
, 12435
В настоящее время, чтобы преобразовать этот вывод во что-то читаемое, я использую этот уродливый блок кода: http://codepad.org/qyWcRBCl
foreach($out as $k => $a)
foreach($a as $l => $b)
foreach ($b as $m => $c)
foreach ($c as $n => $d)
echo $k.$l.$m.$n.$d.'<br>';
Как я могу изменить свою функцию, чтобы исключить foreach
стек и вывод в аналогичном формате из permute()
.
Комментарии:
1. Что «более читабельно», чем каждое число в новой строке?
2. Метод foreach неэффективен и может содержать только 5 букв. Я хочу исключить foreach и выводить в удобочитаемом формате из
permute()
.3.
in case my teacher has a hard time reading it.
Стек — это не место для ответов на домашние задания4. Это не специально для домашней работы, а для того, чтобы научить меня другому способу вывода, который я, похоже, не могу понять. Домашнее задание полностью выполнено, это пройдет без проблем.
5. Однако вы были бы правы, если бы мое назначение заключалось в выводе определенным образом, а это не так.
Ответ №1:
Мое решение — работать со строками:
function permute($string) {
if (strlen($string)<2) {
return array($string);
}
$permutations = array();
// Copy everything but the first character of the string.
$copy = substr($string, 1);
foreach (permute($copy) as $permutation) {
$length = strlen($permutation);
// Insert the first character of the original string.
for ($i=0; $i<=$length; $i ) {
$permutations[] = substr($permutation, 0, $i) . $string[0] . substr($permutation, $i);
}
}
sort($permutations);
return $permutations;
}
header('Content-type:text/plain');
print_r(permute('12345'));
У вас уже есть рабочая реализация, поэтому я без колебаний предоставляю ее вам. Обратите внимание, что массив создается не по порядку, поэтому я просто сортирую его в конце. Также обратите внимание, что это работает только с вещами, значение которых должно быть равно 1 символу, поэтому перестановка имен автомобилей не сработает.
Даже если вам не нравится этот ответ, я предлагаю вам использовать подсказку типа для массива:
function permute(array $arr) {
Это принудит вас передать в него массив.
Комментарии:
1. К сожалению, назначение было специфичным для использования массива, а не строк.
2. Спасибо вам за это PS, я забыл об этом 😉
Ответ №2:
function display_permutation($array){
if(is_array($array)){
foreach($array as $key => $val){
echo $key;
display_permutation($val);
}
}else{
echo $array;
}
}
Комментарии:
1. Я выбрал аналогичное решение, единственная проблема заключается в том, что оно не выводит точно, оно выводит одну строку. Также я хотел бы объединить функции.
2. если вы делаете отступ по глубине, попробуйте включить поле глубины в рекурсивный метод, а табуляция echo / больше, чем для этого отдела для каждой строки.
Ответ №3:
Вот моя функция перестановки, и мы можем отображать результаты простым способом
class Permute {
public $results = Array();
public function __construct(array $array) {
$this->_permute($array);
}
private function _permute(array $orig, array $perm = Array()) {
if(!count($orig)) {
$this->results[] = $perm;
return null;
}
$count = count($orig);
for($i = 0; $i < $count; $i) {
$orig2 = $orig;
unset($orig2[$i]);
$orig2 = array_values($orig2);
$perm2 = $perm;
$perm2[] = $orig[$i];
$this->_permute($orig2, $perm2);
}
}
}
$arr = Array(1,2,3,4,5);
$permute = new Permute($arr);
foreach($permute->results as $result) {
echo join('', $result).'<br>';
}
Ответ №4:
Я решил использовать следующую функцию:
function showPerms($a,$i='') {
if (is_array($a))
foreach($a as $k => $v)
showPerms($v,$i.$k);
else
echo $i.$a."n";
}
Тем не менее, я все равно хотел бы сделать это в особой рекурсивной функции.