简体   繁体   English

将PARI程序转换为C ++

[英]Convert PARI program to C++

I found a sequence of interest in OEIS and I want to generate the same sequence in C++ for a programming competition solution I am working on. 我在OEIS中发现了一个感兴趣序列,我想在C ++中为正在研究的编程竞赛解决方案生成相同的序列。

However I hit a roadblock understanding how the program given in the sequence page works. 但是,我遇到了一个障碍,即了解序列页面中给出的程序如何工作。

Here is the program given in the page - 这是页面中给出的程序-

(PARI) test(n)= {m=n; forprime(p=2, 5, while(m%p==0, m=m/p));                                         
return(m==1)} for(n=1, 500, if(test(n), print1(n", ")))
(PARI) a(n)=local(m); if(n<1, 0, n=a(n-1); 
            until(if(m=n, forprime(p=2, 5, while(m%p==0, m/=p)); m==1), n++); n)
(PARI) list(lim)={
lim\=1;
my(v=List(), s, t);
for(i=0, log(lim+.5)\log(5),
    t=5^i;
    for(j=0, log(lim\t+.5)\log(3),
        s=t*3^j;
        while(s <= lim,
            listput(v, s);
            s <<= 1;
        )
    )
);
vecsort(Vec(v))
};

I found out what PARI is, but I am unable to convert this program to C++. 我知道什么是PARI,但是无法将此程序转换为C ++。 Any suggestions to help me generate the same sequence in C++ would be much appreciated. 任何帮助我在C ++中生成相同序列的建议将不胜感激。

I tried to generate the sequence in C++ with the following code snippet. 我尝试使用以下代码片段在C ++中生成序列。 But I think I am missing certain numbers in between as I fail a few tests in the online IDE. 但是我认为由于在线IDE中的一些测试失败而导致两者之间缺少某些数字。

for(int i = 0; i < 16; i++)
{
    for(int j = 0; j < 15; j++)
    {
        for(int k = 0; k < 12; k++)
        {
            std::cout<<pow(2,i)*pow(3,j)*pow(5,k)<<std::endl;
        }
    }
}

I chose 16, 15 and 12 as the limits because otherwise the result value overflows long variable type. 我选择16、15和12作为限制,因为否则结果值会溢出long变量类型​​。

You have three programs here, each of which serve different purposes. 您在这里有三个程序,每个程序都有不同的用途。

The first checks if a number is 5-smooth. 第一个检查数字是否为5平滑。 It simply divides by 2, 3, and 5 until it can't do so any more, and then tests if what's left is 1. 它简单地除以2、3和5,直到不能再除,然后测试是否剩下1。

The second generates the ''n''th 5-smooth number. 第二个生成第“ n”个5平滑数。 It uses the same idea as the first, testing each number in the range. 它使用与第一个相同的想法,测试范围内的每个数字。 This is very inefficient! 这是非常低效的!

The third generates all 5-smooth numbers up to a given bound. 第三个生成直到给定界限的所有5平滑数字。

I'm going to assume that the third is what you want, because it seems most likely to be applicable to your situation. 我将假设第三个是您想要的,因为它似乎最可能适用于您的情况。 (It also helps that I am the author of that program.) (这也有助于我成为该程序的作者。)

#include <iostream>
#include <vector>
#include <algorithm>

int main(void);
std::vector<long> smooth(long lim);

int main(void) {
    long lim = 1000;
    std::vector<long> v = smooth(lim);
    std::cout << "5-smooth numbers up to " << lim << ": ";
    for (std::vector<long>::iterator it = v.begin(); it != v.end(); it++) {
        std::cout << *it << ", ";
    }
    std::cout << "\n";
    return 0;
}

std::vector<long> smooth(long lim) {
    std::vector<long> v = {};
    for (long t = 1; t <= lim; t*=5) {
        for (long s = t; s <= lim; s*=3) {
            for (long n = s; n <= lim; n*=2) {
                v.push_back(n);
            }
        }
    }
    std::sort(v.begin(), v.end());
    return v;
}

This isn't a line-by-line conversion, of course; 当然,这不是逐行转换; for example, I didn't use logarithms since exact logarithms aren't built-in to C++ like PARI. 例如,我没有使用对数,因为确切的对数没有像PARI一样内置在C ++中。 It's pretty fast, it finds all the 5-smooth numbers up to 1,844,674,407,370,955,161 (the highest it can do on a 64-bit machine) in a fraction of a second. 它的速度非常快,它可以在不到一秒钟的时间内找到所有5平滑数字,达到1,844,674,407,370,955,161(在64位计算机上可以达到的最高数字)。

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

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