使用LINQ找出给定一系列素数因子的数的除数

时间:2010-01-04 21:10:53

标签: c# .net linq math

给定一个自然数的素数因子数组,如何在原始数组上找到使用LINQ的除数总数?我已经找到了大部分问题,但是我我的LINQ声明出了问题。


数学背景:

数字的素数因子是素数整数,它们均匀地分配给没有余数的数字。例如60的主要因素是2,2,3,5。

数字的除数都是整数(素数或其他),它们均匀分配给数字而没有余数。 60的除数是1,2,3,4,5,6,10,12,15,20,30,60。

我有兴趣找到除数的总数。 60的除数总数为12。

让我们用指数来表达素数分解:

60 = 2^2 * 3^1 * 5*1

要找到给定数字因子化的除数的总数,我们要做的就是为每个指数加1,然后将这些数加在一起,如下所示:

(2 + 1) * (1 + 1) * (1 + 1) = 12;

这就是你如何找到一个数字的素数因子化的除数的数量。

我迄今为止的守则:

我已经有了很好的代码来获取数字的素数因子,所以我并不关心。 使用LINQ ,我想弄清楚除数的总数是多少。我可以使用几个循环,但我正在尝试使用LINQ(如果可能的话)。

我要去:

  • 使用Distinct()查找数组中的唯一值。
  • 使用Count()查找唯一值出现的时间(这等于指数)。
  • 使用Aggregate()函数将值相乘。

这是我的代码:

class Program
{
    static void Main(string[] args)
    {
        var primeFactors = new int[] { 2, 2, 3, 5 };
        Console.WriteLine(primeFactors.Distinct().PrintList("", ", "));
            //Prints: 2, 3, 5
        Console.WriteLine("[2]:{0} [3]:{1} [5]:{2}"
            , primeFactors.Count(x => x == 2)
            , primeFactors.Count(x => x == 3)
            , primeFactors.Count(x => x == 5)
            );
            //Prints: [2]:2 [3]:1 [5]:1

\\THIS IS WHERE I HAVE TROUBLE:

        Console.WriteLine(primeFactors.Distinct().Aggregate((total,next) =>  
            (primeFactors.Count(x => x ==next) + 1)* total));
            //Prints: 8


        Console.ReadLine();
    }
}

特别是,我遇到了这部分代码的问题:

primeFactors.Distinct().Aggregate((total,next) =>  
    (primeFactors.Count(x => x ==next) + 1)* total)

由于我的数组中的数字不是以x^n的形式存储,而是以数组中n x个实例的形式存储,我的想法是使用{ {1}}在Count()的不同数组中查找n应该是什么。 x函数用于遍历数组中的每个不同项,找到它的Aggregate + 1,然后将其乘以总数。 Count中的lambda表达式应该使用每个不同的数字作为参数(Count)。

上面的代码应该返回12,但是它会返回8.我在调试模式下无法“单步执行”LINQ,我无法弄清楚如何更好地编写它。

为什么我的代码中的那部分没有像我预期的那样返回正确数量的除数?是否有一种不同(更好)的方式来表达这种使用LINQ?

2 个答案:

答案 0 :(得分:4)

试试这个:

int[] factors = new int[] { 2, 2, 3, 5 };
var q = from o in factors
        group o by o into g
        select g.Count() + 1;
var r = q.Aggregate((x, y) => x * y);

您建议的查询的具体问题是您的聚合调用无法计算第一个元素(更不用说不会将计数增加1)。它错误地做的是取第一个因子并将其而不是其计数+ 1与下一个因子相乘。

答案 1 :(得分:2)

如果我了解您要执行的操作,则可能需要使用GroupBy()

var primeFactors = new int[]{ 2, 2, 3, 5 };
var numFacs = primeFactors.GroupBy(f => f, f => f, (g, s) => s.Count() + 1)
                          .Aggregate(1, (x, y) => x * y);