c - 列出给定大小的单元组的元素的最快方法是什么?

标签 c performance math number-theory

有几种快速算法可以计算给定数字 n 以内的素数。但是,在 C 中列出与某个数字 n 互质的所有数字 r 的最快实现是什么?也就是说,在 C 中尽可能高效地找到具有 n 个元素的乘法群的所有元素。特别是,我对 n 是原数的情况感兴趣。

n 原数与阶乘类似,只是仅将素数相乘,而忽略所有其他数字。因此,例如 12 初等将是 12#=11*7*5*3*2。

我目前的实现非常幼稚。我将前 3 组硬编码为数组,并使用它们来创建更大的数组。有没有更快的东西?

#include "stdafx.h"
#include <stdio.h>      /* printf, fgets */
#include <stdlib.h>     /* atoi */
#include <math.h>


int IsPrime(unsigned int number) 
{
    if (number <= 1) return 0; // zero and one are not prime

    unsigned int i;
    unsigned int max=sqrt(number)+.5;

    for (i = 2; i<= max; i++) 
    {
        if (number % i == 0) return 0;
    }

    return 1;
}

unsigned long long primorial( int Primes[], int size)
{
    unsigned long long answer = 1;

    for (int k = 0;k < size;k++)
    {
        answer *= Primes[k];
    }

    return answer;
}

unsigned long long EulerPhi(int Primes[], int size)
{
    unsigned long long answer = 1;

    for (int k = 0;k < size;k++)
    {
        answer *= Primes[k]-1;
    }

    return answer;
}


int gcd( unsigned long long a,  unsigned long long b)
{
    while (b != 0)
    {
        a %= b;
        a ^= b;
        b ^= a;
        a ^= b;
    }


    //Return whethere a is relatively prime to b
    if (a > 1)
    {
        return false;
    }

    return true;
}

void gen( unsigned long long *Gx, unsigned int primor, int *G3)
{
    //Get the magic numbers
    register int Blocks = 30;    //5 primorial=30.
    unsigned long long indexTracker = 0;

    //Find  elements using G3
    for (unsigned long long offset = 0; offset < primor; offset+=Blocks)
    {
        for (int j = 0; j < 8;j++)    //The 8 comes from EulerPhi(2*3*5=30)
        {
            if (gcd(offset + G3[j], primor))
            {
                Gx[indexTracker] = offset + G3[j];
                indexTracker++;
            }
        }
    }


}



int main(int argc, char **argv)
{
    //Hardcoded values
    int G1[] = {1};
    int G2[] = {1,5};
    int G3[] = {1,7,11,13,17,19,23,29};

    //Lazy input checking. The world might come to an end 
    //when unexpected parameters given. Its okey, we will live.
    if (argc <= 1) {
        printf("Nothing done.");
        return 0;
    }

    //Convert argument to integer
    unsigned int N = atoi(argv[1]);

    //Known values
    if (N <= 2 ) 
    {
        printf("{1}");
        return 0;
    }
    else if (N<=4)
    {
        printf("{1,5}");
        return 0;
    }
    else if (N <=6)
    {
        printf("{1,7,11,13,17,19,23,29}");
        return 0;
    }

    //Hardcoded for simplicity, also this primorial is ginarmous as it is. 
    int Primes[50] = {0};
    int counter = 0;

    //Find all primes less than N.
    for (int a = 2; a <= N; a++)
    {
        if (IsPrime(a))
        {
            Primes[counter] = a;
            printf("\n  Prime: : %i \n", a);
            counter++;
        }
    }

    //Get the group size
    unsigned long long MAXELEMENT = primorial(Primes, counter);
    unsigned long long Gsize = EulerPhi(Primes, counter);

    printf("\n  GSize: %llu \n", Gsize);
    printf("\n  GSize: %llu \n", Gsize);

    //Create the list to hold the values
    unsigned long long  *GROUP = (unsigned long long *) calloc(Gsize, sizeof(unsigned long long));

    //Populate the list
    gen( GROUP, MAXELEMENT, G3);

    //Print values
    printf("{");
    for (unsigned long long k = 0; k < Gsize;k++)
    {
        printf("%llu,", GROUP[k]);
    }
    printf("}");


    return 0;
}

最佳答案

如果您正在寻找更快的素数检查,这里有一个相当快的方法,并且消除了对计算密集型函数的所有调用(例如 sqrt 等)

int isprime (int v)
{
    int i;

    if (v < 0) v = -v;                          /* insure v non-negative */
    if (v < 2 || !((unsigned)v & 1))    /* 0, 1 + even > 2 are not prime */
        return 0;

    for (i = 2; i * i <= v; i++)
        if (v % i == 0)
            return 0;

    return 1;
}

(注意:如果您要查找高于标准int范围的数字,您可以根据需要调整type。)

尝试一下,让我知道它与您当前使用的版本相比如何。

关于c - 列出给定大小的单元组的元素的最快方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37404270/

相关文章:

c - L1 缓存未命中的成本是多少?

ios - CIImage 和 CIFilter 实现细节

javascript - 主干模型效率低下?

javascript - GPS 坐标 : 1km square around a point

将枚举错误代码转换为字符串

java - 用字符串列表搜索输入数字(类似于t9字典)

c - 按位表达式清除常量的低字节

c++ - 为什么 gcc 生成一个 memmove 而不是 memcpy 来复制 std::vector<>?

ruby - 如何找到 Ruby 整数数组/散列的异常值?

JavaScript 数学将 Div 放置在中心(算法)