C# 将列表与列表匹配
所以我有一张发票和交易清单。我需要根据这两个付款进行发票匹配。比方说C# 将列表与列表匹配,c#,C#,所以我有一张发票和交易清单。我需要根据这两个付款进行发票匹配。比方说 List<int> invoices = new List<int> { 40, 30, 10, 20, 60, 4, 6 }; List<int> payments = new List<int> { 80, 90 }; List invoices=新列表{40,30,10,20,60,4,6}; 名单付款=新名单{80,90}
List<int> invoices = new List<int> { 40, 30, 10, 20, 60, 4, 6 };
List<int> payments = new List<int> { 80, 90 };
List invoices=新列表{40,30,10,20,60,4,6};
名单付款=新名单{80,90};
我想找到与第一笔付款(80)完全匹配的可能组合,然后根据剩下的发票,我希望它与第二笔付款(90)匹配
因此,发票列表中的第一部分40、30和10应与付款列表(80)中的第一项匹配,20、60、4和6应与付款列表(90)中的第二项匹配
我只能用递归的方法匹配1笔付款。您所需要的只是一个神奇的方法。它遍历所有可能的变量,并返回第一个合适的索引组合或null。它还需要一组索引,这些索引将从搜索中排除;您可以很容易地将上次搜索的结果提供给它
静态int[]匹配(列出发票、int付款、int[]排除=默认)
{
如果(exclude==default)exclude=newint[0];
所选列表=新列表();
sbyte加法(整数)
{
int结果=所选。总和(索引=>发票[索引])+编号;
如果(结果<付款)返回-1;
如果(结果>付款)返回1;
返回0;
}
bool Continue(int start)
{
对于(变量i=开始;i付款)继续;
如果(发票[i]==付款)返回新的整数[]{i};
选定。添加(i);
if(Continue(i+1))返回selected.ToArray();
选定。删除(i);
}
返回null;
}
正在运行的代码
小心。 因为有这么多的组合,所以需要一些时间来处理它们(尤其是大型阵列)。
如果你有多种方法来组合第一次付款,但只有一个或几个组合留下的数字可以组合在第二次付款中?听起来好像你想要某种形式的改变,我想只考虑完美的组合。由于将有多个组合,因此将选择两个匹配的唯一完美组合。但在您的示例中有几个“完美”组合:{60,20}{40,30,10,4,6}{40,10,20,4,6}{30,60}等等。它应该返回第一个有效的组合吗?不清楚您定义的“完美”是什么。
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;
}