代码之家  ›  专栏  ›  技术社区  ›  Echostorm

找到给定数字的所有因子的最佳方法

  •  30
  • Echostorm  · 技术社区  · 16 年前

    所有等分为x的数字。

    编辑:我知道这听起来像是家庭作业。我正在编写一个小应用程序,用半随机测试数据填充一些产品表。其中两个属性是ItemMaximum和Item乘数。我需要确保乘数不会造成不合逻辑的情况,即多购买一件商品会使订单超出允许的最大值。因此,这些系数将给出测试数据的有效值列表。

    这就是在所有人的帮助下我所做的。再次感谢!

    编辑#:我写了3个不同的版本,看看我更喜欢哪一个,并测试了它们对小数字和非常大的数字的分解。我将粘贴结果。

    static IEnumerable<int> GetFactors2(int n)
    {
        return from a in Enumerable.Range(1, n)
                      where n % a == 0
                      select a;                      
    }
    
    private IEnumerable<int> GetFactors3(int x)
    {            
        for (int factor = 1; factor * factor <= x; factor++)
        {
            if (x % factor == 0)
            {
                yield return factor;
                if (factor * factor != x)
                    yield return x / factor;
            }
        }
    }
    
    private IEnumerable<int> GetFactors1(int x)
    {
        int max = (int)Math.Ceiling(Math.Sqrt(x));
        for (int factor = 1; factor < max; factor++)
        {
            if(x % factor == 0)
            {
                yield return factor;
                if(factor != max)
                    yield return x / factor;
            }
        }
    }
    

    将数字分解为20时,每次分解5次:

    • 获取因素1-5445881
    • 获取因素3-2913659

    • 获取因素1-5644457
    • GetFactors2-12117938
    • GetFactors3-3108182
    11 回复  |  直到 7 年前
        1
  •  0
  •   Nima Ghomri    3 年前

    • 循环从1到数字的平方根,调用索引“i”。
    • 如果数字mod i为0,则将i和数字/i添加到因子列表中。

    realocode:

    public List<int> Factor(int number) 
    {
        var factors = new List<int>();
        int max = (int)Math.Sqrt(number);  // Round down
    
        for (int factor = 1; factor <= max; ++factor) // Test from 1 to the square root, or the int below it, inclusive.
        {  
            if (number % factor == 0) 
            {
                factors.Add(factor);
                if (factor != number/factor) // Don't add the square root twice!  Thanks Jon
                    factors.Add(number/factor);
            }
        }
        return factors;
    }
    

    正如Jon Skeet提到的,您可以将其作为 IEnumerable<int> 以及-使用 yield 而不是添加到列表中。优势 List<int> 如果需要,可以在返回之前对其进行排序。然后,您可以使用混合方法得到一个排序的枚举数,生成第一个因子并在循环的每次迭代中存储第二个因子,然后生成以相反顺序存储的每个值。

    您还需要做一些事情来处理将负数传递到函数中的情况。