Получить комбинации размера K на основе словаря c# - PullRequest
0 голосов
/ 29 февраля 2020

У меня есть словарь, подобный этому.

Dictionary<int, string> Diccionario = new Dictionary<int, string>(){
        {1,"124"}  ,  {4,"1457"}  ,  {7,"478"},
        {2,"1235"} ,  {5,"24568"} ,  {8,"05789"},
        {3,"236"}  ,  {6,"3569"}  ,  {9,"698"},
        {0,"08"}   
};

И я хотел бы получить все комбинации для n целого числа. Например.

для n = 11 - 11, 12, 14, 21, 22, 24, 41, 42, 44.

для n = 24 - 11, 14, 15, 17, 21, 24, 25, 27, 31, 34, 35, 37, 51, 54, 55, 57.

для n = 339 - 236, 256, 259...

И так далее ... Но у меня нет ЛЮБОЙ ИДЕИ, как я мог бы пройтись по всем этим числам, поскольку длина каждого числа не всегда одинакова. (1 имеет три возможных комбинации, 2 имеет четыре; и т. Д.)

Спасибо!

Поскольку вы, ребята, спросили меня, откуда поступают данные ... Это происходит отсюда.

enter image description here

Представьте, что PIN-код равен 1273, тогда необходимо создать все возможные комбинации на основе смежного di git (по горизонтали и вертикали) например (1 имеет 2, 3 и само число), чтобы упростить его, я создал словарь, который можно увидеть ранее, указав каждому ключу его возможное значение.

Поскольку ответ был закрыт, я Я не уверен, какую информацию я мог бы добавить, потому что я не могу сказать слишком много о проблеме. Это как если бы у меня был словарь цветов, например:

Dictionary<int, string> Diccionario = new Dictionary<int, string[]>(){
        {1,{"red"}, {"blue"}, {"green"}} , 
        {2,{{"green"}, {"orange"} },
        {3, {{"dark"}}

};

Так что, если бы я получил число 32, комбинация была бы: Dark Green или Dark Orange

Не уверен, если я Я проиллюстрирую мою точку зрения.

Ответы [ 2 ]

1 голос
/ 01 марта 2020

Вы пытаетесь сделать декартово произведение. Это решается здесь: Генерация всех возможных комбинаций (все кредиты Эри c Липперт)

Используя эту функцию, задача действительно проста:

private static readonly int[][] adjacent = new int[][]
    {
        new int[]{0,8},//0
        new int[]{1,2,4},//1  
        new int[]{1,2,3,5},//2
        new int[]{2,3,6},//3
        new int[]{1,4,5,7},//4  
        new int[]{2,4,5,6,8},//5
        new int[]{3,5,6,9},//6
        new int[]{4,7,8},//7
        new int[]{0,5,7,8,9},//8
        new int[]{6,9,8}//9                
    };

public static IEnumerable<IEnumerable<int>> GetCombinations(int[] input)
{
    if (input.Length == 0) { return new int[0][]; }

    return CartesianProduct(input.Select(n => adjacent[n]));
}

Вы заменяете каждое входное число на массив смежных чисел и делаете декартово произведение. Существует специальный случай для пустого ввода, функция CartesianProduct возвращает одну пустую последовательность, что, я думаю, не является правильным результатом. Должен возвращать пустую последовательность последовательностей.

1 голос
/ 29 февраля 2020

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

  • Diccionario должен быть Dictionary<int, int[]>. Строка - ужасный тип для работы. А так как вы, похоже, не используете клавиши * и #, я не вижу вызова для символа.
  • Даже словарь может go за бортом. Простая индексированная коллекция также может это сделать. Обычно вы должны использовать его, только если индексы не являются непрерывными. Но для удобства чтения этот словарь может работать здесь.
  • Вход n также не одно число, а массив int[]

Для ввода {3, 3, 9} вам нужны все комбинации {2, 3, 6}, {2, 3, 6} и { 6, 8, 9}. Это было бы возможно сделать с 4+ слоями вложенных циклов, но вы, вероятно, захотите изучить рекурсию. Это по своей природе рекурсивная операция.

Однако я с большим трудом назвал аргументы и переменные. Это затрудняет написание примера кода.

...