有一个 值
List<List<string>> l=new List<List<string>>();
l.Add(new List<string>(new string[] {"1", "5", "6", "7", "8", "9" }));//6个元素
l.Add(new List<string>(new string[] { "1", "5", "6", "7", "8"}));//5个元素
l.Add(new List<string>(new string[] { "5"}));
...省略多个
要求,对 l 进行全组合,并且组合后,每个组合 元素个数不能超过10,例如 l[0] 和 l[1]组合后,元素是 11,就不合格!
求算法!性能要好!!!!
1、对l的元素的子元素长度排序
2、优先对子元素数量满足匹配条件的最多和最少的子元素集合进行组合
3、重复以上循环。
这个算法不是最优的。
最优的算法应该是:对所有子元素长度进行组合,使得组合之后的长度刚好是10。
兄弟,怎么写。。。我研究一下
@☆绿茶☆: 下面代码给你参考(未验证):
List<List<string>> l = new List<List<string>>(); l.Add(new List<string>(new string[] { "1", "5", "6", "7", "8", "9" }));//6个元素 l.Add(new List<string>(new string[] { "1", "5", "6", "7", "8" }));//5个元素 l.Add(new List<string>(new string[] { "5" })); Func<List<List<string>>, List<List<string>>, List<List<string>>> funcCombine = (source, dest) => { var groups = source.GroupBy(x => x.Count, x => x).OrderByDescending(x => x.Key).ToList(); List<List<string>> tmp = new List<List<string>>(); groups.Where(x => x.Key >= 10).ToList().ForEach(x => { groups.Remove(x); dest.Add(x as List<string>); }); for (int i = 10; i >= 5; i--) { foreach (var group in groups.Where(x => (x as List<string>).Count > 0)) { var key = group.Key; var sub = groups.Where(x => x.Key + key == i).SingleOrDefault(); if (sub != null) { for (int j = 0; i < Math.Min(key, sub.Key); j++) { var left = group.First(); var right = sub.First(); var combine = new List<string>(left); combine.AddRange(right); (group as List<List<string>>).Remove(left); (sub as List<List<string>>).Remove(right); tmp.Add(combine); } } } } if (tmp.Count > 0) { foreach (var group in groups) { tmp.AddRange(group); } } else { foreach (var group in groups) { dest.AddRange(group); } } return tmp; }; var result = new List<List<string>>(); List<List<string>> current; while((current = funcCombine(l, result)).Count > 0);
@519740105: 额,看来我水平不够,我写习惯2.0的,还有并不是 一定要等于10 小于10也是可以的。。。我研究一下,非常谢谢你!
@☆绿茶☆: 你参考就好。这个性能不好。
static void Main(string[] args)
{
List<List<string>> l = new List<List<string>>();
//
//给l添加元素
//
for (int x = 0; x < l.Count; x++)
{
for (int y = x + 1; y < l.Count; y++)
{
if (l[x].Count + l[y].Count > 10)
{
Console.WriteLine("不合格");
}
}
}
}
兄弟,你这是干嘛。。。。好像答非所问
@☆绿茶☆: 把算法写出来了啊。
@Firen: 兄弟,你这不对。。。。
@☆绿茶☆: 对不对拿实际数据测一下不就清楚了。
@Firen: 兄弟,谢谢你,确实不对,不好意思
@☆绿茶☆: 你说的全组合是两两组合还是包括两个以上元素的组合?
@Firen: 所有的组合,不重复,也就是数学上面的 c(m,n)
@☆绿茶☆: 建議你看下Firen的思路,個人覺得是正確的思路。雙重循環就行全部組合。
@☆绿茶☆: c(m,n) 你n取值多少呢? 我的写法是c(m,2)
@Firen: c(m,2)你这样写可以,但是有一个问题,这个样写性能可能不行,太慢了。。。。我做出来了,但是计算一次要80多秒,c(42,10);
谢谢,我自己换了种方式实现了!