【问题标题】:Linq Union/UnionAll/ConcatLinq Union/UnionAll/Concat
【发布时间】:2024-01-08 05:29:01
【问题描述】:

我正在尝试将一段简单的数学转换为 Linq。

我想将几个数字的主要因素捆绑到一个集合中。 考虑以下整数。

8 = 2 * 2 * 2
12 = 2 * 2 * 3

能被 8 和 12 整除的最小数是 24,所以我希望结果组包含

{ 2, 2, 2, 3 }

如果我使用 Concat,结果是 {2,2,2,2,2,3} - 不正确 如果我使用 Union 结果是 {2,3} - 不正确

是否有一个内置的 Linq Set Manipulation 函数可以识别它需要保持一个项目的最大出现次数(即,如果已经足够满足,则不要添加另一个,如果没有,则添加另一个)

【问题讨论】:

    标签: c# linq math set factorization


    【解决方案1】:

    嗯,它不是任何现有的功能,因为我认为不存在,但是非常简单的代码能够处理这个:

            var listA = new List<int> {2, 2, 2};
            var listB = new List<int> {2, 2, 3};
    
            var grouppedA = listA.GroupBy(i => i).Select(g => new { key = g.Key, count = g.Count()});
            var grouppedB = listB.GroupBy(i => i).Select(g => new { key = g.Key, count = g.Count()});
            var result = grouppedA
                .Union(grouppedB)
                .GroupBy(g => g.key)
                .SelectMany(g => Enumerable.Repeat(g.Key, g.Max(h => h.count)));
    
            foreach (int i in result)
            {
                Console.Write(i + " ");
            }
            Console.ReadKey();
    

    输出: 2 2 2 3

    【讨论】:

    • 是的,这与我想出的非常相似,但仍然非常冗长。为帮助喝彩。如果没有其他人回复,会给你+10。
    • 是的,不幸的是。它应该以某种辅助方法关闭,以便于阅读。我认为没有更高级别的 linq 解决方案,因为您的问题不是很常见。代码可能会写得更好,更易读
    【解决方案2】:
    using System;
    using System.Collections.Generic;
    
    public class Sample {
        public static void Main(String[] args) {
            var n8  = toFactors(8);
            var n12 = toFactors(12);
            var uf = unionFactors(n8, n12);//LCM
            printFactors(uf);
        }
        public static void printFactors(Dictionary<long, int> factors){
            Console.Write("{ ");
            foreach(var factor in factors.Keys){
                for(int i=0;i<factors[factor];++i)
                    Console.Write( factor + " ");
            }
            Console.WriteLine("}");
        }
        public static Dictionary<long, int> unionFactors(Dictionary<long, int> af, Dictionary<long, int> bf){
            Dictionary<long, int> uf = new Dictionary<long, int>();
            foreach(var kv in af){
                uf.Add(kv.Key, kv.Value);//copy
            }
            foreach(var kv in bf){
                if(uf.ContainsKey(kv.Key)){
                    if(kv.Value > uf[kv.Key])//max
                        uf[kv.Key] = kv.Value;
                } else {
                    uf.Add(kv.Key, kv.Value);
                }
            }
            return uf;
        }
        public static Dictionary<long, int> toFactors(long num){
            var factors = new Dictionary<long, int>();
            long n = num, i = 2, sqi = 4;
            while(sqi <= n){
                while(n % i == 0){
                    n /= i;
                    if(factors.ContainsKey(i)){
                        factors[i] += 1;
                    } else {
                        factors.Add(i, 1);
                    }
                }
                sqi += 2 * (i++) + 1;
            }
            if(n != 1 && n != num){
                if(factors.ContainsKey(i)){
                    factors[i] += 1;
                } else {
                    factors.Add(i, 1);
                }
            }
            if(factors.Count == 0)
                factors.Add(num, 1);//prime
            return factors;
        }
    }
    

    【讨论】:

    • 我认为成为 LINQ 是多余的。