Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.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 - Fatal编程技术网

C 求给定数的因子的算法。。最短方法?

C 求给定数的因子的算法。。最短方法?,c,algorithm,C,Algorithm,找出给定数字的因子的最简单、最省时的逻辑是什么。 是否存在基于相同的算法 事实上,我真正的问题是找出给定数量的因素的数量 因此,任何算法,请让我知道这 谢谢。您可以看一看。有大量可用的算法-从简单的试凑到非常复杂的大数算法。看看维基百科,挑一个适合你需要的 下面是一个简短但低效的C#实现,它可以找到素因子的数量。如果您需要因子的数量(不是素因子),则必须存储素因子及其多重性,然后计算因子的数量 var number = 3 * 3 * 5 * 7 * 11 * 11; var numberFa

找出给定数字的因子的最简单、最省时的逻辑是什么。 是否存在基于相同的算法

事实上,我真正的问题是找出给定数量的因素的数量

因此,任何算法,请让我知道这


谢谢。

您可以看一看。

有大量可用的算法-从简单的试凑到非常复杂的大数算法。看看维基百科,挑一个适合你需要的

下面是一个简短但低效的C#实现,它可以找到素因子的数量。如果您需要因子的数量(不是素因子),则必须存储素因子及其多重性,然后计算因子的数量

var number = 3 * 3 * 5 * 7 * 11 * 11;

var numberFactors = 0;
var currentFactor = 2;

while (number > 1)
{
    if (number % currentFactor == 0)
    {
        number /= currentFactor;
        numberFactors++;
    }
    else
    {
        currentFactor++;
    }
}

欧几里德的算法应该足够了

事实上,我真正的问题是找出给定数量的因素的数量

嗯,这是不同的。设
n
为给定的数字

如果
n=p1^e1*p2^e2*…*pk^ek
,其中每个
p
是一个素数,
n
的因子数是
(e1+1)*(e2+1)**(ek+1)
。更多关于这个

因此,找到每个素因子出现的幂就足够了。例如:

read given number in n
initial_n = n
num_factors = 1;
for (i = 2; i * i <= initial_n; ++i) // for each number i up until the square root of the given number
{
    power = 0; // suppose the power i appears at is 0
    while (n % i == 0) // while we can divide n by i
    {
        n = n / i // divide it, thus ensuring we'll only check prime factors
        ++power // increase the power i appears at
    }
    num_factors = num_factors * (power + 1) // apply the formula
}

if (n > 1) // will happen for example for 14 = 2 * 7
{
    num_factors = num_factors * 2 // n is prime, and its power can only be 1, so multiply the number of factors by 2
}
在我的机器上的结果:

测试等效性…
等价性确认
定时IVlad…
总毫秒数:2448
定时Maciej…
总毫秒数:3951
按任意键继续


以下是我与|/| ad.进行简短讨论的结果:)

读取n中的给定数字
整数除数计数=1;
int i;
对于(i=2;i*i
小心,这个答案对于n的单个值来说是没有用的/快速的

方法1

如果维护一个查找表(用于数字的第一个素数因子),则可以在O(polylog(n))中获得它

如果gcd(a,b)=1,则 a的系数数量*b=(a的系数数量)*(b的系数数量)

因此,对于给定的数字a*b,如果gcd(a,b)!=那么我们可以有另外两个数字p和q,其中p=a和q=b/gcd(a,b)。因此,gcd(p,q)=1。现在,我们可以递归地找到p和q的因子数

只需要少量的努力就可以确保p和q都不是1

另外,当您需要知道从1到n的所有数字的因子数时,此方法也很有用。它的顺序是O(nlogn+O(查找表))

方法2:(我对此没有所有权。)

如果你查找第一个素因子直到n,那么你可以知道它是O(logn)中的所有素因子,从而从中找到因子的数目


p.S.谷歌“logn中的因式分解”以获得更好的解释。

代码或执行时间最短?问题的灵感来自projecteuler问题之一?@Meriton-找到解决方案最短。@Maciej-这是其他问题的子问题。不受任何地方的启发。这个“给定的数字”能有多大?-1欧几里德的算法没有找到整数的因式分解。是的,它找到了。这是一种划分算法,根据定义,它将导致因子。也许他应该指定素因子分解,这是错误的。你算的是什么,因子还是基本因子?这将为18提供3个因子,这两种方法都是错误的。numberFactors计算基本因子,但我的回答指出,因子的数量可以从基本因子及其多重性中得出。你说你的解决方案计算基本因子是错误的
numberFactors
将包含
18
的值
3
,这是错误的,在
18
中只有
2
素数因子:
2和3
。18有三个素数因子-两个和两个三个-但只有两个不同的素数因子。是的,关键是要认识到每个除数都有它的对应项,它足以循环到平方根。然而,如果一个从2循环到平方根,检查每个i是否除以n,计算幂并除以n在我看来是浪费时间。最好只是增加系数的计数器。如果
i
n
的系数,那么
n/i
也是如此。这是另一种方法,也只允许求平方根,只要确保
i
n/i
是不同的,这样你就不会数到两次!但是,这不允许您只检查素数,因此我认为它并不总是更快(使用我发布的方法,您可以预计算素数以使其更快)。例如,对于
20
,您必须检查
4
,以了解
4
5
是您描述的方法中的因素(如果我考虑的是相同的事情)。是的,但您要迭代每个数字,直到
n
的sqrt。我的方法有可能只在素数上迭代。这更容易实现,但可能只有在您不必多次运行它的情况下才更可取。如果您使用Linux,则始终可以使用'factor'命令来获取所有主要因素#无码
 class Program
{
    static private List<int> primes = new List<int>();

    private static void Sieve()
    {
        bool[] ok = new bool[2000];

        for (int i = 2; i < 2000; ++i) // primes up to 2000 (only need up to sqrt of 1 000 000 actually)
        {
            if (!ok[i])
            {
                primes.Add(i);

                for (int j = i; j < 2000; j += i)
                    ok[j] = true;
            }
        }
    }

    private static int IVlad(int n)
    {
        int initial_n = n;
        int factors = 1;

        for (int i = 0; primes[i] * primes[i] <= n; ++i)
        {
            int power = 0;
            while (initial_n % primes[i] == 0)
            {
                initial_n /= primes[i];
                ++power;
            }
            factors *= power + 1;
        }

        if (initial_n > 1)
        {
            factors *= 2;
        }

        return factors;
    }

    private static int Maciej(int n)
    {
        int factors = 1;
        int i = 2;
        for (; i * i < n; ++i)
        {
            if (n % i == 0)
            {
                ++factors;
            }
        }

        factors *= 2;

        if (i * i == n)
        {
            ++factors;
        }

        return factors;
    }

    static void Main()
    {
        Sieve();


        Console.WriteLine("Testing equivalence...");

        for (int i = 2; i < 1000000; ++i)
        {
            if (Maciej(i) != IVlad(i))
            {
                Console.WriteLine("Failed!");
                Environment.Exit(1);
            }
        }

        Console.WriteLine("Equivalence confirmed!");

        Console.WriteLine("Timing IVlad...");
        Stopwatch t = new Stopwatch();

        t.Start();
        for (int i = 2; i < 1000000; ++i)
        {
            IVlad(i);
        }

        Console.WriteLine("Total milliseconds: {0}", t.ElapsedMilliseconds);
        Console.WriteLine("Timing Maciej...");

        t.Reset();
        t.Start();
        for (int i = 2; i < 1000000; ++i)
        {
            Maciej(i);
        }


        Console.WriteLine("Total milliseconds: {0}", t.ElapsedMilliseconds);
    }
}
read given number in n
int divisorsCount = 1;
int i;
for(i = 2; i * i < n; ++i)
{
    if(n % i == 0)
    {
        ++divisorsCount;
    }
}
divisorsCount *= 2;
if(i * i == n)
{
    ++divisorsCount;
}