仅使用素数 2、3 和 5 生成序列,然后显示第 n 项 (C++)
Generating a sequence using prime numbers 2, 3, and 5 only, and then displaying an nth term (C++)
我正在解决一个问题,该问题要求使用质数 2、3 和 5 生成序列,然后显示序列中的第 n 个数字。 因此,如果我要求程序显示第 1000 个数字,它应该显示它。
我不能使用数组或类似的东西,只能使用基本的决策和循环。
我开始研究它并撞墙...这是我得到的:
#include <iostream>
using namespace std;
int main() {
unsigned int n=23;
for(int i=2; i<n; i++){
if(i%2==0){
cout<<i<<", ";
}else if(i%3==0){
cout<<i<<", ";
}else if(i%5==0){
cout<<i<<", ";
}
}
return 0;
}
不幸的是,该代码没有执行所需的操作。 它显示数字,例如 14,其中包括一个质数 7。 这些数字只能除以 3 个指定的素数 (2,3,5)。
我找到了一些我试图理解的信息,但到目前为止还不确定如何实现它......也许使用大量的 for() 循环? 所以,看来我必须使用2^n * 3^m * 5^k的概念,其中n+m+k>0。
我想我必须通过一个测试运行一个数字,它首先检查它是否完全可以被 2^1 * 3^0 * 5^0 整除,然后是 2^0 * 3^1 * 5^0,然后是 2^0 * 3^0 * 5^1,依此类推......只是不知道从哪里开始。
这是一个著名的问题,以理查德·汉明的名字命名为汉明问题,在Dijkstra的著名著作《编程学科》中也有介绍。数学家称这些数字(如果包括 1)5 平滑数,因为它们的素数分解只包含小于或等于 5 的素数。
你应该注意到的是,你可以从彼此生成数字。 以下是思考问题的一种方法:
#include <set>
#include <iostream>
using namespace std;
int
main()
{
const unsigned n = 23;
set<unsigned> s;
s.insert(2);
s.insert(3);
s.insert(5);
for (unsigned i = 0; i < n; ++i)
{
// This returns the smallest element in the set.
unsigned x = *s.begin();
cout << x << 'n';
// Erase the smallest element.
s.erase(s.begin());
// Insert the multiples of x.
s.insert(2*x);
s.insert(3*x);
s.insert(5*x);
}
}
这需要 O(n log n) 时间来打印 n 个数字。通过合并惰性流,可以使用类似的算法在 O(n) 时间内完成此操作。我的解决方案使用了boost::transform_iterator
和boost::iterator_facade
,所以我不建议初学者这样做。
这段代码会这样做。 将问题分解为较小的问题通常是一个好的计划。
int main() {
unsigned int n=23;
unsigned int counter=0;
unsigned int answer;
for ( answer = 2; counter < n; ++answer ) {
if ( isNotDivisibleByAPrimeGreaterThan5( i ) {
++counter;
}
}
cout << answer;
return 0;
}
现在你只需要编写这个函数。
bool isNotDivisibleByAPrimeGreaterThan5( unsigned int i ) {
// return true if i is not divisable by a prime greater than 5.
}
#include <type_traits>
#include <utility>
#include <iostream>
template<int... s>
struct seq {};
template<int n, typename seq, typename=void>
struct can_be_factored_into;
template<int n, int first, int... rest>
struct can_be_factored_into< n, seq<first, rest...>, typename std::enable_if< (n > 1) && (n%first) >::type >: can_be_factored_into< n, seq<rest...> > {};
template<int n, int first, int... rest>
struct can_be_factored_into< n, seq<first, rest...>, typename std::enable_if< (n > 1) && !(n%first) >::type >: can_be_factored_into< n/first, seq<first, rest...> > {};
template<int n, int... rest>
struct can_be_factored_into< n, seq<rest...>, typename std::enable_if< n == 1 >::type: std::true_type {};
template<int n>
struct can_be_factored_into< n, seq<>, typename std::enable_if< n != 1 >::type: std::false_type {};
template<int n>
using my_test = can_be_factored_into< n, seq<2,3,5> >;
template<template<int n>class test, int cnt, int start=1, typename=void>
struct nth_element;
template<template<int n>class test, int cnt, int start>
struct nth_element<test, cnt, start, typename std::enable_if< (cnt>1)&&test<start>::value >::type >:
nth_element<test, cnt-1, start+1 > {};
template<template<int n>class test, int cnt, int start>
struct nth_element<test, cnt, start, typename std::enable_if< (cnt==1)&&test<start>::value >::type >
{ enum { value = start }; };
template<template<int n>class test, int cnt, int start>
struct nth_element<test, cnt, start, typename std::enable_if< !test<start>::value >::type >:
nth_element<test, cnt, start+1 > {};
int main() {
std::cout << nth_element< my_test, 1500 >::value << "n";
}
一旦你编译了上面的代码,它将在远不到 1 分钟的时间内执行。
缺点是它会破坏大多数编译器的编译时递归限制。 (这是你每天的轻描淡写)
为了改善这一点,需要重写nth_element
,以便在该范围内进行指数爆炸搜索和分而治之。 您可能还必须修改代码以使用 64 位值,因为上述序列的第 1500 个元素可能大于 2^32。
还是让它快速编译也是一种要求? :)
这是汉明实现的第一遍。 尚未编译:
#include <iostream>
#include <utility>
template<long long... s>
struct seq;
template<long long cnt, typename seq, typename=void>
struct Hamming;
template<long long cnt, long long first, long long... rest>
struct Hamming<cnt, seq<first, rest...>, typename std::enable_if< cnt == 0 >::type> {
static const long long value = first;
};
template<long long x, typename seq>
struct prepend;
template<long long x, long long... s>
struct prepend<x, seq<s...>>
{
typedef seq<x, s...> type;
};
template<typename s1, typename s2, typename=void>
struct merge;
template<long long begin_s1, long long... s1, long long begin_s2, long long... s2>
struct merge< seq< begin_s1, s1... >, seq< begin_s2, s2... >, typename std::enable_if< (begin_s1 < begin_s2) >::type > {
typedef typename prepend< begin_s1, typename merge< seq< s1... >, seq< begin_s2, s2... > >::type >::type type;
};
template<long long begin_s1, long long... s1, long long begin_s2, long long... s2>
struct merge< seq< begin_s1, s1... >, seq< begin_s2, s2... >, typename std::enable_if< (begin_s1 >= begin_s2) >::type > {
typedef typename prepend< begin_s2, typename merge< seq< begin_s1, s1... >, seq< s2... > >::type >::type type;
};
template<long long begin_s1, long long... s1>
struct merge< seq< begin_s1, s1... >, seq<>, void > {
typedef seq< begin_s1, s1... > type;
};
template<long long... s2>
struct merge< seq<>, seq<s2...>, void > {
typedef seq< s2... > type;
};
template<long long cnt, long long first, long long... rest>
struct Hamming<cnt, seq<first, rest...>, typename std::enable_if< cnt != 0 >::type>:
Hamming<cnt-1, typename merge< seq<first*2, first*3, first*5>, seq<rest...> >::type >
{};
int main() {
std::cout << Hamming<1500, seq<1>>::value << "n";
};
检查这个。
#include <iostream>
using namespace std;
int IsPrime(int var);
int CheckifPrimeGreaterThaFive(int Num);
int GetFactors(int Num)
{
int i =0,j=0;
for (i =2,j=0; i <= Num; i++)
{
if (Num%i == 0)
{
if (1 == CheckifPrimeGreaterThaFive(i))
{
return 1;
}
}
}
return 0;
}
int CheckifPrimeGreaterThaFive(int Num)
{
if ((Num != 2 && Num != 3 && Num != 5) && IsPrime(Num))
{
return 1;
}
return 0;
}
int IsPrime(int var)
{
for (int i = 2; i <= var/2; i++)
{
if (var % i == 0)
return 0;
}
return 1;
}
int main() {
int n=98;
int i, FactorsCount=0;
for(i=2; i<n; i++)
{
if (0 == GetFactors(i))
{
cout<<" "<<i;
}
}
return 0;
}
- 如何存储用户输入的所有数据,然后在他们想要查看所有数据时显示它们
- 从文本文件中读取并输入到数组结构中,然后显示读取的数据C++
- Gtkmm - 关闭窗口然后显示另一个窗口的正确方法
- 如何存储多个用户输入,然后以C++显示它们
- 如何从文本文件中获取值,然后用它们执行一些计算(例如乘以并显示它们)?
- 将25个甚至整数存储到一个名为intlist的整数阵列中,然后在屏幕上显示数组,并在屏幕上显示名为fivintegers
- 根据标准对结构向量进行排序,然后显示结果
- 显示然后删除链接列表C
- 我如何调用我的3个数据成员中每个人的设置方法,然后显示由我的设置方法设置的值
- 如何增加几个月循环.然后显示
- 如何使用我的 if-else 语句根据用户权重的输入执行特定操作,然后将其显示到控制台?
- c++将var从一个函数传递到另一个函数,然后在主函数中显示结果
- MFC:在 CRichEditCtrl 中突出显示一条线一段时间,然后恢复
- C++,使用 stack.h 读取一个字符串,然后反向显示它
- 图像在隐藏时消失,然后重新显示ListView
- 对输入'age'名称进行排序,然后显示结果
- 如何附加到相邻的十六进制值,然后显示
- 尝试在单击按钮时捕获编辑框中的文本,然后显示到另一个编辑框
- C++如何将数组传递给函数,然后调用它来显示数组的值
- 如何在mousepressEvent()函数中显示像素坐标,然后如何在每次单击鼠标时在paintGL()函数中将其使用