确定可以分解为素数 {2,3,5,7} 的下一个最高数
Determining the next highest number that can be factored into prime numbers {2,3,5,7}
我想写一个函数,它被赋予一个无符号整数作为输入参数,并返回可以分解为素数{2,3,5,7}的下一个最高数字。 这是一个简短的代码片段,显示了我想做什么。
unsigned int getHigherNumber(unsigned int x)
{
// obtain the next highest number that can be factored into
// prime numbers (2, 3, 5, and 7)
if (~(x % 2 || x % 3 || x % 5 || x % 7))
return x;
else
{
// ???
}
} // end
此函数的目的是查找应填充数组的零数,以确保 FFTW(链接)等算法能够以高效方式运行。 给定的链接讨论了该算法对于长度可以分解为小素数的输入是最佳的。
正如对这个问题的评论中所建议的,如果FFTW算法是最优的,似乎只允许2^a * 3^b * 5^c * 7^d形式的数字。
例如,标准 FFTW 分布对于大小可以分解为小素数(2、3、5 和 7)的数组最有效,否则它使用较慢的通用例程。
真的,你不需要下一个最高的,而只需要相当接近的东西。最简单的方法是选择最接近的 2 的幂。这最多会浪费原始数组的大小。
为此,找到最高有效位并将其乘以 2。
查找最有效位的明显方法:
未签名的 int v;用于查找日志基数 2 的 32 位字 无符号整数 r = 0;r 将是最有效位 而 (v>>= 1) { r++; }
基于前面的答案,如果数组将非常大~2^10,并且您希望在保持简单的同时尽可能少地使用额外的空间,您也可以选择小于x的最大幂7乘以最大幂5,依此类推。那是
unsigned int getHigherNumber(unsigned int x)
{
unsigned int ans=1;
unsigned int primes[4]={2,3,5,7};
for(int i=3; i>=0; i--)
{
for(int j=0; ; j++)
{
if(pow(primes[i],j)>x)
{
ans*=pow(7,j-1);
if(i==0)
ans*=2;
break;
}
}
}
return ans;
}
(未经测试)。我认为这应该让你得到一个比最接近的 2 次方更小的数字,但代价是一些速度。不过,这绝对不是最佳的。
以下算法和源代码可能没有经过高度优化,无法找到通用形式 (2^a * 3^b * 5^c * 7^d) 的下一个最高数字,但它很有用,因为代码将返回具有这些幂之一的最高数字。
该算法首先检查该数字是否为 {2,3,5,7} 的幂。 如果是,则简单地返回该数字。 如果不是,则算法会找到高于输入数字的最小功率。
更复杂的方法将使用质因式分解算法和搜索/排序,或者可能是硬编码的查找表,但这些解决方案对于此应用程序来说可能过于复杂。
#include <iostream>
#include <cmath>
#include <vector>
#include <algorithm>
// http://stackoverflow.com/questions/1804311/how-to-check-if-an-integer-is-power-of-3
// Checks if n^x
int powerOf(int n, int x)
{
while (n % x == 0)
{
n /= x;
}
return n == 1;
}
unsigned int hN(unsigned int x, unsigned int base)
{
double exponent = std::ceil( std::log(x) / std::log(base) );
double num = std::pow(base, exponent);
return static_cast<unsigned int>(num);
}
unsigned int getHigherNumber(unsigned int n)
{
unsigned int rv = n;
const int pnum = 4;
// 1) Is the number a power of {2,3,5,7}?
// If it is, then simply return it
if(powerOf(n,2)) return rv;
if(powerOf(n,3)) return rv;
if(powerOf(n,5)) return rv;
if(powerOf(n,7)) return rv;
// 2) If not, then find next highest power of {2,3,5,7} that is the smallest
// number higher than n
unsigned int num0 = hN(n, 2);
unsigned int num1 = hN(n, 3);
unsigned int num2 = hN(n, 5);
unsigned int num3 = hN(n, 7);
std::vector<unsigned int>v(pnum);
v[0] = num0;
v[1] = num1;
v[2] = num2;
v[3] = num3;
rv = *std::min_element(v.begin(),v.end());
// 3) TODO: More sophisticated methods would use prime-factorization
// algorithms and searching/sorting, or perhaps a look-up table,
// but these may be too complex for this application
return rv;
} // end
int main()
{
// const unsigned int num = 64;
// const unsigned int num = 18;
const unsigned int num = 2234;
std::cout << "num = " << num << std::endl;
std::cout << "higher number = " << getHigherNumber( num ) << std::endl;
} // end
相关文章:
- 使用一个内存集数组和单个堆栈在 O(n) 中查找数组的下一个更大元素
- 查找下一个具有真值C++的数组索引
- 找出堆栈数组中的下一个整数是否相同
- 如何使用字符串字符数组中的 ++ 运算符访问下一个字符串
- 指针指向数组中的下一个元素,但地址是相同的.如何
- 有效的方法来计算浮子后下一个更高的整数
- 通过在上一个数组结束后立即存储下一个元素来扩展数组
- C 如何从数组中的下一个可用位置填充数组
- 确定可以分解为素数 {2,3,5,7} 的下一个最高数
- 返回指向指针数组的指针获取下一个元素失败
- do while循环中的数组值没有传递给下一个
- 找到下一个最大的回文数
- 获取下一个非连续的二进制数
- 具有一个零位的下一个更高的数字
- 如何在C++中的字符串数组中找到下一个空闲元素,然后将数据附加到它
- 将C++函数重写为C#(将指针传递到数组中的下一个元素)
- 如何将分配给*Child[n]的*Base指向Child数组的下一个元素
- c++存储数组下一个位置的地址
- 计算下一个最短路径(到目的地的最小跳数)
- 使用内部函数在数组中查找下一个非零