如何修复我的素数生成程序,使其不再生成合数
How do I fix my Prime Generating program, from producing composite numbers
我正在尝试用 C++ 编写一个程序,它将计算质数,并将它们存储在一个数组中。考虑这是我的第三个代码。
我 运行 遇到的问题是,当我得到质数时,我也得到合数,特别是 5 和 7 的倍数(至少直到 30 的极限)。我知道,代码可能会很糟糕,但鉴于我在编码和素数方面的有限经验,我可以想出什么。
这是我写的:
#include <iostream>
int j;
int i = 3;
int prime[30];
int main()
{
for (i; i < 30; i+=2)
{
for (j =i; j>i*i; j--)
{
if ((i % j) == 0)
{
continue;
}
}
prime[i] = i;
std::cout << prime[i] << std::endl;
}
}
输出:3 5 7 9 11 13 15 17 19 21 23 25 27 29
你的内部循环只需要用你目前遇到的素数来测试可整除性。 (例如,如果您已经用 3 测试过整除性,那么用 9 测试整除性就没有意义了)
int main()
{
int j;
int i = 3;
int primes[30];
int primecount = 0;
primes[primecount++] = 2; // hardcode 2, it's the only even number
for (i = 3; i < 30; i += 2)
{
bool isPrime = true;
for (j = 0; j < primecount; j++)
{
if ((i % primes[j]) == 0)
{
isPrime = false;
break;
}
}
if (isPrime)
{
primes[primecount++] = i;
}
}
for (int k = 0; k < primecount; k++)
{
std::cout << primes[k] << " ";
}
std::cout << std::endl;
}
与 CoderCharmander points out 一样,continue
仅从 inner 循环中断,但您打算继续 outer[=30] =] 循环。最小的修复是使用可怕的 goto
,在这里完全合适。
而且内部 for
循环规范都是错误的:
#include <iostream>
int prime[30];
int main()
{
int i, j;
std::cout << 2 << " "; // the first prime is 2
for (i=3; i < 30; i+=2)
{
for // all wrong: (j =i; j>i*i; j--)
(j = 2; j*j <= i; ++j) // or even, (j = 3; j*j <= i; j += 2)
{
if ((i % j) == 0)
{
prime[i] = 0; // initialize the non-primes as well!
goto L1; // continue the outer loop
}
}
// the inner loop finished normally
prime[i] = i;
std::cout << i << " ";
L1: ;
}
}
这也不必要地通过小于阈值的所有大于 2 的数字(或按照评论建议中的赔率)测试数字,但我们只需要通过素数进行测试。
进行此修改时,请务必注意不要引入比我们试图修复的效率低得多的效率(二次方 时间复杂度损失超过预期 log 因子增益),因为没有必要测试例如23 由 5、7、11、13 和 19。
实际上 testing divisibility can be avoided altogether,如果有人愿意,那完全是另一回事。
我正在尝试用 C++ 编写一个程序,它将计算质数,并将它们存储在一个数组中。考虑这是我的第三个代码。
我 运行 遇到的问题是,当我得到质数时,我也得到合数,特别是 5 和 7 的倍数(至少直到 30 的极限)。我知道,代码可能会很糟糕,但鉴于我在编码和素数方面的有限经验,我可以想出什么。
这是我写的:
#include <iostream>
int j;
int i = 3;
int prime[30];
int main()
{
for (i; i < 30; i+=2)
{
for (j =i; j>i*i; j--)
{
if ((i % j) == 0)
{
continue;
}
}
prime[i] = i;
std::cout << prime[i] << std::endl;
}
}
输出:3 5 7 9 11 13 15 17 19 21 23 25 27 29
你的内部循环只需要用你目前遇到的素数来测试可整除性。 (例如,如果您已经用 3 测试过整除性,那么用 9 测试整除性就没有意义了)
int main()
{
int j;
int i = 3;
int primes[30];
int primecount = 0;
primes[primecount++] = 2; // hardcode 2, it's the only even number
for (i = 3; i < 30; i += 2)
{
bool isPrime = true;
for (j = 0; j < primecount; j++)
{
if ((i % primes[j]) == 0)
{
isPrime = false;
break;
}
}
if (isPrime)
{
primes[primecount++] = i;
}
}
for (int k = 0; k < primecount; k++)
{
std::cout << primes[k] << " ";
}
std::cout << std::endl;
}
与 CoderCharmander points out continue
仅从 inner 循环中断,但您打算继续 outer[=30] =] 循环。最小的修复是使用可怕的 goto
,在这里完全合适。
而且内部 for
循环规范都是错误的:
#include <iostream>
int prime[30];
int main()
{
int i, j;
std::cout << 2 << " "; // the first prime is 2
for (i=3; i < 30; i+=2)
{
for // all wrong: (j =i; j>i*i; j--)
(j = 2; j*j <= i; ++j) // or even, (j = 3; j*j <= i; j += 2)
{
if ((i % j) == 0)
{
prime[i] = 0; // initialize the non-primes as well!
goto L1; // continue the outer loop
}
}
// the inner loop finished normally
prime[i] = i;
std::cout << i << " ";
L1: ;
}
}
这也不必要地通过小于阈值的所有大于 2 的数字(或按照评论建议中的赔率)测试数字,但我们只需要通过素数进行测试。
进行此修改时,请务必注意不要引入比我们试图修复的效率低得多的效率(二次方 时间复杂度损失超过预期 log 因子增益),因为没有必要测试例如23 由 5、7、11、13 和 19。
实际上 testing divisibility can be avoided altogether,如果有人愿意,那完全是另一回事。