Объединить значения из одного массива в другой в переполнении стека

Я пытаюсь создать функцию для генерации всех возможных комбинаций определенной группы символов и иметь ее переменную в зависимости от длины.

У меня есть функция для создания массива символов, которые я хотел бы, и это прекрасно работает.

function generate_characters($l, $n, $d) {
$r = array();

if ($l === true) {
foreach (range('a', 'z') as $index) {
array_push($r, $index);
}
}

if ($n === true) { array_push($r, '0','1','2','3','4','5','6','7','8','9'); }if ($d === true) { array_push($r, '-'); }

return $r;
}

Затем мне нужно, чтобы он создал массив всех возможных комбинаций на основе $ length, например, если ‘$ length = 1’, мне нужен следующий массив

Array
(
[0] => a
[1] => b
[2] => c
[3] => d
[4] => e
[5] => f
[6] => g
[7] => h
[8] => i
[9] => j
[10] => k
[11] => l
[12] => m
[13] => n
[14] => o
[15] => p
[.... removed some values to save on length ....]
[35] => 9
)

но если ‘$ length = 2’ мне нужно это

Array
(
[0] => aa
[1] => ab
[2] => ac
[3] => ad
[4] => ae
[5] => af
[6] => ag
[7] => ah
[8] => ai
[9] => aj
[.... removed some values to save on length ....]
[1329] => 97
[1330] => 98
[1331] => 99
)

Я пробовал array_walk () и array_walk_recursive (), а также несколько циклов foreach и while, но безрезультатно.

Я могу заставить это работать, вручную делая это для каждой длины, но не с переменной длиной, делая это, но не знаю, как сделать это переменным по длине.

function generate_two($l, $n, $d) {
$r = array();

foreach (generate_characters($l, $n, false) as $v1) {
foreach (generate_characters($l, $n, $d) as $v2) {
array_push($results, "$v1$v2");
}
}
return $r;
}

все это при отсутствии символа «-» в качестве первого символа, хотя я мог бы удалить эти значения после генерации массива, если мне нужно.

Спасибо Дэн

2

Решение

Предполагая, что вы хотите использовать созданный вами массив в качестве массива для добавления в него. Я не понимаю, почему вам нужно работать с определенными символами, отличными от символов в массиве (я могу ошибаться, но это может быть легко адаптировано для этого).

/**
* @param array $array
* @param $length
* @param null $original
* @return array
*/
function generate_values(array $array, $length, $original = null) {

// If length is 1 or less just return the array
if ($length <= 1) {
return $array;
}

// The resulting values array
$result = [];

// Copy the array if original doesn't exist
if (!is_array($original)) {
$original = $array;
}

// Loop over each item and append the original values
foreach($array as $item) {
foreach($original as $character) {
$result[] = $item . $character;
};
}

// Recursively generate values until the length is 1
return generate_values($result, --$length, $original);
}

Чтобы использовать его, вы можете использовать свой генератор.

$characterArray = generate_characters(true, false, false);

$results = generate_values($characterArray, 2);
1

Другие решения

Я не знаю, является ли это лучшим решением, но:

function generate_characters($length, $n, $d, $array = array()) {
$letters = array('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9');
$numbers = range(0, 9);
$others = array('-');

if($n == true)
$letters = array_merge($letters, $numbers);

if($d == true)
$letters = array_merge($letters, $others);if(empty($array))
$array = $letters;

if(--$length <= 0)
return $array;

$result = array();
foreach ($array as $value) {
foreach ($letters as $add) {
$result[] = $value.$add;
}
}

return generate_characters($length, $n, $d, $result);
}

echo '<pre>';
print_r(generate_characters(3, true, true));
0

Образец кода

function generate_characters($l, $n, $d)
{
// Start with an empty list
$r = array();

// Add the letters, if required
if ($l) {
$r = array_merge($r, range('a', 'z'));
}
// Add the digits, if required
if ($n) {
$r = array_merge($r, range('0', '9'));
}
// Add special characters, if required
if ($d) {
$r[] = '-';
}

return $r;
}/**
* Generate all combinations of $len characters using the characters
* from a given list
*
* @param array $chars  the list of characters to use
* @param int   $len    the length of strings to generate
* @return array
*/
function generate_combinations(array $chars, $len)
{
// $len <= 0: this is an error
// $len == 1: the input list is the output
if ($len <= 1) {
return $chars;
}

// Compute the output here
$result = array();

// Recursively compute the list of characters of length $len - 1
$partial = generate_combinations($chars, $len - 1);

// Append each entry from the input list to each string of length $len - 1 computed on the previous step
foreach ($partial as $head) {
foreach ($chars as $tail) {
// Put the combination in the output list
$result[] = $head.$tail;
}
}

// This is the list of all strings of length $len over the list $chars
return $result;
}

использование

Нет необходимости звонить generate_characters() опять и опять. Учитывая одинаковые аргументы, он всегда возвращает один и тот же список символов. Сохраните его в переменной, используйте переменную дальше.

$chars = generate_characters(TRUE, FALSE, TRUE);
$comb2 = generate_combinations($chars, 2);
$comb5 = generate_combinations($chars, 5);

замечания

Хотя теоретически правильно, генерация всех комбинаций совершенно бесполезна в реальной жизни. Количество комбинаций увеличивается в геометрической прогрессии, и вскоре ваш скрипт будет использовать всю доступную память для хранения списка.

Я протестировал приведенный выше код, и PHP 5.6 потребовалось более 2 ГБ памяти для генерации всех комбинаций из 5 символов (с использованием букв + тире). PHP 7 использует память лучше, и для этой же задачи ему требуется менее 1 ГБ памяти.

Как вы можете себе представить, невозможно использовать более высокие значения для параметра $len; даже для $len == 5перечисленные выше суммы уже огромны.

0

Если вы хотите комбинацию двух значений массива, вы можете использовать непосредственно этот код. Вам не требуется длина этого массива в вашей функции.

function generateValue($array1, $array2) {
$result = array();
foreach ($array as $value) {
foreach ($original as $value2) {
$result[] = $value.$value2;
}
}

return $result;
}
print_r(generateValue($array1, $array2));
0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector