C# 求一个数的因子
我正试图重构这个算法,使其更快。为了提高速度,这里的第一次重构是什么C# 求一个数的因子,c#,performance,math,factors,C#,Performance,Math,Factors,我正试图重构这个算法,使其更快。为了提高速度,这里的第一次重构是什么 public int GetHowManyFactors(int numberToCheck) { // we know 1 is a factor and the numberToCheck int factorCount = 2; // start from 2 as we know 1 is a factor, and less than as numberToC
public int GetHowManyFactors(int numberToCheck)
{
// we know 1 is a factor and the numberToCheck
int factorCount = 2;
// start from 2 as we know 1 is a factor, and less than as numberToCheck is a factor
for (int i = 2; i < numberToCheck; i++)
{
if (numberToCheck % i == 0)
factorCount++;
}
return factorCount;
}
public int GetHowManyFactors(int numberToCheck)
{
//我们知道1是一个因子,数字是一个校验
整数因子计数=2;
//从2开始,我们知道1是一个因子,小于numberToCheck是一个因子
对于(int i=2;i
减少你必须达到的高度的界限,因为你可以故意停在数字的平方根处,尽管这确实需要谨慎地挑选出具有奇数因子的正方形,但是它确实有助于减少循环的执行频率。您可以进行的第一个优化是,您只需要检查数字的平方根。这是因为因子成对出现,其中一个小于平方根,另一个大于平方根
一个例外是,如果n
是一个精确的平方,那么它的平方根是n
的一个因子,但不是一对的一部分
例如,如果您的数字为30,则系数为以下几对:
- 1 x 30
- 2 x 15
- 3 x 10
- 5 x 6
public int GetFactorCount(int numberToCheck)
{
整数因子计数=0;
intsqrt=(int)Math.天花(Math.sqrt(numberToCheck));
//从1开始,因为我们希望我们的方法在numberToCheck为0或1时也能工作。
对于(int i=1;i
您还可以使用其他更快的方法,但您可能会发现,这已经足够满足您的需要,特别是当您只需要它来处理32位整数时
public int GetHowManyFactors(int numberToCheck)
{
// we know 1 is a factor and the numberToCheck
int factorCount = 2;
int i = 2 + ( numberToCheck % 2 ); //start at 2 (or 3 if numberToCheck is odd)
for( ; i < numberToCheck / 2; i+=2)
{
if (numberToCheck % i == 0)
factorCount++;
}
return factorCount;
}
public int GetHowManyFactors(int numberToCheck)
{
//我们知道1是一个因子,数字是一个校验
整数因子计数=2;
int i=2+(numberToCheck%2);//从2开始(如果numberToCheck为奇数,则从3开始)
对于(;i
看起来这里有一个关于这个主题的冗长讨论:
希望这对你有帮助,如果你打算经常使用这个函数,你可以使用修改后的埃拉托斯涅斯算法,在数组中以1到最大的间隔存储answars。它将运行initializearray()一次,然后在0(1)中返回答案
const int Max=1000000;
int arr[]=新int[Max+1];
公共无效初始值设定项array()
{
对于(int i=1;i首先要注意的是,找到所有的素数因子就足够了。一旦有了这些因子,就很容易找到总因子的数目:对于每个素数,在它出现的次数上加1,然后将它们相乘。因此对于12=2*2*3,就有(2+1)*(1+1)=3*2=6个因子
接下来的事情从第一个方面开始:当你找到一个因子时,把它划分出来,这样得到的数字就更小了。当你把它与你只需要检查当前数的平方根的事实结合起来时,这是一个巨大的改进。例如,考虑n=10714293844487412。天真地,它需要N个步骤。平方根需要sqrt(N)或大约1亿步。但是由于因子2、2、3和953在早期就被发现了,所以实际上只需要检查到100万步——100倍的改进
另一个改进:你不需要检查每个数字,看它是否能将你的数字除,只需检查素数。如果更方便的话,你可以使用2和奇数,或者2、3和数字6n-1和6n+1(一种基本的轮筛)
这是另一个很好的改进。如果你能快速确定一个数字是否为素数,你可以进一步减少除法的需要。假设在去掉小因子后,你有120528291333090808192969。即使检查它的平方根也需要很长时间——3000亿步。但是米勒-拉宾测试(非常快——可能10到20纳秒)将显示这个数字是复合的。这有什么帮助?这意味着如果你查到它的立方根,没有发现任何因子,那么只剩下两个素数。如果这个数字是平方的,它的因子是素数;如果这个数字不是平方的,这些数是不同的素数。这意味着你可以将你的“运行总数”乘以3或4,r特别是,要得到最终的答案——即使不知道因素!这比你想象的要大得多:所需的步骤数从3000亿减少到5000万,这是6000倍的改进
上面提到的唯一问题是,Miller Rabin只能证明数字是复合的;如果给它一个素数,它就不能证明这个数字是素数。在这种情况下,你可能希望编写一个素数证明函数来省去分解数字平方根的工作。(或者,如果你对自己的答案是正确的信心很高,而不是证明答案是正确的,你可以再做几次米勒-拉宾测试。如果一个数字通过15次测试,那么它的合成概率小于十亿分之一。)一个易于实现的算法,它将
public int GetHowManyFactors(int numberToCheck)
{
// we know 1 is a factor and the numberToCheck
int factorCount = 2;
int i = 2 + ( numberToCheck % 2 ); //start at 2 (or 3 if numberToCheck is odd)
for( ; i < numberToCheck / 2; i+=2)
{
if (numberToCheck % i == 0)
factorCount++;
}
return factorCount;
}
const int Max =1000000;
int arr [] = new int [Max+1];
public void InitializeArray()
{
for(int i=1;i<=Max;++i)
arr[i]=1;//1 is factor for everyone
for(int i=2;i<=Max;++i)
for(int j=i;i<=Max;i+=j)
++arr[j];
}
public int GetHowManyFactors(int numberToCheck)
{
return arr[numberToCheck];
}
public int solution(int n) {
var counter = 0;
if (n == 1) return 1;
counter = 2; //1 and itself
int sqrtPoint = (Int32)(Math.Truncate(Math.Sqrt(n)));
for (int i = 2; i <= sqrtPoint; i++)
{
if (n % i == 0)
{
counter += 2; // We found a pair of factors.
}
}
// Check if our number is an exact square.
if (sqrtPoint * sqrtPoint == n)
{
counter -=1;
}
return counter;
}
def solution(N):
"""
Problem Statement can be found here-
https://app.codility.com/demo/results/trainingJNNRF6-VG4/
Codility 100%
Idea is count decedent factor in single travers. ie. if 24 is divisible by 4 then it is also divisible by 8
Traverse only up to square root of number ie. in case of 24, 4*4 < 24 but 5*5!<24 so loop through only i*i<N
"""
print(N)
count = 0
i = 1
while i * i <= N:
if N % i == 0:
print()
print("Divisible by " + str(i))
if i * i == N:
count += 1
print("Count increase by one " + str(count))
else:
count += 2
print("Also divisible by " + str(int(N / i)))
print("Count increase by two count " + str(count))
i += 1
return count
if __name__ == '__main__':
# result = solution(24)
# result = solution(35)
result = solution(1)
print("")
print("Solution " + str(result))
if (N == 1) return 1;
int divisors = 0;
int max = N;
for (int div = 1; div < max; div++) {
if (N % div == 0) {
divisors++;
if (div != N/div) {
divisors++;
}
}
if (N/div < max) {
max = N/div;
}
}
return divisors;