Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 求给定整数的所有精确因子的算法_C_Algorithm_Numbers_Performance_Factors - Fatal编程技术网

C 求给定整数的所有精确因子的算法

C 求给定整数的所有精确因子的算法,c,algorithm,numbers,performance,factors,C,Algorithm,Numbers,Performance,Factors,我想找到一个数的所有精确除数。 目前我有: { int n; int i=2; scanf("%d",&n); while(i<=n/2) { if(n%i==0) printf("%d,",i); i++; } getch(); } { int n; int i=2; scanf(“%d”和“&n”); 而(i首先,你的代码应该具有i的条件。简单的线性搜索可以通过

我想找到一个数的所有精确除数。 目前我有:

{
   int n;
   int i=2;
   scanf("%d",&n);
   while(i<=n/2)
    {
        if(n%i==0)
                  printf("%d,",i);
        i++;
     }
   getch();
}
{
int n;
int i=2;
scanf(“%d”和“&n”);

而(i首先,你的代码应该具有
i的条件。简单的线性搜索可以通过首先抛出2的所有因子来改进。这可以通过简单的位移位或使用一个很好的内在函数计数训练零来完成。这两种情况下都非常快。然后运行shg建议的算法(这将运行得更快,因为2的幂不存在),并将结果与2的所有可能幂结合起来(不要忘记这一步)。这对有大量训练零的输入有很大帮助,但如果没有,甚至会有帮助-你不必再测试任何偶数除数,因此循环长度变为原来的一半

扔掉一些常量低因子(但大于2)也会有所帮助。编译器几乎肯定会优化带有常量的模(如果没有,您可以自己优化),但更重要的是,这意味着剩下的测试因子更少。别忘了将该因子与您找到的因子结合起来


您还可以完全分解数字(使用您最喜欢的算法-可能最好是Pollard的Rho),然后打印所有产品(空产品和完整产品除外)对于较大的输入,这很有可能会更快——与简单的线性搜索相比,Pollard的Rho算法查找因子的速度非常快,通常因子少于适当的除数,最后一步(枚举乘积)只涉及快速数学(无除法)。这对因子非常小的数字最有帮助,Rho找到的最快。

使用C中的“查找所有素数因子”查找所有除数(更快) 最多18位

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

unsigned int FindDivisors(unsigned long long divisors[], unsigned long long N) {
    unsigned int lastdiv = 0;
    divisors[lastdiv++] = 1;
    unsigned long long powerfactor = 1;
    unsigned long long number = N;
    while ((number & 1) == 0) {
        powerfactor <<= 1;
        divisors[lastdiv++] = powerfactor;
        number >>= 1;
    }

    unsigned long long factor = 3; unsigned long long upto = lastdiv;
    powerfactor = 1;
    while (factor * factor <= number) {
        if (number % factor == 0) {
            powerfactor *= factor;
            for (unsigned int i = 0; i < upto; i++)
                divisors[lastdiv++] = divisors[i] * powerfactor;
            number /= factor;
        }
        else {
            factor += 2; upto = lastdiv;
            powerfactor = 1;
        }
    }

    if (number > 1) {
        if (number != factor) {
            upto = lastdiv;
            powerfactor = 1;
        }
        powerfactor *= number;
        for (unsigned int i = 0; i < upto; i++)
            divisors[lastdiv++] = divisors[i] * powerfactor;
    }
    return lastdiv;
}

int cmp(const void *a, const void *b) {
    if( *(long long*)a-*(long long*)b < 0 ) return -1;
    if( *(long long*)a-*(long long*)b > 0 ) return 1;
    return 0;
}

int main(int argc, char *argv[]) {
    unsigned long long N = 2;
    unsigned int Ndigit = 1;
    if (argc > 1) {
        N = strtoull(argv[1], NULL, 10);
        Ndigit = strlen(argv[1]);
    }
    unsigned int maxdiv[] = {1, 4, 12, 32, 64, 128, 240, 448, 768, 1344,
                             2304, 4032, 6720, 10752, 17280, 26880, 41472, 64512, 103680};

    unsigned long long divisors[maxdiv[Ndigit]];
    unsigned int size = FindDivisors(divisors, N);
    printf("Number of divisors = %u\n", size);

    qsort(divisors, size, sizeof(unsigned long long), cmp);
    for (unsigned int i = 0; i < size; i++)
        printf("%llu ", divisors[i]);
    printf("\n");

    return 0;
}
#包括
#包括
#包括
#包括
无符号整型findDivisor(无符号长除数[],无符号长N){
无符号int-lastdiv=0;
除数[lastdiv++]=1;
无符号长功率因数=1;
无符号长数=N;
而((数字&1)==0){
功率因数=1;
}
无符号长-长因子=3;无符号长-长-高达=lastdiv;
功率因数=1;
而(系数*系数1){
如果(数字!=系数){
upto=最后一个div;
功率因数=1;
}
功率因数*=数字;
for(无符号整数i=0;i0,则返回1;
返回0;
}
int main(int argc,char*argv[]){
无符号长N=2;
无符号整数Ndigit=1;
如果(argc>1){
N=strtoull(argv[1],NULL,10);
Ndigit=strlen(argv[1]);
}
无符号整数maxdiv[]={1,4,12,32,64,128,240,448,768,1344,
2304, 4032, 6720, 10752, 17280, 26880, 41472, 64512, 103680};
无符号长除数[maxdiv[Ndigit]];
无符号整数大小=findDivisor(除数,N);
printf(“除数=%u\n”,大小);
qsort(除数,大小,sizeof(无符号长),cmp);
for(无符号整数i=0;i
其中一个答案中的代码有一个错误,乍一看很难看出。如果sqrt(n)是一个有效的除数;但n不是一个完美的平方数,则忽略两个结果

例如,尝试
n=15
,看看会发生什么;
sqrt(15)=3
,因此while循环的最后一个值是2。如果(i*i==n)
执行的下一条语句将作为
如果(3*3==15)
执行。因此3没有列为除数,也遗漏了5

下面将正确处理正整数的一般情况

 {
   int n;
   int i=2;
   scanf("%d",&n);
   while(i <= sqrt(n))
    {
        if(n%i==0) {
            printf("%d,",i);
            if (i != (n / i)) {
                printf("%d,",n/i);
            }
        } 

        i++;
    }
   getch();
}
{
int n;
int i=2;
scanf(“%d”和“&n”);
而(i
int count=2;
//长childsum=0;
long _originalvalue=和;
股息=“1”;
对于(int i=2;i
当给定的数字是奇数时,我们可以跳过偶数。 接受的代码中的一点即兴创作:)

这里是查找给定数字的因子的Java代码

import java.util.Scanner;
public class Factors {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int t=scanner.nextInt();
        while(t-- > 0) {
            int n = scanner.nextInt();
            if(n % 2 == 0) {
                for(int i = 1; i <= Math.sqrt(n); i++) {
                    if(n % i == 0) {
                        System.out.println(i + ", ");
                        if(i != n/i) {
                            System.out.println(n/i + ", ");
                        }
                    }
                }
            }
            else {
                for(int i = 1; i <= Math.sqrt(n); i=i+2) {
                    if(n % i == 0) {
                        System.out.println(i + ", ");
                        if(i != n/i) {
                            System.out.println(n/i + ", ");
                        }
                    }
                }
            }
        }
    }
}
import java.util.Scanner;
公共阶级因素{
公共静态void main(字符串[]args){
扫描仪=新的扫描仪(System.in);
int t=scanner.nextInt();
而(t-->0){
int n=scanner.nextInt();
如果(n%2==0){
对于(inti=1;i这是我的新C#版本。多亏了Rndm,它比我第一次尝试快了近50倍

public static long GetDivisors(long number)
    {
        long divisors = 0;

        long boundary = (long)Math.Sqrt(number);

        for (int i = 1; i <= boundary; i++)
        {
            if (number % i == 0)
            {
                divisors++;
                if(i != (number / i))
                {
                    if (i * i != number)
                    {
                        divisors++;
                    }
                }
            }
        }

        return divisors;
    }
公共静态长getdivisions(长数字)
{
长除数=0;
长边界=(长)数学.Sqrt(数字);

对于(int i=1;i您可以将
printf(“%d,”,i);printf(“%d,”,n/i);
更改为
printf(“%d,”,i);如果(i!=n/i){printf(“%d,”,n/i);}
,对于完美正方形,它不会打印两次根。您可以通过迭代
in/i!=i进行多次检查
,这意味着
n/i!=i
,然后将while循环外部的
i=sqrt(n)
作为单边情况进行检查。通过循环sqrt(n)可以找到所有除数的证据是什么仅次?请解释。如何打印?它将打印2和4。您是指1和8不会打印的事实吗?@Rndm-注意
我可以给您一个考试吗
import java.util.Scanner;
public class Factors {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int t=scanner.nextInt();
        while(t-- > 0) {
            int n = scanner.nextInt();
            if(n % 2 == 0) {
                for(int i = 1; i <= Math.sqrt(n); i++) {
                    if(n % i == 0) {
                        System.out.println(i + ", ");
                        if(i != n/i) {
                            System.out.println(n/i + ", ");
                        }
                    }
                }
            }
            else {
                for(int i = 1; i <= Math.sqrt(n); i=i+2) {
                    if(n % i == 0) {
                        System.out.println(i + ", ");
                        if(i != n/i) {
                            System.out.println(n/i + ", ");
                        }
                    }
                }
            }
        }
    }
}
public static long GetDivisors(long number)
    {
        long divisors = 0;

        long boundary = (long)Math.Sqrt(number);

        for (int i = 1; i <= boundary; i++)
        {
            if (number % i == 0)
            {
                divisors++;
                if(i != (number / i))
                {
                    if (i * i != number)
                    {
                        divisors++;
                    }
                }
            }
        }

        return divisors;
    }