Im doing exercise from the Bjarne Stroustrup book called "Programming principles and practice using c++". I have to find first n prime numbers that user wants[user enters 5, and program finds first five prime numbers]. I found the solution on this site:
http://people.ds.cam.ac.uk/nmm1/C++/Exercises/Chapter_04/ex_15.cpp
bool prime (vector<int> table, int number) {
for (int i = 0; i < table.size(); ++i)
if (number%table[i] == 0) return false;
return true;
}
but i cant understand the test for primality. Why modulo? I have my own test for primality and its much easier to understand for me, albeit its less elegant and more verbose.
bool isPrime(int num) {
for (int i = 2; i < num; i++) {
for (int j = 0; j < num; j++) {
if (i*j == num) {
return false;
}
}
}
if (num == 1) {
return false;
}
return true;
}
So if anyone can explain me that guy code i would be greatful.
Here's the other code, included in its entirety:
#include "std_lib_facilities.h"
bool prime (vector<int> table, int number) {
for (int i = 0; i < table.size(); ++i)
if (number%table[i] == 0) return false;
return true;
}
int main () {
int count, next;
cout << "Input the number of primes\n";
cin >> count;
vector<int> table;
next = 2;
while (table.size() < count) {
if (prime(table,next)) table.push_back(next);
++next;
}
for (int n = 0; n < table.size(); ++n)
cout << table[n] << " ";
cout << endl;
// keep_window_open();
return 0;
}
This code populates the vector table with all the prime numbers it has found so far. Starting from 2, it checks if the number is divisible by any of the numbers in this table it has constructed. If it isn't divisible, it means that this number is a prime, and it gets entered into the table.
The modulo operator is used to check for divisibility here. a%b returns the remainder that occurs when the division a/b is performed. If this value is 0, there is no remainder, and we can conclude that a is divisible by b.
The modulo operator returns the remainder of a division operation. So if the remainder is equal to 0 for any of the numbers in the table, then we can say that the number is evenly divisible, and therefore not prime. On the other hand, if the modulo returns anything other than 0 for all of the numbers in the table, the number is not evenly divisible, and therefore it is prime.
https://www.cprogramming.com/tutorial/modulus.html
Welcome to StackOverflow :)
Related
I have a program like this: given a sequence of integers, find the biggest prime and its positon.
Example:
input:
9 // how many numbers
19 7 81 33 17 4 19 21 13
output:
19 // the biggest prime
1 7 // and its positon
So first I get the input, store it in an array, make a copy of that array and sort it (because I use a varible to keep track of the higest prime, and insane thing will happen if that was unsorted) work with every number of that array to check if it is prime, loop through it again to have the positon and print the result.
But the time is too slow, can I improve it?
My code:
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
int main()
{
int n;
cin >> n;
int numbersNotSorted[n];
int maxNum{0};
for (int i = 0; i < n; i++)
{
cin >> numbersNotSorted[i];
}
int numbersSorted[n];
for (int i = 0; i < n; i++)
{
numbersSorted[i] = numbersNotSorted[i];
}
sort(numbersSorted, numbersSorted + n);
for (int number = 0; number < n; number++)
{
int countNum{0};
for (int i = 2; i <= sqrt(numbersSorted[number]); i++)
{
if (numbersSorted[number] % i == 0)
countNum++;
}
if (countNum == 0)
{
maxNum = numbersSorted[number];
}
}
cout << maxNum << '\n';
for (int i = 0; i < n; i++)
{
if (numbersNotSorted[i] == maxNum)
cout << i + 1 << ' ';
}
}
If you need the biggest prime, sorting the array brings you no benefit, you'll need to check all the values stored in the array anyway.
Even if you implemented a fast sorting algorithm, the best averages you can hope for are O(N + k), so just sorting the array is actually more costly than looking for the largest prime in an unsorted array.
The process is pretty straight forward, check if the next value is larger than the current largest prime, and if so check if it's also prime, store the positions and/or value if it is, if not, check the next value, repeat until the end of the array.
θ(N) time compexity will be the best optimization possible given the conditions.
Start with a basic "for each number entered" loop:
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
int main() {
int n;
int newNumber;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> newNumber;
}
}
If the new number is smaller than the current largest prime, then it can be ignored.
int main() {
int n;
int newNumber;
int highestPrime;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> newNumber;
if(newNumber >= highestPrime) {
}
}
}
If the new number is equal to the highest prime, then you just need to store its position somewhere. I'm lazy, so:
int main() {
int n;
int newNumber;
int highestPrime;
int maxPositions = 1234;
int positionList[maxPositions];
int nextPosition;
int currentPosition = 0;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> newNumber;
currentPosition++;
if(newNumber >= highestPrime) {
if(newNumber == highestPrime) {
if(nextPosition+1 >= maxPositions) {
// List of positions is too small (should've used malloc/realloc instead of being lazy)!
} else {
positionList[nextPosition++] = currentPosition;
}
}
}
}
}
If the new number is larger than the current largest prime, then you need to figure out if it is a prime number, and if it is you need to reset the list and store its position, etc:
int main() {
int n;
int newNumber;
int highestPrime = 0;
int maxPositions = 1234;
int positionList[maxPositions];
int nextPosition;
int currentPosition = 0;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> newNumber;
currentPosition++;
if(newNumber >= highestPrime) {
if(newNumber == highestPrime) {
if(nextPosition+1 >= maxPositions) {
// List of positions is too small (should've used malloc/realloc instead of being lazy)!
} else {
positionList[nextPosition++] = currentPosition;
}
} else { // newNumber > highestPrime
if(isPrime(newNumber)) {
nextPosition = 0; // Reset the list
highestPrime = newNumber;
positionList[nextPosition++] = currentPosition;
}
}
}
}
}
You'll also want something to display the results:
if(highestPrime > 0) {
for(nextPosition= 0; nextPosition < currentPosition; nextPosition++) {
cout << positionList[nextPosition];
}
}
Now; the only thing you're missing is an isPrime(int n) function. The fastest way to do that is to pre-calculate a "is/isn't prime" bitfield. It might look something like:
bool isPrime(int n) {
if(n & 1 != 0) {
n >>= 1;
if( primeNumberBitfield[n / 32] & (1 << (n % 32)) != 0) {
return true;
}
}
return false;
}
The problem here is that (for positive values in a 32-bit signed integer) you'll need 1 billion bits (or 128 MiB).
To avoid that you can use a much smaller bitfield for numbers up to sqrt(1 << 31) (which is only about 4 KiB); then if the number is too large for the bitfield you can use the bitfield to find prime numbers and check (with modulo) if they divide the original number evenly.
Note that Sieve of Eratosthenes ( https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes ) is an efficient way to generate that smaller bitfield (but is not efficient to use for a sparse population of larger numbers).
If you do it right, you'll probably create the illusion that it's instantaneous because almost all of the work will be done while a human is slowly typing the numbers in (and not left until after all of the numbers have been entered). For a very fast typist you'll have ~2 milliseconds between numbers, and (after the last number is entered) humans can't notice delays smaller than about 10 milliseconds.
But the time is too slow, can I improve it?
Below loop suffers from:
Why check smallest values first? Makes more sense to check largest values first to find the largest prime. Exit the for (... number..) loop early once a prime is found. This takes advantage of the work done by sort().
Once a candidate value is not a prime, quit testing for prime-ness.
.
// (1) Start for other end rather than as below
for (int number = 0; number < n; number++) {
int countNum {0};
for (int i = 2; i <= sqrt(numbersSorted[number]); i++) {
if (numbersSorted[number] % i == 0)
// (2) No point in continuing prime testing, Value is composite.
countNum++;
}
if (countNum == 0) {
maxNum = numbersSorted[number];
}
}
Corrections left for OP to implement.
Advanced: Prime testing is a deep subject and many optimizations (trivial and complex) exist that are better than OP's approach. Yet I suspect the above 2 improvement will suffice for OP.
Brittleness: Code does not well handle the case of no primes in the list or n <= 0.
i <= sqrt(numbersSorted[number]) is prone to FP issues leading to an incorrect results. Recommend i <= numbersSorted[number]/i).
Sorting is O(n * log n). Prime testing, as done here, is O(n * sqrt(n[i])). Sorting does not increase O() of the overall code when the square root of the max value is less than log of n. Sorting is worth doing if the result of the sort is used well.
Code fails if the largest value was 1 as prime test incorrectly identifies 1 as a prime.
Code fails if numbersSorted[number] < 0 due to sqrt().
Simply full-range int prime test:
bool isprime(int num) {
if (num % 2 == 0) return num == 2;
for (int divisor = 3; divisor <= num / divisor; divisor += 2) {
if (num % divisor == 0) return false;
}
return num > 1;
}
If you want to find the prime, don't go for sorting. You'll have to check for all the numbers present in the array then.
You can try this approach to do the same thing, but all within a lesser amount of time:
Step-1: Create a global function for detecting a prime number. Here's how you can approach this-
bool prime(int n)
{
int i, p=1;
for(i=2;i<=sqrt(n);i++) //note that I've iterated till the square root of n, to cut down on the computational time
{
if(n%i==0)
{
p=0;
break;
}
}
if(p==0)
return false;
else
return true;
}
Step-2: Now your main function starts. You take input from the user:
int main()
{
int n, i, MAX;
cout<<"Enter the number of elements: ";
cin>>n;
int arr[n];
cout<<"Enter the array elements: ";
for(i=0;i<n;i++)
cin>>arr[i];
Step-3: Note that I've declared a counter variable MAX. I initialize this variable as the first element of the array: MAX=arr[0];
Step-4: Now the loop for iterating the array. What I did was, I iterated through the array and at each element, I checked if the value is greater than or equal to the previous MAX. This will ensure, that the program does not check the values which are less than MAX, thus eliminating a part of the array and cutting down the time. I then nested another if statement, to check if the value is a prime or not. If both of these are satisfied, I set the value of MAX to the current value of the array:
for(i=0;i<n;i++)
{
if(arr[i]>=MAX) //this will check if the number is greater than the previous MAX number or not
{
if(prime(arr[i])) //if the previous condition satisfies, then only this block of code will run and check if it's a prime or not
MAX=arr[i];
}
}
What happens is this- The value of MAX changes to the max prime number of the array after every single loop.
Step-5: Then, after finally traversing the array, when the program finally comes out of the loop, MAX will have the largest prime number of the array stored in it. Print this value of MAX. Now for getting the positions where MAX happens, just iterate over the whole loop and check for the values that match MAX and print their positions:
for(i=0;i<n;i++)
{
if(arr[i]==MAX)
cout<<i+1<<" ";
}
I ran this code in Dev C++ 5.11 and the compilation time was 0.72s.
I am new to c++ and I have been tasked to write a code which finds the smallest prime factor of a number using recursion. If N is less than 2 the code should return 1. If N is a prime number itself the code should return N. Otherwise the code should return the smallest prime factor of N. I have attempted the question but I have used a for loop to check for the lowest prime factor and I am unsure if this method in the context of my answer is iterative or recursive. To call the function for main the user should enter lowestPrimeFactor(x);, where x is the number they want to find the lowest prime factor for. I am stuck with trying to change the iterative section to recursive, where the code checks for the lowest prime factor. I would appreciate any feedback.
#include <stdio.h>
#include <iostream>
#include <math.h>
long lowestPrimeFactor(long N, long i=2) {
if(N<2){ //if N is less than 2, return 1
std::cout << 1; //print to screen to check
return 1;
}
bool isPrime =true; //Check if number is prime
for(i=2;i<=N/2; ++i){
if(N%i==0){
isPrime=false;
break;
}
}
if (isPrime){
std::cout<<N;
return N;
}
for (int i = 3; i* i <= N; i+=2){ //This is where I am unsure how to translate to recursive as it is based of an iterative solution
if(N%i == 0)
std::cout<<i;
return i;
}
//Driver code to check functionality
int main(){
lowestPrimeFactor(19);
}
EDIT
I think I have modified the code correctly to be recursive for the prime factor check
//Recursive
if(i*i<=N){
N%i==0; lowestPrimeFactor(i);
}
else return i;
Just need to try and adjust the bool part to be recursive too
Try this:
#include <iostream>
using namespace std;
long lowestPrimeFactor(long N, long i = 2) {
if (N % i == 0) // Test for factor
return i;
else if (i < N * N)
return lowestPrimeFactor(N, i + 1); // Test next factor
else
return N;
}
void test(long N){
// Format results
cout << N << " gives " << lowestPrimeFactor(N) << endl;
}
int main() {
for (long N = 2; N < 30; ++N) // Generate some test cases
test(N);
}
This has the inefficiency that it tests for non-prime factors too (which I think the original solution also does) so really rather than recursing with i + 1 (the next integer after i) we should be calculating and passing in the next prime after i.
The required code, if you want to use recursion for checking out the lowest prime factor instead of the last for loop would be as follows:
#include <iostream>
long lowestPrimeFactor(long N,long pr = 3)
{
bool isPrime =true;
if(N<2)
{ //if N is less than 2, return 1
std::cout << N << std::endl;//print to screen to check
return 1;
}
else
{
for(long i=2;i<=N/2; ++i)
{
if(N%i==0)
{
isPrime=false;
break;
}
}
}
if(isPrime)
{
std::cout << N << std::endl;
return N;
}
else
{
if(N%2==0){
std::cout << 2 << std::endl;
return 2;
}
else
{
if(N%pr == 0)
{
std::cout << pr << std::endl;
return pr;
}
else
{
return lowestPrimeFactor(N,pr+2);
}
}
}
}
//Driver code to check functionality
int main()
{
lowestPrimeFactor(19);
lowestPrimeFactor(20);
lowestPrimeFactor(7);
lowestPrimeFactor(1);
lowestPrimeFactor(15);
}
This isn't fully recursive but it checks for only prime numbers till 7 after which it checks for 9 and so on i.e odd numbers which even the original code had.
Note: Prime factors it checks properly: 2,3,5,7 and prime numbers
I wrote a C++ program that prints all prime numbers lower than n, but the program keeps crashing while executing.
#include <iostream>
using namespace std;
bool premier(int x) {
int i = 2;
while (i < x) {
if (x % i == 0)
return false;
i++;
}
return true;
}
int main() {
int n;
int i = 0;
cout << "entrer un entier n : ";
cin >> n;
while (i < n) {
if (n % i == 0 && premier(i))
cout << i;
i++;
}
;
}
As Igor pointed out, i is zero the first time when n%i is done. Since you want only prime numbers and the smallest prime number is 2, I suggest you initialise i to 2 instead of 0.
You want to print all prime numbers less than n and has a function to check primality already.
Just
while (i < n){
if ( premier(i) == true )
cout<<i;
i++;
}
And while printing, add a some character to separate the numbers inorder to be able to distinguish them like
cout<<i<<endl;
P.S: I think you call this a C++ program. Not a script.
Edit: This might interest you.
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;
}
This code is to find the prime numbers from 3 to n, n being an input. this code works perfect but I need to understand it much more clearly mostly the part within the nested for loop.
#include <iostream>
using namespace std;
int main ()
{
cout << "Please enter a number: \n";
int inputtedNumber;
cin >> inputtedNumber;
cout <<"the primes between 3 and that number are: \n";
int candidate = inputtedNumber;
for (int i=3; i<candidate; i++)
{
bool prime=true;
for (int j=2; j*j<=i;j++)
{
if (i % j == 0)
{
prime=false;
break;
}
}
if(prime) cout << i << "\n";
}
system("pause");
return 0;
}
thank you!
The inner loop looks at each number from 2 to the square root of i, to see if i is divisible by that number. If i is divisible by j, then i%j will be zero. If it finds a divisor, then we know it's not prime and can stop looking.
There's no need to go beyond the square root since, if there is a divisor larger than that, there must also be a corresponding divisor smaller than that, which will already have been found by this loop.
This line is key.
if (i % j == 0)
The if block is executed if i is divisible by j, which implies that i is not prime.
for (int i=3; i<candidate; i++) // for every i between 3 and candidate
{
bool prime=true;
for (int j=2; j*j<=i;j++) // for every j between 2 and the square root of i
{
if (i % j == 0) // if there is an i that is evenly divisible by j
{
prime=false; // set the flag
break; // break the inner loop
}
}
if(prime) cout << i << "\n"; // if i was a prime (no j's were evenly divisible), print it
}