Список соответствия со списком - PullRequest
2 голосов
/ 22 апреля 2020

Итак, у меня есть список счетов и транзакций. Мне нужно сделать сопоставление счетов на основе этих обоих платежей. Допустим,

            List<int> invoices = new List<int> { 40, 30, 10, 20, 60, 4, 6 };
            List<int> payments = new List<int> { 80, 90 };

Я хочу найти возможную комбинацию, которая будет точно соответствовать первым платежам (80), а затем на основе оставленных счетов-фактур. Я хочу выполнить сопоставление со вторым платежом (90).

Таким образом, первый раздел в списке счетов, который равен 40,30 и 10, должен совпадать с первым пунктом в списке платежей (80), а 20, 60, 4 и 6 должен совпадать со вторым пунктом в списке платежей (90).

Я могу выполнить сопоставление только с 1 платежом, используя рекурсив.

1 Ответ

0 голосов
/ 22 апреля 2020

Все, что вам нужно, - это метод магов c. Он просматривает все возможные варианты и возвращает первую подходящую комбинацию индексов или ноль. Также он принимает массив индексов, которые будут исключены из поиска; Вы можете легко кормить его результатами, полученными в результате предыдущего поиска.


static int[] Match(List<int> invoices, int payment, int[] exclude = default)
        {
            if (exclude == default) exclude = new int[0];
            List<int> selected = new List<int>();
            sbyte Add(int number)
            {
                int result = selected.Sum(index => invoices[index]) + number;
                if (result < payment) return -1;
                if (result > payment) return 1;
                return 0;
            }
            bool Continue(int start)
            {
                for (var i = start; i < invoices.Count; i++)
                {
                    if (exclude.Contains(i)) continue;
                    switch (Add(invoices[i]))
                    {
                        case 1:
                            break;
                        case -1:
                            selected.Add(i);
                            if (Continue(i + 1))
                                return true;
                            selected.Remove(i);
                            break;
                        case 0:
                            selected.Add(i);
                            return true;
                    }
                }
                return false;
            }
            for (int i = 0; i < invoices.Count; i++)
            {
                if (exclude.Contains(i) || invoices[i] > payment) continue;
                if (invoices[i] == payment) return new int[] { i };
                selected.Add(i);
                if (Continue(i + 1)) return selected.ToArray();
                selected.Remove(i);
            }
            return null;
        }

Код в действии здесь .


Будьте осторожны.

Поскольку комбинаций так много, обработка всех их занимает некоторое время (особенно больших массивов). Может быть, вы должны рассмотреть что-то еще.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...