C# 中的排列算法
我正在努力解决我需要编写的算法。我正在使用 C#。
假设我有一个 List
和一个 List
。 我需要编写一个算法来枚举所有袋子中午餐的所有排列。
例如,假设有 3 份午餐和 2 个袋子:
// Permutation 1
Bag 1, Lunch 1
Bag 2, Lunch 1
// Permutation 2
Bag 1, Lunch 1
Bag 2, Lunch 2
// Permutation 3
Bag 1, Lunch 1
Bag 2, Lunch 3
// Permutation 4
Bag 1, Lunch 2
Bag 2, Lunch 1
// Permutation 5
Bag 1, Lunch 2
Bag 2, Lunch 2
// Permutation 6
Bag 1, Lunch 2
Bag 2, Lunch 3
// Permutation 7
Bag 1, Lunch 3
Bag 2, Lunch 1
// Permutation 8
Bag 1, Lunch 3
Bag 2, Lunch 2
// Permutation 9
Bag 1, Lunch 3
Bag 2, Lunch 3
这两个排列 Bag 1 Lunch 1 和 Bag 2 Lunch 2
和 Bag 1 Lunch 2 和 Bag 2 Lunch 1
是不同的由于袋子的容量不同,因此需要对它们进行枚举。
袋子和午餐的数量可以是任意数量。
我创建了一个名为 BagLunch
的类,其中包含一个袋子和午餐对。我上面给出的示例列表将存储在 List
中。
谢谢。
I'm struggling with this algorithm I need to write. I'm using C#.
Say I have a List<Bag>
and I have a List<Lunch>
.
I need to write an algorithm which will enumerate all permutations of lunches in all bags.
For example, say there are 3 lunches and 2 bags:
// Permutation 1
Bag 1, Lunch 1
Bag 2, Lunch 1
// Permutation 2
Bag 1, Lunch 1
Bag 2, Lunch 2
// Permutation 3
Bag 1, Lunch 1
Bag 2, Lunch 3
// Permutation 4
Bag 1, Lunch 2
Bag 2, Lunch 1
// Permutation 5
Bag 1, Lunch 2
Bag 2, Lunch 2
// Permutation 6
Bag 1, Lunch 2
Bag 2, Lunch 3
// Permutation 7
Bag 1, Lunch 3
Bag 2, Lunch 1
// Permutation 8
Bag 1, Lunch 3
Bag 2, Lunch 2
// Permutation 9
Bag 1, Lunch 3
Bag 2, Lunch 3
The two permutations Bag 1 Lunch 1 and Bag 2 Lunch 2
and Bag 1 Lunch 2 and Bag 2 Lunch 1
are different because the bags have different capacities, hence they would both need to be enumerated.
The number of bags and lunches can be any number.
I have created a class called BagLunch
which contains a bag and lunch pair. The example list I've given above would be stored in a List<BagLunch>
.
Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
在 LINQ 中使用交叉联接:
编辑:
您需要修改 select 子句来处理
BagLunch
类的结构。Use a cross join in LINQ:
Edit:
You'll want to modify the select clause to handle the structure of your
BagLunch
class.如果您允许欺骗[午餐可以装在两个袋子中] - 正如示例所示,您有
#bags^#lunches
可能性。每个袋子都有自己独特的“选择”来放置午餐
要生成这些可能性 - 只需“选择”午餐作为袋子,然后递归调用算法即可。每次午餐重复一次。
生成它们的伪代码:
If you allow dupes [a lunch can be in two bags] - as the example suggests you have
#bags^#lunches
possibilities.Each bag has its own unique "choice" which lunch to put
To genereate these possibilities - just "choose" a lunch for a bag, and recursively invoke the algorithm. repeat for each lunch.
pseudo code for generating them:
那么您想在保留订单的同时从 n 个(k = 袋子,n = 午餐)中检查 k 个吗?我希望你能假设 k<=n,否则你会被空袋子困住......
我不想完全破坏你的作业,所以我只会为你指出正确的方向。这就需要递归。首先选择第一个袋子的午餐,然后选择剩下的 k-1 袋子的午餐。当您只剩下一袋午餐时,请选择剩余的每份午餐,直到吃完为止。
编辑:
哦,午餐可以同时装在两个袋子里。所以是n^k。最短的方法是使用上面建议的 LINQ 交叉连接,但这感觉有点像作弊。相反,只需创建一个包含 K 个元素的整数数组,用零填充它,然后开始向最右边的元素加 1。当到达 N 时,将其重置为零并将 1 带到下一个元素。您只是在计算以 N 为基数的 K 位数字。每次迭代后,您可以输出包分配。
So you want to go over k out of n (k = bags, n = lunches) while keeping the order? I hope you can assume that k<=n, otherwise you're going to get stuck with empty bags...
I don't want to spoil your homework entirely, so I'll just point you in the right direction. This begs for recursion. First choose the lunch for the first bag, then choose the lunches for the k-1 bags that are left. When you have only one bag left, choose each of the remaining lunches until you're done.
EDIT:
Oh, a lunch can reside in two bags at once. So it's n^k. The shortest way would be to use the LINQ cross join suggested above, but it feels a little like cheating. Instead, just create an integer array of K elements, fill it with zeroes, and started adding one to the rightmost element. When you it gets to N, reset it to zero and carry the one to the next element. You're just counting K-digit numbers in base-N. After each iteration, you can output the bag assignment.
我有一个方法可以重新创建上面的示例。该方法实际上是将袋子视为数字的位置......因为如果您查看示例,您可以将其读作 11、12、13、21、22、23。然后就是转换为基本 Lunch.Count 的问题。我还从这里偷了一个方法: https://stackoverflow.com/a/95331/483179 转换为任何基数有人提到它未经测试,因此您可能必须构建更强大的东西。最后我没有做任何边缘条件测试,所以喂入 0 个袋子可能会产生意想不到的结果。这是我想出的。
以及结果输出:
I have a method that recreates your example above. The approach is actually to think of the bags as positions of a number... for if you look at your example you could read it as 11, 12,13,21,22,23. Then it's a matter of converting to base Lunch.Count. Also I stole a method from here: https://stackoverflow.com/a/95331/483179 to convert to any base which it was mentioned it was untested so you may have to build something more robust. Finally I didn't do any edge condition testing so feeding in 0 bags could have unexpected results. Here is what I came up with.
and the resultant output: