使用C ++函数练习使用!=来识别素数

时间:2016-07-08 03:28:47

标签: c++ function codeblocks primes

我正在通过本书的c ++编程原理和实践。在本书中,有一个练习,通过检查数字与已被识别为素数的数字来查找素数。这是我为解决这个问题而编写的函数。

vector <int> primes;

int findprime (int x) {
    for (int p=0; p<primes.size(); ++p) {
        if (x%primes[p]!=0) {
            return x;
        }
    }   
}

int main() {
    primes.push_back(2);
    for (int i=3; i<100; ++i) {
        primes.push_back(findprime(i));
    }
    for (int i=0; i<primes.size(); ++i) {
        cout << primes[i] << '\n'; 
    }
}

作者在他的解决方案中的作用是:

bool is_prime(int n) {
    for (int p = 0; p<prime.size(); ++p)
        if (n%prime[p]==0) return false;    // no remainder: prime[p] divided

    return true;    // no smaller prime could divide
}

我的代码不起作用,但我真的不明白为什么。我想我错过了关于功能如何运作的一些知识。如果有人能解释我的代码无法正常工作并填补我的空白,我将非常感激。

4 个答案:

答案 0 :(得分:2)

通过到达定义为返回值而不返回任何内容的函数的末尾来调用未定义的行为。您的编译器应该发出警告。如果没有,那么你应该打开编译器警告。

findprime总是会返回一些int,但如果x不能被primes中的某个值整除,那么您将无需到达函数的末尾遇到return语句。在那种情况下它应该返回什么?答案是答案没有具体说明。在这种情况下,实现可以随意做任何事情。在这种情况下,它似乎只是返回x

答案 1 :(得分:1)

这是清理过的代码,注释了错误和修复[请原谅无偿的样式清理]:

#include <vector>
#include <iostream>
std::vector <int> primes;

// NOTE/BUG: before this was returning the inverse sense
// RETURNS: 0=not prime, 1=prime
int
findprime(int x)
{
    for (int p = 0; p < primes.size(); ++p) {
        if (x % primes[p] == 0) {
            return 0;
        }
    }

    // BUG: this return was missing
    return 1;
}

int
main()
{
    primes.push_back(2);

    for (int i = 3; i < 100; ++i) {
        // BUG: before this was _always_ adding the number
#if 0
        primes.push_back(findprime(i));
#else
        if (findprime(i))
            primes.push_back(i);
#endif
    }

    for (int i = 0; i < primes.size(); ++i) {
        std::cout << primes[i] << '\n';
    }
}

答案 2 :(得分:0)

你和作者的解决方案是不同的:

作者的逻辑是检查某个数字n的素数。如果任何素数均匀地除n,并且只有在检查了true之后的所有素数之后,它才会提前退出。

您的代码int findprime (int x)所做的不是这个。如果x无法平均分配至少一个现有素数,则返回x。因为它会将每个数字明确地添加为素数,所以它总能找到一些不能完美划分x的数字。正如其他人所提到的那样,函数编写得很糟糕,因为它可以以避免所有return语句的方式进行分支(错误,导致未定义的行为)。

我建议使用作者的版本并研究它的工作原理 - 它起作用,因为当它确实提前退出时,它确实如此。不能被一个素数划分本身并不能保证你处理素数,当所有素数不分割你的数字时 - 如果任何可以除以那么这个数字不是素数,也不需要再检查了。有更高级的测试,但素数测试和寻找素数是它自己的主题,可以研究超出任何编程语言或方法的细节。

答案 3 :(得分:0)

此代码应该有效:

int findprime(int x)
{
    for (int p=0; p<primes.size(); p++)
    {
        if ((x%primes[p])==0)
        {
           return -1;
           break;
        }
    }
return x;
}

int main()
{
   primes.push_back(2);
   primes.push_back(3);
   for (int i=3; i<100; ++i)
   {
      if(findprime(i)!=-1)  
      {
        primes.push_back(i);
      }
   }
   for (int i=0; i<primes.size(); ++i)
   {
       cout << primes[i] << '\n'; 
   }
}

如上所述,其中一个答案如上所述。你正在浏览向量的所有值,最后没有返回任何内容。