Комбинации без повторений должны быть включены в комбинации - PullRequest
0 голосов
/ 16 ноября 2018

У меня есть 2 списка int с, и мне нужен список всех возможных комбинаций без повторений из 5 чисел. Но также необходимо включить все int из другого списка.

Пример:

var takeFrom = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
var mustInclude = new List<int> { 1, 3, 5 };

Я использовал KwCombinatorics , но чтобы закончить, нужны годы. И почти 80% результата бесполезны, потому что он не содержит int s из списка mustInclude.

Пример вывода:

var result = new List<int> 
{
     { 1, 3, 5, 9, 10 },
     { 1, 3, 5, 8, 7 },
     { 1, 3, 5, 6, 9 },
}

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

Ответы [ 2 ]

0 голосов
/ 16 ноября 2018

Заимствование GetAllCombos из этого Вопроса , и, используя идею @juharr, я полагаю, что следующий код даст вам результаты, которые вы ищете.

List<int> takeFrom = new List<int> { 2, 4, 6, 7, 8, 9, 10 };
    List<int> mustInclude = new List<int> { 1, 3, 5 };

    protected void Page_Load(object sender, EventArgs e)
    {
        List<List<int>> FinalList = new List<List<int>>();

        FinalList = GetAllCombos(takeFrom);
        FinalList = AddListToEachList(FinalList, mustInclude);

        gvCombos.DataSource = FinalList;
        gvCombos.DataBind();
    }

    // Recursive
    private static List<List<T>> GetAllCombos<T>(List<T> list)
    {
        List<List<T>> result = new List<List<T>>();
        // head
        result.Add(new List<T>());
        result.Last().Add(list[0]);
        if (list.Count == 1)
            return result;
        // tail
        List<List<T>> tailCombos = GetAllCombos(list.Skip(1).ToList());
        tailCombos.ForEach(combo =>
        {
            result.Add(new List<T>(combo));
            combo.Add(list[0]);
            result.Add(new List<T>(combo));
        });
        return result;
    }

    private static List<List<int>> AddListToEachList(List<List<int>> listOfLists, List<int> mustInclude)
    {
        List<List<int>> newListOfLists = new List<List<int>>();

        //Go through each List
        foreach (List<int> l in listOfLists)
        {
            List<int> newList = l.ToList();

            //Add each item that should be in all lists
            foreach(int i in mustInclude)
                newList.Add(i);

            newListOfLists.Add(newList);
        }

        return newListOfLists;
    }

    protected void gvCombos_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            List<int> drv = (List<int>)e.Row.DataItem;
            Label lblCombo = (Label)e.Row.FindControl("lblCombo");

            foreach (int i in drv)
                lblCombo.Text += string.Format($"{i} "); 
        }
    }

GetAllCombos дает вам все комбинации без номеров, требуемых для всех списков, а затем второй метод AddListToEachList добавит необходимые числа в каждый список.

0 голосов
/ 16 ноября 2018

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

Примерно так:

takeFrom = takeFrom.Except(mustInclude).ToList();
listOfPairs = KwCombinatorics(takeFrom, 2);
result = listOfPairs.Select(pair => mustInclude.Concat(pair).ToList()).ToList();
...