the code is showing wrong results...it is showing 15,21 and many other odd numbers as prime but they are not...how to fix the problem?..what code should I write in main section[inside int main()]?
#include<bits/stdc++.h>
using namespace std;
#define M 1000000
bool marked[M];
bool sieve(int n)
{
for (int i = 3; i * i <= n; i += 2)
{
if (marked[i] == false)
{
for (int j = i * i; j <= n; j += i + i)
{
marked[j] = true;
}
}
}
}
bool isPrime(int n)
{
if (n < 2)
return false;
if (n == 2)
return true;
if (n % 2 == 0)
return false;
return marked[n] == false;
}
int main()
{
int i,j,k,n,m;
cin>>n;
for(i=0; i<n; i++)
{
cin>>m;
if(isPrime(m))
cout<<"prime"<<endl;
else
cout<<"N"<<endl;
}
}
Is the wrong answer coming due to not properly using or calling functions?.....in this case what should be done.....
My guess is that, since you never call the sieve function, your marked array never gets filled. Since marked is not dynamically allocated, it is zeroed out within your program. Hence, in your isPrime function, all odd numbers will cascade through your if statements and then hit the part where marked[n] == false which would return true since marked[n] is 0 for all of its entries, which is equivalent to the boolean false.
You might want to figure out where it would be best to run the sieve function.
You have wrong increment here:
for (int j = i * i; j <= n; j += i + i)
You need to increase j by i, but you actually increase in by 2*i. Anyway I agree with the previous answer that you never call sieve.
Related
Homework: I'm just stumped as hell. I have algorithms set up, but I have no idea how to code this
Just to be clear you do not need arrays or to pass variables by reference.
The purpose of the project is to take a problem apart and using Top-Down_Design or scratch pad method develop the algorithm.
Problem:
Examine the numbers from 2 to 10000. Output the number if it is a Dual_Prime.
I will call a DualPrime a number that is the product of two primes. Ad where the two primes are not equal . So 9 is not a dual prime. 15 is ( 3 * 5 ) .
The output has 10 numbers on each line.
My Algorithm set-up
Step 1: find prime numbers.:
bool Prime_Number(int number)
{
for (int i = 2; i <= sqrt(number); i++)
{
if (number % 1 == 0)
return false;
}
return true;
}
Step 2: store prime numbers in a array
Step 3: Multiply each array to each other
void Multiply_Prime_Numbers(int Array[], int Size)
{
for (int j = 0; j < Size- 1; j++)
{
Dual_Prime[] = Arr[j] * Arr[j + 1]
}
}
Step 4: Bubble sort
void Bubble_Sort(int Array[], int Size) // Sends largest number to the right
{
for (int i = Size - 1; i > 0; i--)
for (int j = 0; j < i; j++)
if (Array[j] > Array[j + 1])
{
int Temp = Array[j + 1];
Array[j + 1] = Array[j];
Array[j] = Temp;
}
}
Step 5: Display New Array by rows of 10
void Print_Array(int Array[], int Size)
{
for (int i = 0; i < Size; i++)
{
cout << Dual_Prime[i] << (((j % 10) == 9) ? '\n' : '\t');
}
cout << endl;
}
I haven't learned dynamic arrays yet,
Although dynamic arrays and the sieve of Eratosthenes are more preferable, I tried to write minimally fixed version of your code.
First, we define following global variables which are used in your original implementation of Multiply_Prime_Numbers.
(Please check this post.)
constexpr int DP_Size_Max = 10000;
int DP_Size = 0;
int Dual_Prime[DP_Size_Max];
Next we fix Prime_Number as follows.
The condition number%1==0 in the original code is not appropriate:
bool Prime_Number(int number)
{
if(number<=1){
return false;
}
for (int i = 2; i*i <= number; i++)
{
if (number % i == 0)
return false;
}
return true;
}
In addition, Multiply_Prime_Numbers should be implemented by double for-loops as follows:
void Multiply_Prime_Numbers(int Array[], int Size)
{
for (int i = 0; i < Size; ++i)
{
for (int j = i+1; j < Size; ++j)
{
Dual_Prime[DP_Size] = Array[i]*Array[j];
if(Dual_Prime[DP_Size] >= DP_Size_Max){
return;
}
++DP_Size;
}
}
}
Then these functions work as follows.
Here's a DEMO of this minimally fixed version.
int main()
{
int prime_numbers[DP_Size_Max];
int size = 0;
for(int j=2; j<DP_Size_Max; ++j)
{
if(Prime_Number(j)){
prime_numbers[size]=j;
++size;
}
}
Multiply_Prime_Numbers(prime_numbers, size);
Bubble_Sort(Dual_Prime, DP_Size);
for(int i=0; i<DP_Size;++i){
std::cout << Dual_Prime[i] << (((i % 10) == 9) ? '\n' : '\t');;
}
std::cout << std::endl;
return 0;
}
The Sieve of Eratosthenes is a known algorithm which speeds up the search of all the primes up to a certain number.
The OP can use it to implement the first steps of their implementation, but they can also adapt it to avoid the sorting step.
Given the list of all primes (up to half the maximum number to examine):
Create an array of bool as big as the range of numbers to be examined.
Multiply each distinct couple of primes, using two nested loops.
If the product is less than 10000 (the maximum) set the corrisponding element of the array to true. Otherwise break out the inner loop.
Once finished, traverse the array and if the value is true, print the corresponding index.
Here there's a proof of concept (implemented without the OP's assignment restrictions).
// Ex10_TwoPrimes.cpp : This file contains the 'main' function. Program execution begins and ends there.
#include "pch.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void Homework_Header(string Title);
void Do_Exercise();
void Sieve_Of_Eratosthenes(int n);
void Generate_Semi_Prime();
bool Semi_Prime(int candidate);
bool prime[5000 + 1];
int main()
{
Do_Exercise();
cin.get();
return 0;
}
void Do_Exercise()
{
int n = 5000;
Sieve_Of_Eratosthenes(n);
cout << endl;
Generate_Semi_Prime();
}
void Sieve_Of_Eratosthenes(int n)
{
// Create a boolean array "prime[0..n]" and initialize
// all entries it as true. A value in prime[i] will
// finally be false if i is Not a prime, else true.
memset(prime, true, sizeof(prime));
for (int p = 2; p*p <= n; p++)
{
// If prime[p] is not changed, then it is a prime
if (prime[p] == true)
{
// Update all multiples of p
for (int i = p * p; i <= n; i += p)
prime[i] = false;
}
}
}
bool Semi_Prime(int candidate)
{
for (int index = 2; index <= candidate / 2; index++)
{
if (prime[index])
{
if (candidate % index == 0)
{
int q = candidate / index;
if (prime[q] && q != index)
return true;
}
}
}
return false;
}
void Generate_Semi_Prime()
{
for (int i = 2; i <= 10000; i++)
if (Semi_Prime(i)) cout << i << "\t";
}
So I have the following problem. They give me an array w/ n numbers and I have to print if it contains any prime numbers using "Divide et Impera". I solved the problem but it gets only 70/100 because it isn't efficient(they say).
#include <iostream>
using namespace std;
bool isPrime(int x){
if(x == 2) return false;
for(int i = 2; i <= x/2; ++i)
if(x%i==0) return false;
return true;
}
int existaP(int a[], int li, int ls){
if(li==ls)
if(isPrime(a[li]) == true) return 1;
else return 0;
else return existaP(a, li, (li+ls)/2)+existaP(a, (li+ls)/2+1, ls);
}
int main(){
int n, a[10001];
cin >> n;
for(int i = 1; i<=n; ++i) cin >> a[i];
if(existaP(a,1,n) >= 1) cout << "Y";
else cout << "N";
return 0;
}
The lowest hanging fruit here is your stopping conditional
i <= x/2
which can be replaced with
i * i <= x
having taken care to ensure you don't overflow an int.This is because you only need to go up to the square root of x, rather than half way. Perhaps i <= x / i is better still as that avoids the overflow; albeit at the expense of a division which can be relatively costly on some platforms.
Your algorithm is also defective for x == 2 as you have the incorrect return value. It would be better if you dropped that extra test, as the ensuing loop covers it.
Here is an efficinent way to check prime number.
bool isPrime(int num) {
if(num <= 1) return false;
if (num <= 3) return true;
int range = sqrt(num);
// This is checked so that we can skip
// middle five numbers in below loop
if (num % 2 == 0 || num % 3 == 0)
return false;
for (int i = 5; i <= range; i += 6)
if (num % i == 0 || num % (i + 2) == 0)
return false;
return true;
}
A stander way(maybe..?) is just check from i = 0 to the sqrt(number)
bool isPrime(int num){
if(num == 1) return false;
for(int i = 2;i<=sqrt(num);i++){
if(num % i == 0) return false;
}
return true;
}
bool isprime(int x)
{
if(x <= 1) return false;
if(x == 2 || x == 3) return true;
if(x % 2 == 0 || x % 3 == 0) return false;
if((x - 1) % 6 != 0 && (x + 1) % 6 != 0) return false;
for(int i = 5; i * i <= x; i += 6)
{
if(x % i == 0 || x % (i + 2) == 0) return false;
}
return true;
}
If prime numbers need to be printed for a particular range or to determine whether a number is prime or not, the sieve of the eratosthenes algorithm is probably preferable as it is very efficient in terms of time complexity O( n * log2( log2(n) ) ), but the space complexity of this algorithm can cause an issue if the numbers are exceeding certain memory limit.
We can optimize this simpler algorithm which has a time complexity of O(n1/2) by introducing few additional checks based on this thoerem as shown in the above isprime code block.
Despite the fact that Sieve of Erathosthenes algorithm is efficient in terms of time complexity under space restrictions, the above provided isprime code block can be utilized, and there are numerous variations of the Sieve of Erathosthenes algorithm that perform considerably better, as explained in this link.
Many more algorithms exist, but in terms of solving coding challenges, this one is simpler and more convenient. You can learn more about them by clicking on the following links:
https://www.quora.com/Whats-the-best-algorithm-to-check-if-a-number-is-prime
https://www.baeldung.com/cs/prime-number-algorithms#:~:text=Most%20algorithms%20for%20finding%20prime,test%20or%20Miller%2DRabin%20method.
Your code will give a wrong answer if n is 1.
Your time complexity can be decreased to sqrt(n) , where n is the number.
Here is the code
bool isPrime(long int n)
{
if (n == 1)
{
return false;
}
int i = 2;
while (i*i <= n)
{
if (n % i == 0)
{
return false;
}
i += 1;
}
return true;
}
The "long int" will help to avoid overflow.
Hope this helps. :-)
If the numbers are not too big you could also try to solve this using the sieve of Eratosthenes:
#include <iostream>
#include <array>
using namespace std;
constexpr int LIMIT = 100001;
// not_prime because global variables are initialized with 0
bool not_prime[LIMIT];
void sieve() {
int i, j;
not_prime[2] = false;
for(int i = 2; i < LIMIT; ++i)
if(!not_prime[i])
for(int j = i + i; j < LIMIT; j += i)
not_prime[j] = true;
}
int existaP(int a[], int li, int ls){
if(li==ls)
if(!not_prime[a[li]] == true)
return 1;
else
return 0;
else
return existaP(a, li, (li + ls) / 2) + existaP(a, (li + ls) / 2 + 1, ls);
}
int main(){
int n, a[10001];
cin >> n;
for(int i = 1; i<=n; ++i) cin >> a[i];
sieve();
if(existaP(a,1,n) >= 1) cout << "Y";
else cout << "N";
return 0;
}
Basically when you encounter a prime all the numbers that are a multiple of it won't be primes.
P.S.: Acum am vazut ca esti roman :)
Poti sa te uiti aici pentru a optimiza si mai mult algoritmul: https://infoarena.ro/ciurul-lui-eratostene
Another inefficiency not yet mentioned is existaP(a, li, (li+ls)/2) + existaP(a, (li+ls)/2+1, ls);
In particular, the problem here is the +. If you know existaP(a, li, (li+ls)/2) > 0, then existaP(a, (li+ls)/2+1, ls) no longer matters. In other words, you're currently counting the exact number of unique factors, but as soon as you know a number has at least two factors you know it's not prime.
Here is one efficient way to check a given number is prime.
bool isprime(int n) {
if(n<=1)
return false;
if(n<=3)
return true;
if(n%2==0||n%3==0)
return false;
for(int i=5;i*i<=n;i=i+6) {
if(n%i==0||n%(i+2)==0)
return false;
}
return true;
}
This is a much faster algorithm in my opinion. It works on the Euclidean algorithm to calculate H.C.F. Basically, I check if the HCF of the number AND the consecutively second number is 1; and if the number itself is divisible by either 2 or 3. Don't ask how I mathematically reached the solution, it just struck me :D. The time complexity of this solution is O(log (max(a,b))), which is notably smaller than the time complexity of the program which runs a loop counter 2 to sqrt(n) is O(sqrt(n)).
#include <iostream>
using namespace std;
int hcf(int, int);
int hcf(int a, int b)
{
if (b == 0)
{
return a;
}
return hcf(b, a % b);
}
int main()
{
int a;
cout << "\nEnter a natural number: ";
cin >> a;
if(a<=0)
{
cout << "\nFor conventional reasons we keep the discussion of primes to natural numbers in this program:) (Read: Ring of Integers / Euclid's Lemma)";
return 0;
}
if (a == 1)
{
cout << "\nThe number is neither composite nor prime :D";
return 0;
}
if (a == 2)
{
cout << "\nThe number is the only even Prime :D";
return 0;
}
if (hcf(a, a + 2) == 1)
{
if (a % 2 != 0 && a % 3 != 0)
{
cout << "\nThe number is a Prime :D";
return 0;
}
}
cout << "\nThe number is not a Prime D:";
return 0;
}
Correct me if I'm wrong. I'm a student.
I wrote this code to print all prime numbers between 3 and 'n' inputted by the user, but upon running, it produces nothing.
Can you please help?
#include <iostream>
using namespace std;
int main()
{
int n;
cin >> n;
for (int candidate = 3; candidate < n; ++candidate)
{
bool isPrime = true;
for (int x = 2; x < n; x++)
{
if (candidate % x == 0)
{
isPrime = false;
}
}
if (isPrime)
{
cout << n << "";
}
}
}
One thing you should know. For checking whether n is prime if we start checking by division operation then you shouldn't check more than sqrt(n).
for (int candidate = 3; candidate < n; ++candidate)
{
bool isPrime = true;
for (int x = 2; x*x < candidate; x++)
{
if (candidate % x == 0)
{
isPrime = false;
break;
}
}
if (isPrime)
{
cout << candidate << "";
}
}
Better way is to use Sieve of Eratosthenes for this:
isPrime: initialize with all true
for(int i=2;i*i<=n;i++)
for(int j =i*i;j<=n;j+=i)
isPrime[j]=false; // the if was not needed.
Now you know which are primes between 3 and n.
There are several efficiency savings possible in your code. The most efficient method (apart from using a pre-calculated look-up table for small (<1000) n) is the sieve of Erastosthenes.
A very naive version of this algorithm (see also the answer by
coderredoc)
std::vector<int> primes(int n)
{
std::vector<bool> is_prime(n+1,true);
for(auto divisor=2; divisor*divisor <= n; ++divisor)
for(auto candidate=divisor*divisor; candidate <= n; candidate+=divisor)
is_prime[candidate]=false;
std::vector<int> result;
for(auto candidate=2; candidate <= n; ++candidate)
if(is_prime[candidate]) result.push_back(candidate);
return result;
}
essentially reverses the loops over candidates and divisors compared to your original algorithm, but only tests for divisors satisfying divisor*divisor<=candidate.
This algorithm can be substantially improved by realizing that we only need to test for prime divisors (which is the main trick of the sieve)
std::vector<int> primes(int n)
{
std::vector<bool> is_prime(n+1,true);
for(auto divisor=2; divisor*divisor <= n; ++divisor)
if(is_prime[divisor])
for(auto candidate=divisor*divisor; candidate <= n; candidate+=divisor)
is_prime[candidate]=false;
std::vector<int> result;
for(auto candidate=2; candidate <= n; ++candidate)
if(is_prime[candidate]) result.push_back(candidate);
return result;
}
which cuts down on the testing for large n. A further efficiency saving (by a factor ~2 in space and time) is possible by avoiding even candidates and divisors:
std::vector<int> primes(int n)
{
if(n<2) return {};
if(n==2) return {2};
std::vector<bool> is_prime((n+1)>>1,true);
for(auto divisor=3; divisor*divisor <= n; divisor+=2)
if(is_prime[divisor>>1])
for(auto candidate=divisor*divisor; candidate <= n; candidate+=2*divisor)
is_prime[candidate>>1]=false;
std::vector<int> result(1,2);
for(auto candidate=3; candidate <= n; candidate+=2)
if(is_prime[candidate>>1]) result.push_back(candidate);
return result;
}
This algorithm has a poor memory access pattern (into the is_prime[]), which becomes a problem for very large n. A more sophisticated method, segmented sieve, can avoid that, see the above link.
Change your inner loop from
for (int x = 2; x < n; x++)
{
if (candidate % x == 0)
{
isPrime = false;
}
}
to
for (int x = 2; x < candidate; x++)
{
if (candidate % x == 0)
{
isPrime = false;
break;
}
}
otherwise x would eventually become candidate itself and candidate%candidate is 0 which would cause isPrime to become false.
The break statement is used because after being sure that the number is not prime, there's no need of further iterations.
And since you consider only numbers from 3, you could change your outer loop to save some iterations like
for (int candidate = 3; candidate < n; candidate+=2)
This would increment candidate by 2 each time. This is okay because no even numbers greater than 2 are not prime.
Also, if the range of numbers you are considering is inclusive of n, you may modify the outer for loop to
for (int candidate = 3; candidate < n; candidate+=2)
to consider n as well.
It's not recommended to use using namespace std; — because this imports all of the identifiers from std. See this question on Stack Overflow.
Should the end condition of the second loop be candidate instead of n, i.e.
for (int x = 2; x < candidate; x++)//not before N prime numbers divine up to them
{
if (candidate % x == 0)
isPrime = false;
}
Shouldn't you put out candidate instead of n
I think this should work
#include <iostream>
#include <vector>
int main()
{
//setup start parameters
//test sequence
std::vector<int> test_sequence {2};
int end_number, start_number;
start_number = 3;
//take wished end number
std::cin >> end_number;
// test is wished number smaler than start number
if (start_number < end_number)
{
// loop which goes trough every number between start and end number
for (start_number; start_number <= end_number; start_number++)
{
bool isPrime = true;
//test is this number prime
for (int n = 0; n < test_sequence.size(); n++)
{
if (start_number % test_sequence[n] == 0 && start_number != test_sequence[n] )
{
isPrime = false;
}
}
if (isPrime)
{
std::cout << start_number << std::endl;
//hold result for next test
test_sequence.push_back(start_number);
}
}
}
else
{
std::cout << "Wrong input";
}
}
Result for first 200
Doing this question on SPOJ, trying to implement a sieve and a segmented sieve to get the desired primes. My code is as follows:
//Prime Generator
#include <iostream>
#include <math.h>
#include <cstdio>
using namespace std;
int main() {
//traditional sieve
int squareRoot = sqrt(1000000000);
//printf("%d\n\n", squareRoot);
bool primeList[squareRoot] = {false}; //all primes are marked as true, composite is false
//make entire array true
for (int i = 1; i < squareRoot; i++){
primeList[i] = true;
}
//traditional sieve to find primes first
for (int i = 2; i <= squareRoot; i++){
for (int j = i*i; j <= squareRoot; j+=i){
//composites are marked as false
primeList[j - 1] = false;
}
}
//segmented sieve + output
int a;
scanf("%d", &a);
while (a > 0){
int m, n;
scanf("%d%d", &m, &n);
//if lower than this range, then we can just output the primes we already computed
if (n <= squareRoot){
for (int i = m; i <= n; i++){
if (primeList[i - 1] == true){
printf("%d\n", i);
}
}
printf("\n");
}
//it is beyond this range, so we need to segment sieve
else {
int upperLimit = sqrt(n); //highest we need to divide by
int diff = n - m;
bool myPrimes[diff + 1];
for (int i = 0; i <= diff; i++){
myPrimes[i] = true;
}
for (int i = 2; i <= upperLimit; i++){
if (primeList[i - 1] == true){
int lowest = m/i * i;
while (lowest < m){
lowest += i;
}
while (lowest <= n){
myPrimes[lowest - m] = false;
lowest += i;
}
}
}
for (int i = m; i <= n; i++){
if (myPrimes[i - m] == true){
printf("%d\n", i);
}
}
printf("\n");
}
a--;
}
}
The basic logic I'm trying to do is:
First do a sieve of Eratosthenes to generate all the primes up to the sqrt of 10^9, since 10^9 is the upper limit of n.
If n is below sqrt(10^9), then I do not calculate anything new, just output the appropriate primes from (1).
If n is above sqrt(10^9), then I first calculate sqrt(n), which is the largest number we'd need, as any number bigger would not be divisible in the range [m, n].
Then I'd do the actual sieve, starting from 2, and trying to mark as false all numbers that are a multiple of a prime. I do 'lowest = m/i * i' to get the number that is the closest to m, where lowest <= m. If it is lower than m, then I add until it is just above m. I.E. if m==125 and n == 200, then 125/2 = 62, 62*2 = 124. 124+2 == 126, which would be the first number that is a multiple of 2 in the series [125,200].
Then we output any numbers that have no been marked false.
My issue is it seems my algorithm is correct (to me). I'm more than certain my first sieve works, but it seems that it might falter at generating primes larger than sqrt(10^9). However, from my testing it seems it does generate all the primes (and only primes). Is my algorithm to generate primes too uncertain? Is it a one-off issue with rounding?
My guess is that the error comes from
for (int i = 2; i <= upperLimit; i++){
if (primeList[i - 1] == true){
int lowest = m/i * i;
while (lowest < m){
lowest += i;
}
while (lowest <= n){
myPrimes[lowest - m] = false;
lowest += i;
}
}
}
But I can't tell where. Any tips or pointers would be welcome!
I got the mistake , its in the second case where you are defining myPrimes[diff] = {true} . But think of the where the time when input is like
m = 1 and n > sqrt(1000000000) then it would give 1 as a prime number.
Hope that would make accept you answer.
I am trying to print the nth number of the series
2,23,235,2357,235711,23571113...
but i am not getting the right output after n=3.
At n=3 it's giving 234 which is wrong
#include<stdio.h>
#include<math.h>
main()
{
unsigned int t, n, p, i, j, d;
int s;
scanf("%d", &t);
if (t <= 10)
{
while (t != 0)
{
scanf("%d", &n);
p = n;
j = 2;
s = 0;
while (p > 0)
{
d = prime(j);
// printf("%d",d);
if (d == 1)
{
s = s + j * pow(10, p - 1);
p--;
j++;
}
else
j++;
}
printf("%d", s);
t--;
}
}
}
int prime(int num)
{
int i, flag = 1, n;
// n=sqrt(num);
for (i = 2; (i <= num / 2) && (flag == 1); i++)
{
if (num % i == 0)
flag = 0;
}
if (flag == 0)
return 0;
else
return 1;
}
I am trying to generate a prime number after each iteration.
So you're generating primes and want to output strings of the concatenated primes.
Write a function filling an array with the first n primes. That's easy.
Then you write an output function like:
for (i = 0; i < n; ++i) {
for (j = 0; j <= i; ++j) {
printf("%d", arr[j]);
}
printf("\n"); /* or any other separator */
}
No trouble any more with large numbers, until you reach primes in the order of magnitude of a billion.
In some low-quality C implementations, the pow function does not return a correct result even when the mathematical result is exactly representable in the floating-point format. E.g., pow(10, 2) may return 99.9999999999999857891452847979962825775146484375 instead of 100.
When a floating-point value that is not an integer is assigned to an integer object, the value is converted to an integer by truncation. Thus, for example, 234.9999847412109375 would become 234.
Generally, you should avoid using floating-point functions such as pow for integer arithmetic. However, for reasonably small values where you know the result of pow should be exactly an integer, you can correct the result by using round: round(pow(10, p - 1)).
Without using any extra space and inbuilt function !
#include<stdio.h>
int isPrime(int p)
{
int i;
for(i=2;i*i<=p;i++)
if(p%i==0)
return 0;
return 1;
}
int main()
{
int n=10,count=0,p=2;
while(count<n)
{
if(isPrime(p))
{
printf("%d",p);
count++;
}
p++;
}
}
even you can get rid of "count" variable by decrementing 'n'. and optimize this code by considering the fact that even numbers are not prime number (or all prime numbers are of the form of 6n+1 or 6n-1 ).