c#排列组合的问题?

快跑稻草人 2017-08-29 06:55:33
我想对一个List进行排列,比如:
public class Simple
{
public stringName{get;set;}
public int value{get;set;}
}

如果我有一个List<Simple>,如何从中组合出几个组合?要排除value相同的SImple,比如两个Simple中的value相等,就不组合他们,忽略他们,请问该怎么做?
...全文
385 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
xuzuning 2017-08-30
  • 打赏
  • 举报
回复
写简单点就是
            foreach (var x in a.Combination(a.Count(), 3))
            {
                var n = x.Select(p => p.value).Distinct().Count();
                if(n == x.Count()) Console.WriteLine(string.Join(",", x));
            }
        }
快跑稻草人 2017-08-30
  • 打赏
  • 举报
回复
引用 13 楼 xuzuning 的回复:
        static void Main(string[] args)
        {
            var a = new List<Simple>()
            {
                new Simple() {Name="a",value=1},
                new Simple() {Name="b",value=2},
                new Simple() {Name="c",value=1},
                new Simple() {Name="d",value=4},
                new Simple() {Name="a",value=1},
                new Simple() {Name="e",value=3},
                new Simple() {Name="f",value=4},
                new Simple() {Name="g",value=5},
            };
            var q = a.Distinct(p =>p.value);
            Console.WriteLine(string.Join(",", q));

            foreach (var x in q.Combination(q.Count(), 3))
            {
                Console.WriteLine(string.Join(",", x));
            }
        }
可能刚才没说清楚,我给您说一下:
  static void Main(string[] args)
        {
            var a = new List<Simple>()
            {
                new Simple() {Name="a",value=1},
                new Simple() {Name="b",value=2},
                new Simple() {Name="c",value=1},
                new Simple() {Name="d",value=4},
                new Simple() {Name="a",value=1},
                new Simple() {Name="e",value=3},
                new Simple() {Name="f",value=4},
                new Simple() {Name="g",value=5},
            };
            var q = a.Distinct(p =>p.value);
            Console.WriteLine(string.Join(",", q));
 
            foreach (var x in q.Combination(q.Count(), 3))
            {
                Console.WriteLine(string.Join(",", x));
            }
        }
其中
new Simple() {Name="a",value=1}
new Simple() {Name="c",value=1}
不能组合,value相同,但是他俩分别可以和
new Simple() {Name="b",value=2}
组合,您的结果之中,去掉了
 new Simple() {Name="c",value=1}
,这样结果就少掉了。
xuzuning 2017-08-30
  • 打赏
  • 举报
回复
那你就过滤一下
        static void Main(string[] args)
        {
            var a = new List<Simple>()
            {
                new Simple() {Name="a",value=1},
                new Simple() {Name="b",value=2},
                new Simple() {Name="c",value=1},
                new Simple() {Name="d",value=4},
                new Simple() {Name="a",value=1},
                new Simple() {Name="e",value=3},
                new Simple() {Name="f",value=4},
                new Simple() {Name="g",value=5},
            };
            //var q = a.Distinct(p =>p.value);
            //Console.WriteLine(string.Join(",", q));

            foreach (var x in a.Combination(a.Count(), 3))
            {
                var d = new Dictionary<int, int>();
                foreach (var t in x) d[t.value] = 1;
                if(d.Count == x.Count()) Console.WriteLine(string.Join(",", x));
            }
        }
        public class Simple
        {
            public string Name{get;set;}
            public int value{get;set;}
            public override string ToString()
            {
                return string.Format("{{Name:{0} Value:{1}}}", Name, value);
            }
        }
xuzuning 2017-08-30
  • 打赏
  • 举报
回复
        public class Simple
        {
            public string Name{get;set;}
            public int value{get;set;}
            public override string ToString()
            {
                return string.Format("{{Name:{0} Value:{1}}}", Name, value);
            }
        }
xuzuning 2017-08-30
  • 打赏
  • 举报
回复
        static void Main(string[] args)
{
var a = new List<Simple>()
{
new Simple() {Name="a",value=1},
new Simple() {Name="b",value=2},
new Simple() {Name="c",value=1},
new Simple() {Name="d",value=4},
new Simple() {Name="a",value=1},
new Simple() {Name="e",value=3},
new Simple() {Name="f",value=4},
new Simple() {Name="g",value=5},
};
var q = a.Distinct(p =>p.value);
Console.WriteLine(string.Join(",", q));

foreach (var x in q.Combination(q.Count(), 3))
{
Console.WriteLine(string.Join(",", x));
}
}
快跑稻草人 2017-08-30
  • 打赏
  • 举报
回复
引用 11 楼 xuzuning 的回复:
我没说如何做组合 我是说:只要原始数据是唯一的,结果就不会有重复 我给的代码只是完成求组合前得数据准备工作 求组合的算法很多,推荐这样写
        public static IEnumerable<IEnumerable<TValue>> Combination<TValue>(
            this IEnumerable<TValue> values,
            Int32 count,
            Int32 num)
        {
            var t = Enumerable.Range(0, num).ToList();
            do
            {
                yield return values.Where((x, i) => t.Contains(i));
            }
            while (NextCombination(t, count, num));
        }
        public static bool NextCombination(List<int> ar, int num, int k)
        {
            if (ar.Count() != k) ar = Enumerable.Range(0, k).ToList();
            bool changed = false, finished = false;
            if (k > 0)
            {
                for (int i = k - 1; !changed && !finished; i--)
                {
                    if (ar[i] < (num - 1) - (k - 1) + i)
                    {
                        ar[i]++;
                        if (i < k - 1)
                        {
                            for (int j = i + 1; j < k; j++)
                            {
                                ar[j] = ar[j - 1] + 1;
                            }
                        }
                        changed = true;
                    }
                    finished = (i == 0);
                }
            }
            return changed;
        }
    }
原始数据如果去掉重复的就会少结果,a,b,c三个,a=b,a可以和c组合,b和c组合,但是去掉ab之中的一个,就只有ac,或者bc,就会少一个结果,这样是不行的。
xuzuning 2017-08-30
  • 打赏
  • 举报
回复
我没说如何做组合 我是说:只要原始数据是唯一的,结果就不会有重复 我给的代码只是完成求组合前得数据准备工作 求组合的算法很多,推荐这样写
        public static IEnumerable<IEnumerable<TValue>> Combination<TValue>(
            this IEnumerable<TValue> values,
            Int32 count,
            Int32 num)
        {
            var t = Enumerable.Range(0, num).ToList();
            do
            {
                yield return values.Where((x, i) => t.Contains(i));
            }
            while (NextCombination(t, count, num));
        }
        public static bool NextCombination(List<int> ar, int num, int k)
        {
            if (ar.Count() != k) ar = Enumerable.Range(0, k).ToList();
            bool changed = false, finished = false;
            if (k > 0)
            {
                for (int i = k - 1; !changed && !finished; i--)
                {
                    if (ar[i] < (num - 1) - (k - 1) + i)
                    {
                        ar[i]++;
                        if (i < k - 1)
                        {
                            for (int j = i + 1; j < k; j++)
                            {
                                ar[j] = ar[j - 1] + 1;
                            }
                        }
                        changed = true;
                    }
                    finished = (i == 0);
                }
            }
            return changed;
        }
    }
threenewbee 2017-08-30
  • 打赏
  • 举报
回复
if (obj1.Value != obj2.Value) //组合
weixin_38102860 2017-08-30
  • 打赏
  • 举报
回复
学习了。。。。。
快跑稻草人 2017-08-30
  • 打赏
  • 举报
回复
引用 2 楼 ilikeff8 的回复:
你到底是要排序还是要求组合
组合,像数学中的C
快跑稻草人 2017-08-30
  • 打赏
  • 举报
回复
引用 7 楼 xuzuning 的回复:
当然,Distinct 方法是需要扩展一下的
    public class CommonEqualityComparer<T, V> : IEqualityComparer<T>
    {
        private Func<T, V> keySelector;

        public CommonEqualityComparer(Func<T, V> keySelector)
        {
            this.keySelector = keySelector;
        }

        public bool Equals(T x, T y)
        {
            return EqualityComparer<V>.Default.Equals(keySelector(x), keySelector(y));
        }

        public int GetHashCode(T obj)
        {
            return EqualityComparer<V>.Default.GetHashCode(keySelector(obj));
        }
    } 

    public static class DistinctExtensions
    {
        public static IEnumerable<T> Distinct<T, V>(this IEnumerable<T> source, Func<T, V> keySelector)
        {
            return source.Distinct(new CommonEqualityComparer<T, V>(keySelector));
        }
    } 
不一定是组合2个,也可能是组合3个或者4个,从a中选择3个组合,所有可能的组合
xuzuning 2017-08-30
  • 打赏
  • 举报
回复
当然,Distinct 方法是需要扩展一下的
    public class CommonEqualityComparer<T, V> : IEqualityComparer<T>
    {
        private Func<T, V> keySelector;

        public CommonEqualityComparer(Func<T, V> keySelector)
        {
            this.keySelector = keySelector;
        }

        public bool Equals(T x, T y)
        {
            return EqualityComparer<V>.Default.Equals(keySelector(x), keySelector(y));
        }

        public int GetHashCode(T obj)
        {
            return EqualityComparer<V>.Default.GetHashCode(keySelector(obj));
        }
    } 

    public static class DistinctExtensions
    {
        public static IEnumerable<T> Distinct<T, V>(this IEnumerable<T> source, Func<T, V> keySelector)
        {
            return source.Distinct(new CommonEqualityComparer<T, V>(keySelector));
        }
    } 
xuzuning 2017-08-30
  • 打赏
  • 举报
回复
        static void Main(string[] args)
{
var a = new List<Simple>()
{
new Simple() {Name="a",value=1},
new Simple() {Name="b",value=2},
new Simple() {Name="c",value=1},
new Simple() {Name="d",value=4},
};
var q = a.Distinct(p =>p.value);
foreach (var x in q)
{
Console.WriteLine("Name:{0}, value:{1}", x.Name, x.value);
}
}
constanline 2017-08-30
  • 打赏
  • 举报
回复
组合是指什么,把两个不同的Simple合成一个List还是别的什么?
xuzuning 2017-08-30
  • 打赏
  • 举报
回复
先过滤掉 value相等的元素
sinat_34574433 2017-08-30
  • 打赏
  • 举报
回复
楼上太高级了 哈哈 对于初学者就开始搞lambda是挺费解的。这个问题简化下,就是个数组组合的问题,让Simple实现IComparable,实现比较的那个方法,就可以把这个对象当作数值对待了。数值求全组合的算法 百度一下一大堆。
快跑稻草人 2017-08-30
  • 打赏
  • 举报
回复
引用 17 楼 xuzuning 的回复:
写简单点就是
            foreach (var x in a.Combination(a.Count(), 3))
            {
                var n = x.Select(p => p.value).Distinct().Count();
                if(n == x.Count()) Console.WriteLine(string.Join(",", x));
            }
        }
表示看不懂
ilikeff8 2017-08-29
  • 打赏
  • 举报
回复
你到底是要排序还是要求组合
nry19871012 2017-08-29
  • 打赏
  • 举报
回复
搜一搜 lambda表达式

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧