简体   繁体   English

使用递归C ++查找半素数

[英]Finding a Semi Prime number using recursion c++

is there any way to convert this to a recursion form? 有什么办法可以将其转换为递归形式? how to find the unknown prime factors(in case it is a semiprime)? 如何找到未知的素因数(如果是半素数)?

semiPrime function:

bool Recursividad::semiPrimo(int x)
{
    int valor = 0;
    bool semiPrimo = false;
    if(x < 4)
    {
        return semiPrimo;
    }
    else if(x % 2 == 0)
    {
        valor = x / 2;
        if(isPrime(valor))
        {
            semiPrimo = true;
        }
    }
    return semiPrimo;
}

Edit: i've come to a partial solution(not in recursive form). 编辑:我已经部分解决方案(不是递归形式)。 i know i have to use tail recursion but where? 我知道我必须使用尾递归,但是在哪里?

   bool Recursividad::semiPrimo(int x){
    bool semiPrimo=false;
vector<int> listaFactores= factorizarInt(x);
vector<int> listaFactoresPrimos;
int y = 1;

for (vector<int>::iterator it = listaFactores.begin();
            it!=listaFactores.end(); ++it) {
                if(esPrimo(*it)==true){
            listaFactoresPrimos.push_back(*it);         
        }
    } 
int t=listaFactoresPrimos.front();
if(listaFactoresPrimos.size()<=1){  
    if(t*t==x){
    semiPrimo=true;
    }
}else{
    int f=0;
    #pragma omp parallel 
    {
     #pragma omp for
    for (vector<int>::iterator it = listaFactoresPrimos.begin();
            it!=listaFactoresPrimos.end(); ++it) {
                f=*it;
                int j=0;
                for (vector<int>::iterator ot = listaFactoresPrimos.begin();
            ot!=listaFactoresPrimos.end(); ++ot) {
                j=*ot;

                if((f * j)==x){
                            semiPrimo=true;         }

                }

    } 
    }
}
return semiPrimo;
}

any help would be appreciated 任何帮助,将不胜感激

You can convert a loop into recursion in a formulaic manner. 您可以按公式方式将循环转换为递归。 Note that do_something() needn't be a single function call; 注意, do_something()不必是单个函数调用; it can be anything (except flow control like break that'd change the loop behavior): 它可以是任何东西(除了可以改变循环行为的break类的流控制之外):

void iterative() {
    for (int x = 0; x < 10; ++x) {
        do_something(x);
    }
}

becomes 变成

void recursion_start() {
    recursive(0);
}

void recursive(int x) {
    if (x < 10) {
        do_something(x);
        recursive(x + 1);
    }
}

Note also that you can rewrite that as the following, which in a good compiler will actually run just as fast as the iterative version (this is called "tail-call optimization"). 还要注意,您可以按照以下方式重写该代码,它在一个好的编译器中实际上将以与迭代版本一样快的速度运行(这称为“尾调用优化”)。 gcc 4.6.2, for example, manages to do this—actually, its smart enough to do the above version as well. 例如,gcc 4.6.2可以做到这一点-实际上,它足够聪明,也可以执行上述版本。

void recursive(int x) {
    if (x >= 10)
        return;
    do_something(x);
    recursive(x + 1);
}

Actually your algorithm isn't the best way to do it. 实际上,您的算法并不是实现它的最佳方法。 If x will be more than 100, your program will fail. 如果x大于100,则您的程序将失败。

The naive algorithm to check if the number is prime is the trial division algorithm . 检验数是否为素数的天真的算法是试算法 Implementation with recursion: 递归实现:

bool is_prime_rec(int x, int it = 2)
{
    if (it > sqrt(double(x)))
        return true;
    return x%it ? is_prime_rec(x, ++it) : false;
}

But it will look much better if we replace recursion with a cycle: 但是,如果将循环替换为循环,它将看起来更好:

bool is_prime(int x)
{
    if (x == 2)
        return true;
    if (x%2 == 0)
        return false;

    // speed up a bit
    for (int i = 3; i <= sqrt(double(x)); i += 2) 
        if (x%i == 0)
            return false;
    return true;
}

The usual answer for finding prime numbers from 1 to n is the Sieve of Erasthones . 查找从1到n的质数的常见答案是Erasthones筛 But first, you need to figure out how you're determining whether the number is semi-prime. 但是首先,您需要弄清楚如何确定数字是否为半素数。 You can catch the trivial cases from 1 to 7 if you'd like. 如果需要,您可以捕获从1到7的琐碎情况。 After that, it's a matter of running the sieve and checking each prime number as a divisor. 之后,只需运行筛子并检查每个质数作为除数即可。 If it's an even divisor and the quotient is also on your list of primes, you're golden. 如果它是偶数除数,并且商也位于质数列表中,那么您就是黄金。 If it's not on your list of prime (and hasn't been reached by the sieve yet), add it to a list of likelies and check those as you generate sufficiently high prime numbers. 如果它不在您的质数列表中(并且尚未通过筛子到达),则将其添加到可能性列表中,并在生成足够高的质数时对其进行检查。 Once you find two primes, exit with success. 一旦找到两个素数,就成功退出。 If you reach the your number divided by your smallest prime divisor, exit with failure. 如果达到数字除以最小除数,则失败退出。

Catch is, I can't think of a way to implement this in recursion and not hurt performance. Catch是,我想不出一种在递归上实现此功能且不会损害性能的方法。 That said, you can combine this with derobert's bit about converting to recursion, passing along pointers to your reference arrays of primes and likelies. 也就是说,您可以将其与derobert的有关转换为递归的知识结合起来,并传递指向质数和似然的引用数组的指针。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM