C++ 寻找复合数
我有一系列随机数。范围实际上由用户确定,但最多为1000个整数。它们被放置在以下位置:C++ 寻找复合数,c++,primes,sieve,C++,Primes,Sieve,我有一系列随机数。范围实际上由用户确定,但最多为1000个整数。它们被放置在以下位置: vector<int> n 向量n 插入的值如下所示: srand(1); for (i = 0; i < n; i++) v[i] = rand() % n; srand(1); 对于(i=0;i
vector<int> n
向量n
插入的值如下所示:
srand(1);
for (i = 0; i < n; i++)
v[i] = rand() % n;
srand(1);
对于(i=0;i
我正在创建一个单独的函数来查找所有的非素数值。这是我现在所拥有的,但我知道这是完全错误的,因为我在这个系列中得到了素数和复合数
void sieve(vector<int> v, int n)
{
int i,j;
for(i = 2; i <= n; i++)
{
cout << i << " % ";
for(j = 0; j <= n; j++)
{
if(i % v[j] == 0)
cout << v[j] << endl;
}
}
}
void筛(向量v,int n)
{
int i,j;
对于(i=2;i您应该尝试使用a。您需要知道创建筛子的最大数量(O(n)
),然后您可以在该范围内构建一组素数(O(max_元素)
,或者根据问题状态O(1000)==O(1)
)然后检查每个数字是否在素数集中。您应该尝试使用a。您需要知道创建筛子的最大数字(O(n)
),然后您可以在该范围内构建一组素数(O(max_元素)
,或者问题状态为O(1000)==O(1)
))然后检查每个数字是否在素数集中。基本上,你有很多不相关的数字,所以对于每个数字,你必须检查它是否是素数
如果您事先知道数字的范围,那么您可以生成该范围内可能出现的所有素数(或其sqrt),并测试容器中的每个数字是否可被任何一个生成的素数整除
生成素数最好是通过Erathostenes筛来完成的——可以找到许多这种算法的例子。基本上,你有很多不相关的数字,所以你必须检查每一个数字是否是素数
如果您事先知道数字的范围,那么您可以生成该范围内可能出现的所有素数(或其sqrt),并测试容器中的每个数字是否可被任何一个生成的素数整除
生成素数最好是通过Erathostenes筛来完成的——很多例子都可以找到该算法。首先,我认为Knuth首先说了:过早优化是许多错误的原因。先制作慢版本,然后找出如何使其更快
第二,对于您的外部循环,您实际上只需要转到sqrt(n)而不是n。首先,我认为Knuth首先说了:过早优化是许多错误的原因。首先制作慢版本,然后找出如何使其更快
第二,对于外部循环,实际上只需要转到sqrt(n)而不是n。您尝试实现的筛子的想法取决于这样一个事实,即您从一个素数(2)开始,并划掉该数字的大量部分-因此,所有依赖于素数“2”的数字都会事先被排除
这是因为所有的非素数都可以分解为素数,而素数不能被模0整除,除非你把它们除以1或除以它们本身
因此,如果你想依赖这个算法,你需要一些方法来实际恢复算法的这个属性。你试图实现的筛子的想法取决于这样一个事实,即你从一个素数(2)开始,并划掉那个数的大量部分——因此所有依赖于素数“2”的数都被预先排除
这是因为所有的非素数都可以分解为素数,而素数不能被模0整除,除非你把它们除以1或除以它们本身
因此,如果您想依赖此算法,则需要一些方法来实际恢复算法的此属性。在本代码中:
if(i % v[j] == 0)
cout << v[j] << endl;
现在,您正在打印i的随机除数。您没有打印出已知不是素数的随机数。此外,您的输出中将有重复项,也许这是可以的。在此代码中:
if(i % v[j] == 0)
cout << v[j] << endl;
现在,您正在打印i的随机除数。您没有打印出已知不是素数的随机数。此外,您的输出中会有重复数,也许这是可以的。您的代码完全错误。首先,您正在测试i%v[j]==0,这是向后的,也解释了为什么会得到所有的数字。其次,当您测试和输出每个输入数字时,每次它未通过(断开的)可分性测试时,您的输出将包含重复项
其他建议:
使用n作为向量中的最大值和向量中的元素数是令人困惑和毫无意义的。您不需要传入向量中的元素数-您只需查询向量的大小。您可以相当快地计算出最大值(但如果您提前知道,您也可以传入)
如上所述,您只需要测试sqrt(n)[其中n是vecotr中的最大值]
你可以使用一个筛子来生成所有的素数,直到n,然后从输入向量中删除这些值,正如上面所建议的。这可能会更快更容易理解,特别是如果你把素数存储在某个地方
如果你要单独测试每个数字(我想是用反筛)然后,我建议按顺序分别测试每个数字。我想这比您编写的方式更容易理解-测试每个数字是否可以被k整除,以不断增加k。您的代码完全错误。首先,您测试的是I%v[j]==0,这是向后的,也解释了为什么会得到所有的数字。其次,当您测试和输出每个输入数字时,每次它未通过(断开的)可分性测试时,您的输出将包含重复项
其他建议:
使用n作为向量中的最大值和向量中的元素数是令人困惑和毫无意义的。您不需要传入向量中的元素数-您只需查询向量的大小。您可以相当快地计算出最大值(但如果您提前知道,您也可以传入)
如上所述,您只需要
if(v[j] % i == 0)
vector<int> inputNumbers;
// First, find all the prime numbers from 1 to n
bool isPrime[n+1] = {true};
isPrime[0]= false;
isPrime[1]= false;
for (int i = 2; i <= sqrt(n); i++)
{
if (!isPrime[i])
continue;
for (int j = 2; j <= n/i; j++)
isPrime[i*j] = false;
}
// Check the input array for non-prime numbers
for (int i = 0; i < inputNumbers.size(); i++)
{
int thisNumber = inputNumbers[i];
// Vet the input to make sure we won't blow our isPrime array
if ((0<= thisNumber) && (thisNumber <=n))
{
// Prints out non-prime numbers
if (!isPrime[thisNumber])
cout<< thisNumber;
}
}
void sieve(vector<int> v, int n) {
int i,j;
for(j = 0; j <= n; j++) {
cout << v[j] << ": ";
for(i = 2; i < v[j]; i++) {
if(v[j] % i == 0) {
cout << "is divisible by " << i << endl;
break;
}
}
if (i == v[j]) {
cout << "is prime." << endl;
}
}
}