已知的最有效的尾递归素数验证函数是什么?
What's the most efficient tail recursive prime verification function known?
我一直在尝试元编程:
// compiled on Ubuntu 13.04 with:
// clang++ -O3 -ftemplate-depth-8192 -fconstexpr-depth=4096 -std=c++11 -stdlib=libc++ -lcxxrt -ldl compile-time-primes.cpp -o compile-time-primes
// assembly output with:
// clang++ -S -mllvm --x86-asm-syntax=intel -O3 -ftemplate-depth-8192 -fconstexpr-depth=4096 -std=c++11 -stdlib=libc++ -lcxxrt -ldl compile-time-primes.cpp -o compile-time-primes.asm
#include <array>
#include <iostream>
template<typename T>
constexpr bool is_prime(T number, T limit, T counter)
{
return counter >= limit
? number % limit != 0
: number % counter
? is_prime(number, number / counter, counter + 2)
: false;
}
template<typename T>
constexpr bool is_prime(T n)
{
return n == 2 || n == 3 || n == 5
? true
: n <= 1 || n % 2 == 0
? false
: is_prime(n, n / 3, T{3});
}
template<size_t n>
struct print_below;
template<> struct print_below<2> { inline static void primes() { std::cout << 2; } };
template<size_t n>
struct print_below
{
inline static void primes()
{
print_below<n - 1>::primes();
constexpr bool is_n_prime = is_prime(n);
if(is_n_prime)
std::cout << ", " << n;
}
};
template <typename T, T... N>
struct primes { static const std::array<bool, sizeof...(N)> cache; };
template <typename T, typename L, T R>
struct append_param;
template <typename T, T... L, T R>
struct append_param<T, primes<T, L...>, R> { using primes = primes<T, L..., R>; };
template <size_t N>
struct indexer : append_param<size_t, typename indexer<N - 1>::primes, N - 1> {};
template <>
struct indexer<0> { using primes = primes<size_t>; };
template <typename T, T... N>
const std::array<bool, sizeof...(N)> primes<T, N...>::cache = {{ is_prime(N)... }};
int main()
{
std::cout << "Some primes: n";
print_below<8000>::primes();
std::cout << std::endl;
const auto &primes_cache = indexer<1000>::primes::cache;
for(size_t i = 1; i < primes_cache.size(); ++i)
std::cout << i << (primes_cache[i] ? " is " : " is not ") << "prime" << std::endl;
}
现在我想知道is_prime
是否有更好的尾部递归算法,可以放在constexpr
函数中。
还有比这更好的吗?
- 要求:必须是尾部递归的
- 可取:适合
constexpr
函数
可以。
首先,你的一个主要限制将是你的递归深度限制。对于从3
到sqrt(N)
的每一个奇数,您的递归一次。对于~1000的递归限制,这意味着您只能处理100万以内的数字。你需要减少你所做的递归的数量
这样做的一种方法是对数字N
的因子进行分治搜索。通过一些工作,您可以将其扩展到2^1000
顺序的限制(即,除了递归限制之外,其他事情会使它首先无法工作)。
第二,不是检查每个奇数,而是检查6对1和5进行mod,在开始时检查2/3/5的特殊情况。除了半径为6之外,更远距离的模式也可以使用。
第三,有足够可靠的概率原数检验,使用它们是正确的答案。您可能会构建一个硬编码表,其中包含测试失败的数字,根据该表进行检查,然后以其他方式进行测试,并将上限设置为远远高于您实际可以执行的上限。
您的设计的另一个问题是,它每次测试一个素数:理想情况下,您应该建立一个素数表,并使用这些表来帮助进行素数测试。有些编译器会对之前的结果进行记忆,您可以利用这一点。
相关文章:
- 如何正确实现 std::all_of 函数来验证字符串的一部分?
- 获取线函数未定义错误。无法在字符串中保存可验证的内容
- C++ 验证使泛型函数
- 如何验证函数不调用自身?
- 是否可以使用 EXPECT_CALL 来验证模拟对象的构造函数是否在某些时候调用成员函数?
- 无法使用C风格函数调用验证签名
- C++:输入验证器函数
- 使用函数验证输入
- 使用constexpr验证构造函数中的文字参数
- C :对输入验证函数进行编程的性能影响可以对其进行编程,而每次都可以将其编程
- 使用模板函数进行通用输入验证
- C++ 如何在单独的函数中验证用户输入的实数
- 我想知道如何验证函数签名
- 字符串验证函数出错
- 具有编译时间验证的ConstexPR构造函数
- 如何创建不接受浮点值的整数验证函数
- 递归验证函数堆栈溢出
- 已知的最有效的尾递归素数验证函数是什么?
- 验证函数中的文件并在主文件中调用它,输出"file is valid"它是否有效
- c++验证函数循环在第一次迭代后返回相同的结果