is there any way to convert this to a recursion form?
how to find the unknown prime factors(in case it is a semiprime)?
semiPrime function:
bool Recursividad::semiPrimo(int x)
{
int valor = 0;
bool semiPrimo = false;
if(x < 4)
{
return semiPrimo;
}
else if(x % 2 == 0)
{
valor = x / 2;
if(isPrime(valor))
{
semiPrimo = true;
}
}
return semiPrimo;
}
Edit: i've come to a partial solution(not in recursive form). i know i have to use tail recursion but where?
bool Recursividad::semiPrimo(int x){
bool semiPrimo=false;
vector<int> listaFactores= factorizarInt(x);
vector<int> listaFactoresPrimos;
int y = 1;
for (vector<int>::iterator it = listaFactores.begin();
it!=listaFactores.end(); ++it) {
if(esPrimo(*it)==true){
listaFactoresPrimos.push_back(*it);
}
}
int t=listaFactoresPrimos.front();
if(listaFactoresPrimos.size()<=1){
if(t*t==x){
semiPrimo=true;
}
}else{
int f=0;
#pragma omp parallel
{
#pragma omp for
for (vector<int>::iterator it = listaFactoresPrimos.begin();
it!=listaFactoresPrimos.end(); ++it) {
f=*it;
int j=0;
for (vector<int>::iterator ot = listaFactoresPrimos.begin();
ot!=listaFactoresPrimos.end(); ++ot) {
j=*ot;
if((f * j)==x){
semiPrimo=true; }
}
}
}
}
return semiPrimo;
}
any help would be appreciated
You can convert a loop into recursion in a formulaic manner. Note that do_something() needn't be a single function call; it can be anything (except flow control like break that'd change the loop behavior):
void iterative() {
for (int x = 0; x < 10; ++x) {
do_something(x);
}
}
becomes
void recursion_start() {
recursive(0);
}
void recursive(int x) {
if (x < 10) {
do_something(x);
recursive(x + 1);
}
}
Note also that you can rewrite that as the following, which in a good compiler will actually run just as fast as the iterative version (this is called "tail-call optimization"). gcc 4.6.2, for example, manages to do this—actually, its smart enough to do the above version as well.
void recursive(int x) {
if (x >= 10)
return;
do_something(x);
recursive(x + 1);
}
Actually your algorithm isn't the best way to do it. If x will be more than 100, your program will fail.
The naive algorithm to check if the number is prime is the trial division algorithm. Implementation with recursion:
bool is_prime_rec(int x, int it = 2)
{
if (it > sqrt(double(x)))
return true;
return x%it ? is_prime_rec(x, ++it) : false;
}
But it will look much better if we replace recursion with a cycle:
bool is_prime(int x)
{
if (x == 2)
return true;
if (x%2 == 0)
return false;
// speed up a bit
for (int i = 3; i <= sqrt(double(x)); i += 2)
if (x%i == 0)
return false;
return true;
}
The usual answer for finding prime numbers from 1 to n is the Sieve of Erasthones. But first, you need to figure out how you're determining whether the number is semi-prime. You can catch the trivial cases from 1 to 7 if you'd like. After that, it's a matter of running the sieve and checking each prime number as a divisor. If it's an even divisor and the quotient is also on your list of primes, you're golden. If it's not on your list of prime (and hasn't been reached by the sieve yet), add it to a list of likelies and check those as you generate sufficiently high prime numbers. Once you find two primes, exit with success. If you reach the your number divided by your smallest prime divisor, exit with failure.
Catch is, I can't think of a way to implement this in recursion and not hurt performance. That said, you can combine this with derobert's bit about converting to recursion, passing along pointers to your reference arrays of primes and likelies.
Related
Here is the problem I am trying to solve:
Define a class named PrimeNumber that stores a prime number. The default constructor should set the prime number to 1. Add another constructor that allows the caller to set the prime number. Also, add a function to get the prime number. Finally, overload the prefix and postfix ++ and -- operators so they return a PrimeNumber object that is the next largest prime number (for ++) and the next smallest prime number (for --). For example, if the object's prime number is set to 13, then invoking ++ should return a PrimeNumber object whose prime number is set to 17. Create an appropriate test program for the class.
This is not for a class, I am just trying to teach myself C++ because I need it as I will start my PhD in financial mathematics at FSU this fall. Here is my code thus far:
#include <iostream>
#include "PrimeNumber.h"
using namespace std;
int main() {
int x;
cout << "\nenter prime number: ";
cin >> x;
PrimeNumber p(x);
PrimeNumber q(x);
p++;
q--;
cout << "\nprime before is " << q.GetPrime() << endl;
cout << "\nnext prime is " << p.GetPrime() << endl;
return 0;
}
class PrimeNumber {
int prime;
public:
PrimeNumber():prime(0){};
PrimeNumber(int num);
void SetPrime(int num);
int GetPrime(){return prime;};
PrimeNumber& operator++(int);
PrimeNumber& operator--(int);
static bool isPrime(int num);
};
void PrimeNumber::SetPrime(int num) {
if(isPrime(num)){
prime = num;
}else{
cout << num << " is not a prime Defaulting to 0.\n";
prime = 0;
}
}
PrimeNumber::PrimeNumber(int num){
if(isPrime(num))
prime = num;
else {
cout << num << " is not prime. Defaulting to 0.\n";
prime = 0;
}
}
PrimeNumber& PrimeNumber::operator++(int){
//increment prime by 1 and test primality
//loop until a prime is found
do
{
this->prime += 1;
}
while (! PrimeNumber::isPrime(this->prime));
}
PrimeNumber& PrimeNumber::operator--(int){
do
{
this->prime -= 1;
}
while (!PrimeNumber::isPrime(this->prime));
}
bool PrimeNumber::isPrime(int num) {
if(num < 2)
return false;
if(num == 2)
return true;
if(num % 2 == 0)
return false;
const int max_divisor = sqrt(num);
for(int div = 3; div < max_divisor; div += 2) // iterate odd numbers only
if(num % div == 0)
return false;
return true;
}
So, my question here is that for the bool isPrime function, I first say OK the prime numbers 2 and 3 are primes and then I eliminate any numbers that are multiples of 2 or 3. What I want to do is perhaps create a while loop that would eliminate the other multiples of the number leaving the prime numbers only. Although, I am not exactly sure how to achieve this, if anyone has any suggestions, I would greatly appreciate it.
Now that is taken care of, I can't seem to get the ++ and -- operators working correctly. Sometimes it works and sometimes it doesn't.
What I want to do is perhaps create a while loop that would eliminate the other multiples of the number leaving the prime numbers only. Although, I am not exactly sure how to achieve this, if anyone has any suggestions, I would greatly appreciate it.
The algorithm you want to apply is called the Sieve of Erathostenes.
Instead of doing that (it would require that you store more and more prime numbers as you increment an instance), consider the algorithm proposed by Juraj Blaho (that tends to be the simplest).
Edit: consider this algorithm instead:
bool PrimeNumber::isPrime(int num) {
if(num < 2)
return false;
if(num == 2)
return true;
if(num % 2 == 0)
return false;
const int root = sqrt(num);
for(int div = 3; div <= root; div += 2) // iterate odd numbers only
if(num % div == 0)
return false;
return true;
}
This is much faster (for large numbers) than the solution proposed by Juraj Blaho.
End Edit.
If you are instead looking for partial solutions (almost prime numbers, numbers that are "probably prime") consider the Rabin-Miller probabilistic primality test (or other tests linked to, from that page).
To check if a number is prime, you just need to check the remainder after division of each number smaller than square root of the tested number. Additionally some extra checks need to be performed for numbers smaller or equal to 1.
bool isPrime(int x)
{
if (x <= 1)
return false;
for (int i = 2; i * i <= x; ++i)
if (x % i == 0)
return false;
return true;
}
If an optimized version without any floating point calculations and square roots is needed:
bool isPrime(int x)
{
if (x <= 1)
return false;
if (x <= 3)
return true;
if (x % 2 == 0)
return false;
for (int i = 2; ; i += 2)
{
const auto result = std::div(x, i);
if (result.rem == 0)
return false;
if (result.quot < i)
return true;
}
return true;
}
Here is my code. I am primarily wanting to know how this compares to other algorithms in terms of speed and memory.
#include <iostream>
using namespace std;
bool isPrime(int input){
for(int i = 2; i <= input; i++)
if(input%i == 0 && i < input)
return false;
return true;
}
int main(){
int input;
cin >> input;
cout << isPrime(input);
}
First of all, your algorithm takes linear time, O(n). You can speed it up tremendously if you check only the numbers up to sqrt(n): (i * i <= n). That being said, if you want to check k numbers of size ~n for being prime, you would end up with O(k sqrt (n)). That's still bad.
In this case, you would built a sieve (Atkins or Eratosthenes), which can be implemented in O(n log log n) for numbers up to n. This way, every following test can be done in O(1).
For one thing you need to be trying odd numbers and stepping by 2, because none of the even candidates (except 2) is itself prime. For another your loop needs to terminate at i <= input / 3 for the same reason. I have increased your execution speed sixfold.
bool isPrime(int input){
int endval = input / 3;
if (input <= 2)
return true;
if ((input & 1) == 0)
return false;
for( int i = 3; i <= endval; i+=2)
if(input%i == 0)
return false;
return true;
}
You could try something like this (not sure if I checked all possible cases). To avoid a potential overflow issue, i <= (input/i) is used instead of (i*i) <= input.
bool isPrime(int input){
int i;
if(input%2 == 0)
return false;
for(i = 3; i <= (input/i); i += 2)
if(input%i == 0)
return false;
return true;
}
I'm trying to print all the prime numbers in series, the code I ended up with is below, instead of printing all primes it prints random numbers, Some are prime and some are not :/
Why is that so?
#include <iostream>
using namespace std;
long int x,y=3;
int a=3;
bool isprime;
int main()
{
while(a<=100)
{
for(x=2;x<=y;x++)
{
if(y%x==0 && x!=y)
{
isprime=false;
break;
}
else if(y%x!=0 && x!=y)
{
isprime = true;
}
}
if(isprime==true && y%x!=0 && x!=y)
{
cout<<a<<" is a prime number."<<"\n";
isprime=false;
}
a++;
y++;
}
}
This
if(isprime=true && a%x!=0 && a!=y)
should be this
if(isprime==true && a%x!=0 && a!=y)
That's a common mistake. But even better is to realise that you don't need to compare bools against true of false, because they are true or false. So just
if (isprime && a%x!=0 && a!=y)
The logic just looks all wrong (and way too complicated), try this
isprime = true;
for(x=2;x<a;x++)
{
if(a%x==0)
{
isprime = false;
break;
}
}
if (isprime)
{
cout<<a<<"\n";
}
No need for y.
Well what jumps into my eyes is that you never increment y.
y is 3 in the beginning, so you only try if 2 is a possible divisor of a and then go to the next a.
Anyway, I am not sure what you wanted to achieve with y.
Let x run from 2 to a/2, as there is no need to try numbers bigger than a/2.
This is simply because there never will be a divisor bigger than a/2.
Example: a = 30. It would not make sense to try to divide by 16 or bigger, as the result can never be a integer (besides a itself of course)
However, this should do what you want:
int x = 0;
int a = 0;
bool isPrime = false;
for(a=3; a < 100; a+=2)
{
isPrime = true;
for(x = 2; x <= a/2; x++) {
if(a%x == 0) {
isPrime = false;
break;
}
}
if(isPrime) {
cout << a << "\n";
}
}
there are of course other algorithms that can find primes, but I wanted to use your approach basically.
Cheers
Chris
EDIT:
Someone was faster :)
anyway: there is no need to run higher than a/2, this is a important optimization...!
EDIT2:
another optimization is of course skipping all even numbers, so start with a = 3 and increment by 2 for each loop iteration...
I see your code is ok now.
Nevertheless I made small changes, cleaning the code and making it a little bit faster.
#include <iostream>
using namespace std;
long int x, y = 2;
int a = 3;
bool isprime;
int main() {
while (a <= 100) {
while ((y + 1) * (y + 1) <= a) {
y++;
}
isprime = true;
for (x = 3; x <= y; x += 2) {
if (a % x == 0) {
isprime = false;
break;
}
}
if (isprime) {
cout << a << " is a prime number." << "\n";
}
a+=2;
}
}
I'm trying to figure out in c++ how to find all the prime numbers in a range (using 100 for now)
I'm not to concerned about performance, I'm starting out in c++ and trying to understand this program exercise from my book. I have my program I'm trying to use below but it keeps returning false. Any ideas? I've read through almost all of googles/bing's help as well as stack overflow. I can write code for it to work with inputting the number; just not looping through all numbers
any ideas on what i'm doing wrong?
#include <iostream>
using namespace std;
bool isPrime(long n);
int main()
{
int i;
//some vars
char emptyVar;
//first loop (to increment the number)
for (i = 0; i <= 100; i++)
{
//checking all numbers below 100
if (isPrime(i) == true)
{
//is true
cout << i << ", ";
}
else if (isPrime(i) == false)
{
//is false
cout <<"false , ";
}
}
cin >> emptyVar;
}
bool isPrime(long n)
{
long i =0;
//checks to see if the number is a prime
for (i = 2; i < n; i++) // sqrt is the highest possible factor
{
if ( n % i == 0) // when dividing numbers there is no remainder if the numbers are both factors
{
// is a factor and not prime
return false;
}
else if (n % i != 0 && i >= 100)
{
//is not a factor
return true;
}
}
}
The function isPrime does not have a return statement for every possible path of execution. For example, what does isPrime do, when n == 2?
Here's how a for loop works (in pseudo code). The general syntax is
for (initialiazion; condition; increment) {
body;
}
rest;
This can be translated into a while-loop:
initialiazion;
while (condition) {
body;
increment;
}
rest;
Especially, the condition is checked right after the intialization, before body is executed.
I suspect, you think that a for loop works like this:
initialiazion;
do {
body;
increment;
} while (condition);
rest;
i.e. the condition is checked after the first increment. But it doesn't.
It should return true if it's not a factor of EVERY i, not just the first one it encounters.
bool isPrime(long n)
{
long i =0;
//checks to see if the number is a prime
for (i = 2; i < n ; i++) // sqrt is the highest possible factor
{
if ( n % i == 0) // when dividing numbers there is no remainder if the numbers are both factors
{
// is a factor and not prime
return false;
}
}
return true;
}
Also in your case you doesn't make sense to search beyond i > n/2.
Of course you should give a look to the literature, the are really robust primality test algorithms.
Your isPrime function is incorrect. It should check all numbers and only then return true;
And this block wouldn't be ever called on your inputs:
else if (n % i != 0 && i >= 100)
{
//is not a factor
return true;
}
A while ago I got an answer to a question on how to code a bool function to check if a number is prime: bool function for prime numbers.
So from this, code that works is
bool prime(int x)
{
if (x < 2) return false;
for(int i=2; i<= sqrt(x); i++) {
if ((x%i) == 0) return false;
}
return true;
}
However if I change the code to
bool prime(int x)
{
if (x < 2) return false;
for(int i=2; i<= sqrt(x); i++) {
if ((x%i) != 0) return true;
}
return false;
}
It doesn't correctly determine whether a number is prime for many integers. I would of thought that these two segments of code would be equivalent. Is there any way of making this bool prime function work with != ?
Thanks.
No. When testing if a number is prime, you know that it is not as soon as you find a single factor.
That's why you can break out of the for loop early and return false in your first example:
if ((x%i) == 0) return false;
Finding that any single number is not a factor does not prove a number to be prime or non-prime, so you cannot terminate early under that condition.
No, it's not possible.
This original code takes advance of the ability to return early if it finds a factor. The modified version returns early the moment it finds a factor. Since you have to test all possible factors (at least, those less than the square root) before being sure that the number is not prime, the method you propose cannot be made to work.
On a side note, a small change can nearly double the efficiency of the algorithm. Since we don't have to test any even numbers larger than 2, we can test 2 first, then start the loop with 3 and increment by 2s:
bool prime(int x)
{
if (x < 2) return false;
if (x%2 == 0) return x == 2;
for(int i=3; i<= sqrt(x); i+=2) {
if ((x%i) == 0) return false;
}
return true;
}