例如,16
的倍数为{(16,1), (2,8), (4,4)}
的对和15
倍的对是{(15,1), (5,3)}
,但我不知道如何构造算法比蛮力好。我的方法看起来像
private static IEnumerable<Tuple<int, int>> Multipliers(int m)
{
var found = new HashSet<int>();
foreach(int v in Enumerable.Range(1, m))
{
int d = m / v;
bool even = m % v == 0;
if(even && found.Contains(d))
{
yield return Tuple.Create(d, v);
}
found.Add(v);
}
}
这是草率的,可能没有那么高效。
答案 0 :(得分:2)
这里有一个示例方法,但我不确定它是否是最有效的一个&#34;本身:
public static IEnumerable<(int A, int B)> Multipliers(int m)
{
yield return (m, 1);
int i = 2;
int lastVal = m / 2;
while (i <= lastVal)
{
if (m % i == 0)
{
lastVal = m / i;
yield return (lastVal, i);
}
i++;
}
}
public static void Main(string[] args)
{
foreach (var pair in Multipliers(16))
{
Console.WriteLine("{0}, {1}", pair.A, pair.B);
}
}
使用C#7元组返回语法,因为我可以。 :P
编辑:从for
循环切换到while
循环以处理m <= 2
时的情况。
编辑2:正如Adwaenyth所建议的,这是一种中等版本的方法,用于检查m
是否均匀。如果没有,那么跳过所有可能的因素。此外,正如其他答案所建议的那样,将迭代限制为m
而不是m/2
的平方根:
public static IEnumerable<(int A, int B)> Multipliers(int m)
{
yield return (m, 1);
int lastVal = (int)Math.Sqrt(m);
int increment = (m % 2 == 0) ? 2 : 1;
int i = (m % 2 == 0) ? 3 : 2;
while (i <= lastVal)
{
if (m % i == 0)
{
lastVal = m / i;
yield return (lastVal, i);
}
i += increment;
}
}
我非常确定这和这种特殊方法一样有效。为了使它更好,你可以调整它以检查所有素数及其倍数,直到m
的平方根。理想情况下,您可以针对查找表执行此操作,因为在生成它们时,通过仅比较素数而节省的大量时间将会丢失。 (对于非常大的m
,它仍然会更快出现。)
编辑3 我发现我之前的代码使用lastVal
使得所需的时间有点不一致,并且引入了一个奇怪的错误,使其有时会忘记检查更大的因素。这是一个应该解决这些问题的更新:
public static IEnumerable<(int A, int B)> Multipliers(int m)
{
yield return (m, 1);
int finalVal = (int)Math.Sqrt(m);
int increment = m % 2 == 0 ? 2 : 1;
int i = m % 2 == 0 ? 3 : 2;
while (i <= finalVal)
{
if (m % i == 0)
{
yield return (m / i, i);
}
i += increment;
}
}
答案 1 :(得分:0)
首先生成一个素数列表,直到输入N的平方根,对于每个素数p检查它是否除N.如果确实那么N = N / p并递归地重复这个,直到列表中的所有素数都有已经筋疲力尽或N / p = 1。
在罕见的情况下,列表中没有素数可以划分输入,那么您的数字是素数。唯一的对是{(1,N),(N,1)}。当您的输入呈指数级增长时,这种情况会变得更加罕见。
对于另一个案例,计算所有主要除数及其出现的次数。最后找到素数的所有组合,直到N的平方根,这将是除N的对的一部分。
答案 2 :(得分:0)
我认为执行此操作的最佳方法是执行素数分解算法。但是你应该注意到这是一个非常困难的数学领域。您可以在http://mathworld.wolfram.com/PrimeFactorizationAlgorithms.html
中找到文章从素数序列中,您可以组合形成给定数字的所有可能对