Есть такой набор данных:
var replies1 = new List<int>() { 1, 4, 7 };
var replies2 = new List<int>() { 2, 5, 8 };
var replies3 = new List<int>() { 3, 6, 9 };
Есть массив массивов, эти массивы агрегирующий:
var mas = new List<List<int>>() { replies1, replies2, replies3 };
Необходимо построить все возможные маршруты. Маршруты будут такими:
123
423
723
156
456
756
...
Количество массивов может быть неограниченным, как и их длина. По сути это дерево со множеством вершин. Подскажите пожалуйста, как можно реализовать алгоритм, который соберет все возможные маршруты? Очевидно, что реализовать можно рекурсивно, но мои тщетные попытки ни к чему не привели.
Решение с фиксированным количеством массивов:
for (int i = 0; i < replies1.Count; i++)
{
for (int j = 0; j < replies2.Count; j++)
{
for (int k = 0; k < replies3.Count; k++)
{
Console.Write(String.Format("{0}, {1}, {2}", replies1[i], replies2[j], replies3[k]));
Console.WriteLine();
}
}
}
Как правильно написали в комментариях, вам нужно декартово произведение множеств (или вы неправильно описали задачу и привели неправильный пример для фиксированного числа множеств).
Для заранее неизвестного числа множеств можно написать такой рекурсивный вариант:
static class Extensions
{
public static IEnumerable<T> Cartesian<T>(this IEnumerable<IEnumerable<T>> source, Func<T, T, T> aggregator)
{
var list = source as List<IEnumerable<T>> ?? source.ToList();
return CartesianImpl(list, list.Count - 1, aggregator);
}
static IEnumerable<T> CartesianImpl<T>(List<IEnumerable<T>> list, int startIndex, Func<T, T, T> aggregator)
{
if (startIndex > 0)
{
foreach (var y in list[startIndex])
foreach (var x in CartesianImpl(list, startIndex - 1, aggregator))
yield return aggregator(x, y);
}
else
{
foreach (var e in list[startIndex])
yield return e;
}
}
}
Более простой вариант, с использованием итератора, но возвращающий последовательности немного в другом порядке:
static class Extensions
{
public static IEnumerable<T> Cartesian<T>(this IEnumerable<IEnumerable<T>> source, Func<T, T, T> aggregator)
{
var enumerator = source.GetEnumerator();
if (!enumerator.MoveNext()) return Enumerable.Empty<T>();
var result = enumerator.Current;
while (enumerator.MoveNext())
{
var current = enumerator.Current;
result = result.SelectMany(e => current, (x, y) => aggregator(x, y));
}
return result;
}
}
Используем:
var replies1 = new List<int>() { 1, 4, 7 };
var replies2 = new List<int>() { 2, 5, 8 };
var replies3 = new List<int>() { 3, 6, 9 };
var mas = new List<List<int>>() { replies1, replies2, replies3 };
var res = mas.Cartesian((x, y) => 10 * x + y);
Console.WriteLine(string.Join("\n", res));
Виртуальный выделенный сервер (VDS) становится отличным выбором
Как сделал выборку листов при импорте из Excel файла в бд laravelНа данный момент мой импорт:
Например, когда я пишу так: $users = $this->getDoctrine()->getRepository('ProfileBundle:User')->findBy(['deletedAt' => null]); то к модели пользователя подтягиваются все связанные...
Помогите пофиксить ошибку, вот код отправки письма