Алгоритм подбора всех комбинаций многомерного массива
Нужна простая универсальная функция с рекурсией для поиска всех комбинаций значений из массива массивов. В массиве может быть произвольное количество массивов, в каждом из которых произвольное количество элементов.
Пример:
массив1: 1.1, 1.2, 1.3
массив2: 2.1, 2.2, 2.3
массив3: 3.1, 3.2.
Результат:
Массив, внутри которого массивы:
1) 1.1, 2.1, 3.1
2) 1.1, 2.1, 3.2
3) 1.1, 2.2, 3.1
4) 1.1, 2.2, 3.2
и т.д.
Пример:
массив1: 1.1, 1.2, 1.3
массив2: 2.1, 2.2, 2.3
массив3: 3.1, 3.2.
Результат:
Массив, внутри которого массивы:
1) 1.1, 2.1, 3.1
2) 1.1, 2.1, 3.2
3) 1.1, 2.2, 3.1
4) 1.1, 2.2, 3.2
и т.д.
По теме из базы знаний
Найденные решения
Зачем тут рекурсия?
1. Заводите массив "Индексы" длиной "количество массивов". Начальные значения всех элементов массива - 0.
2. Собираете строку вида "ВсеМассивы[Сч][Индексы[Сч]]" - берёте элемент с индексом Индексы[Сч] из массива ВсеМассивы[Сч].
3. Увеличиваете Индексы: если Индексы[0] нельзя увеличить (стал равен длине массива ВсеМассивы[0]), то обнуляете этот индекс и переходите к следующему. Если после этого у вас опять все индексы будут равны 0, то конец алгоритма, все возможные индексы перебрали.
1. Заводите массив "Индексы" длиной "количество массивов". Начальные значения всех элементов массива - 0.
2. Собираете строку вида "ВсеМассивы[Сч][Индексы[Сч]]" - берёте элемент с индексом Индексы[Сч] из массива ВсеМассивы[Сч].
3. Увеличиваете Индексы: если Индексы[0] нельзя увеличить (стал равен длине массива ВсеМассивы[0]), то обнуляете этот индекс и переходите к следующему. Если после этого у вас опять все индексы будут равны 0, то конец алгоритма, все возможные индексы перебрали.
&НаКлиенте
Процедура ВывестиРезультат(Команда)
// Подготовка
ВсеМассивы = Новый Массив;
Для Сч = 1 По 3 Цикл
ВсеМассивы.Добавить(Новый Массив);
КонецЦикла;
Для Сч = 0 По ВсеМассивы.Количество() - 1 Цикл
Для Сч1 = 1 По 3 Цикл
ВсеМассивы[Сч].Добавить(Сч1);
КонецЦикла;
КонецЦикла;
// Основная часть
// Хранение текущего индекса элемента каждого массива
Индексы = Новый Массив;
Для Сч = 1 По ВсеМассивы.Количество() Цикл
Индексы.Добавить(0);
КонецЦикла;
Пока Истина Цикл
ВывестиСообщение(ВсеМассивы, Индексы);
Если НЕ УвеличитьИндекс(ВсеМассивы, Индексы) Тогда
Прервать;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
&НаКлиенте
Процедура ВывестиСообщение(Массивы, Индексы)
Сообщение = Новый Массив;
Для Сч = 0 По Индексы.Количество() - 1 Цикл
Сообщение.Добавить(Массивы[Сч][Индексы[Сч]]);
КонецЦикла;
Сообщить(СтрСоединить(Сообщение, ","));
КонецПроцедуры
&НаКлиенте
Функция УвеличитьИндекс(Массивы, Индексы)
Результат = Ложь;
Для Сч = 0 По Индексы.Количество() - 1 Цикл
// Увеличиваем текущий индекс, если это возможно
Если Индексы[Сч] < Массивы[Сч].Количество() Тогда
Индексы[Сч] = Индексы[Сч] + 1;
КонецЕсли;
// Если вышли за границу, то обнуляем его и увеличиваем следующий
Если Индексы[Сч] = Массивы[Сч].Количество() Тогда
Индексы[Сч] = 0;
Продолжить;
Иначе
Прервать;
КонецЕсли;
КонецЦикла;
// Если перебрали все индексы, то в конце будут одни нули.
Для Каждого ТекИндекс Из Индексы Цикл
Если ТекИндекс <> 0 Тогда
Результат = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
ПоказатьОстальные ответы
Подписаться на ответы
Инфостарт бот
Сортировка:
Древо развёрнутое
Свернуть все
Вот так?
Функция ОбходМассива(Массив)
ВыводВСтроку = "";
Для каждого Элемента из Массив Цикл
Если ТипЗнч(Элемент) = Массив Тогда
СтрокаМассива = ОбходМассива(Элемент);
Сообщить(СтрокаМассива);
Иначе
ВыводВСтроку = ВыводВСтроку + Строка(Элемент) + ", "
КонецЕсли;
КонецЦикла;
Возврат ВыводВСтроку;
КонецФункции
Функция ОбходМассива(Массив)
ВыводВСтроку = "";
Для каждого Элемента из Массив Цикл
Если ТипЗнч(Элемент) = Массив Тогда
СтрокаМассива = ОбходМассива(Элемент);
Сообщить(СтрокаМассива);
Иначе
ВыводВСтроку = ВыводВСтроку + Строка(Элемент) + ", "
КонецЕсли;
КонецЦикла;
Возврат ВыводВСтроку;
КонецФункции
Неплохо было бы уточнить терминологию. Многомерный массив или массив массивов.
Потому как при
И при вашем Примере будет:
массив1: 1.1, 1.2, 1.3
массив2: 2.1, 2.2, 2.3
массив3: 3.1, 3.2, Неопределено
А ежели это просто:
То как мы поймем, что на выходе нужно 3х3, ежели у нас вложенные
произвольной длины?
Потому как при
Массив = Новый Массив(3, 3);
Массив[0][0] = 11;
Массив[0][1] = 12;
Массив[0][2] = 13;
Массив[1][0] = 21;
Массив[1][1] = 22;
Массив[1][2] = 23;
Массив[2][0] = 31;
Массив[2][1] = 32;
ПоказатьИ при вашем Примере будет:
массив1: 1.1, 1.2, 1.3
массив2: 2.1, 2.2, 2.3
массив3: 3.1, 3.2, Неопределено
А ежели это просто:
Массив = Новый Массив;
ВложенныйМассив1 = Новый Массив;
ВложенныйМассив1.Добавить(11);
ВложенныйМассив1.Добавить(12);
ВложенныйМассив1.Добавить(13);
Массив.Добавить(ВложенныйМассив1);
То как мы поймем, что на выходе нужно 3х3, ежели у нас вложенные
произвольной длины?
Зачем тут рекурсия?
1. Заводите массив "Индексы" длиной "количество массивов". Начальные значения всех элементов массива - 0.
2. Собираете строку вида "ВсеМассивы[Сч][Индексы[Сч]]" - берёте элемент с индексом Индексы[Сч] из массива ВсеМассивы[Сч].
3. Увеличиваете Индексы: если Индексы[0] нельзя увеличить (стал равен длине массива ВсеМассивы[0]), то обнуляете этот индекс и переходите к следующему. Если после этого у вас опять все индексы будут равны 0, то конец алгоритма, все возможные индексы перебрали.
1. Заводите массив "Индексы" длиной "количество массивов". Начальные значения всех элементов массива - 0.
2. Собираете строку вида "ВсеМассивы[Сч][Индексы[Сч]]" - берёте элемент с индексом Индексы[Сч] из массива ВсеМассивы[Сч].
3. Увеличиваете Индексы: если Индексы[0] нельзя увеличить (стал равен длине массива ВсеМассивы[0]), то обнуляете этот индекс и переходите к следующему. Если после этого у вас опять все индексы будут равны 0, то конец алгоритма, все возможные индексы перебрали.
&НаКлиенте
Процедура ВывестиРезультат(Команда)
// Подготовка
ВсеМассивы = Новый Массив;
Для Сч = 1 По 3 Цикл
ВсеМассивы.Добавить(Новый Массив);
КонецЦикла;
Для Сч = 0 По ВсеМассивы.Количество() - 1 Цикл
Для Сч1 = 1 По 3 Цикл
ВсеМассивы[Сч].Добавить(Сч1);
КонецЦикла;
КонецЦикла;
// Основная часть
// Хранение текущего индекса элемента каждого массива
Индексы = Новый Массив;
Для Сч = 1 По ВсеМассивы.Количество() Цикл
Индексы.Добавить(0);
КонецЦикла;
Пока Истина Цикл
ВывестиСообщение(ВсеМассивы, Индексы);
Если НЕ УвеличитьИндекс(ВсеМассивы, Индексы) Тогда
Прервать;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
&НаКлиенте
Процедура ВывестиСообщение(Массивы, Индексы)
Сообщение = Новый Массив;
Для Сч = 0 По Индексы.Количество() - 1 Цикл
Сообщение.Добавить(Массивы[Сч][Индексы[Сч]]);
КонецЦикла;
Сообщить(СтрСоединить(Сообщение, ","));
КонецПроцедуры
&НаКлиенте
Функция УвеличитьИндекс(Массивы, Индексы)
Результат = Ложь;
Для Сч = 0 По Индексы.Количество() - 1 Цикл
// Увеличиваем текущий индекс, если это возможно
Если Индексы[Сч] < Массивы[Сч].Количество() Тогда
Индексы[Сч] = Индексы[Сч] + 1;
КонецЕсли;
// Если вышли за границу, то обнуляем его и увеличиваем следующий
Если Индексы[Сч] = Массивы[Сч].Количество() Тогда
Индексы[Сч] = 0;
Продолжить;
Иначе
Прервать;
КонецЕсли;
КонецЦикла;
// Если перебрали все индексы, то в конце будут одни нули.
Для Каждого ТекИндекс Из Индексы Цикл
Если ТекИндекс <> 0 Тогда
Результат = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Показать
Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот