This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Which is the fastest algorithm to find prime numbers?
is there any way to make this more optimize..
#include <vector>
int main()
{
std::vector<int> primes;
primes.push_back(2);
for(int i=3; i < 100; i++)
{
bool prime=true;
for(int j=0;j<primes.size() && primes[j]*primes[j] <= i;j++)
{
if(i % primes[j] == 0)
{
prime=false;
break;
}
}
if(prime)
{
primes.push_back(i);
cout << i << " ";
}
}
return 0;
}
int main(int argc, char *argv[]) {
cout << "2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 ";
}
:-)
More seriously, you could avoid repeatedly squaring the primes by caching primes[j] * primes[j] and save on multiplications.
Sieve of Eratosthenes is a great algorithm for generating prime numbers up to a certain number (which is not what your title states, but what your code implies).
Yes, change i++ to i+=2 and it will work twice as fast.
do not do primes[j]*primes[j] <= i just check primes[j] <= 7
use i+=2
Yes. As Marion has suggested, you can use the Sieve of Eratosthenes but you should be aware of the details. The code you have written looks superficially like the sieve, but it isn't. It's called trial division and it has a different algorithmic complexity than the sieve.
The sieve performs a pass which takes Theta(n/p) time for each prime p. This results in a total complexity of O(n log log n). IIRC the proof is a bit complicated and involves the prime number theorem.
Your algorithm performs pi(sqrt(p)) divisions for each prime number p and a smaller number of divisions for non-primes. (where pi is the prime-counting function). Unfortunately I can't come up with the total complexity off the top of my head.
In short, you should change the code to use an array and mark all the non-primes.
This article addresses the same topic in functional programming languages.
Yes, Sieve of Eratosthenes is the best option (If you need most than 100 numbers this is the best implementation). This is my implementation:
#include <vector>
#include <iostream>
#include <cmath>
using namespace std;
vector<int> sieve(int n){
vector<bool> prime(n+1,true);
vector<int> res;
prime[0]=prime[1]=false;
int m = (int)sqrt(n);
for(int i=2; i<=m; i++){
if(prime[i])
for(int k=i*i; k<=n; k+=i)
prime[k]=false;
}
for(int i=0; i<n ;i++)
if(prime[i])
res.push_back(i);
return res;
}
int main(){
vector<int> primes = sieve(100);
for(int i=0; i<primes.size() ;i++){
if(i) cout<<", ";
if(primes[i]) cout<<i;
}
cout<<endl;
}
Related
I want to sort using the "Bubble Sort" algorithm of the 2d array. My array size will be about array[100000][100000]. my input number will be n=100,000.
For now we can use a small size of the array to fix the sorting issue.
I need to sort them in descending order for the first number(first number's line).
If the first number of 2 values are the same, then I have to sort them according to their second number.
Finally I have to output the result into a txt file
Let's' understand using an example. Here, my input looks like this
41 11
34 4
69 4
78 6
62 8
5 5
81 3
5 10
above our input example and we have a couple of inputs. Now I need to sort them descending orders for the first number. But if the first number of 2 values are the same, then sort them according to their second number.
Example output below,
81 3
78 6
69 4
62 8
41 4
34 4
5 10
5 5
If anyone can please help me.
I am a beginner so I am trying to input the file manually to solve this sorting problem. I can solve the sorting problem then I will try to input and out the text.
Something I have tried but not worked. I am still trying to solve it.
#include<bits/stdc++.h>
#include <algorithm>
using namespace std;
int main ()
{
int arr[100][100];
int n,j;
cin >>n;
cout << "Please enter a number: " << endl;
for(int i=0;i<n;i++)
{ for (int j=i; j<n; j++)
{
cin>>arr[i][j];
}
}
cout << "Unsorted array:" << endl;
for (int i=0; i<n; i++)
{
for (int j=i; j<n; j++)
{
cout<<arr[i][j]<<"\t";
}
}
for (int i=0; i<=n; i++)
{
for (int j=i+1; j<=n-1; j++)
{
int temp;
if(arr[i]>arr[j])
{
temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
}
return 0;
}
Use a std::vector<std::array<int,2>>for your base container. The dynamic growth capabilities of std::vector solves your stack space issue, and the std::array use gives you tied cell comparison. I.e. you can do this:
std::array<int, 2> ar1{1,2}, ar2{1,3};
if (ar1 < ar2) ...
and it will do the right thing. The result then boils down to effectively this:
#include <iostream>
#include <array>
#include <vector>
#include <utility>
int main()
{
std::vector< std::array<int,2> > v;
std::size_t n;
if (std::cin >> n && n > 0)
{
std::array<int,2> row;
while (n-- && std::cin >> row[0] && std::cin >> row[1])
v.emplace_back(row);
// bubblesort the content
std::size_t len = v.size();
while (len-- > 0)
{
bool swapped = false;
for (std::size_t i=0; i<len; ++i)
{
// std::array support multi-cell comparison.
if (v[i] < v[i+1])
{
// use library swap to swap entire row.
std::swap(v[i], v[i+1]);
swapped = true;
}
}
// early exit if no swaps happened on the last pass
if (!swapped)
break;
}
// report final output.
for (auto const& row : v)
std::cout << row[0] << ' ' << row[1] << '\n';
}
}
Input
8
41 11
34 4
69 4
78 6
62 8
5 5
81 3
5 10
Output
81 3
78 6
69 4
62 8
41 11
34 4
5 10
5 5
So when I run this code:
#include <iostream>
using namespace std;
#include <vector>
#include <string>
int main()
{
int current_number = 0;
vector<int>primes;
for(int i = 0; i < 100; i++)
{
current_number++;
for(int h= 0; h < primes.size(); h++)
{
if(current_number % primes[h] == 0)
{
continue;
}
else
{
primes.push_back(current_number);
}
}
}
for(int x =0; x < 100; x++)
{
cout << primes[x];
}
}
I get a segmentation fault. Im pretty sure it has something to do with vectorprimes. But, I'm not sure exactly what. The purpose of the code is to find every prime number between 1 and 100.
Among the problems in the posted code.
The inner loop body will never be entered because primes is initially empty the only code that changes it is in that loop.
Even after fixing the initial primes content with {2} and starting the counter loop with 3, the logic in the inner loop is still wrong. It appends on ever non-zero modulo. That shouldn't be done at all in the inner loop. Rather, the loop should break on any zero-modulo, and the outer loop then only appends to primes when it knows the inner loop didn't break early.
The final reporting loop assumes there are 100 primes in the first 100 numbers, which clearly isn't the case. Either it should be iterating based on container size, using iterators, or better still, just used ranged-for.
Minor: the current_number is pointless; just use i from the outer loop and start it at 3.
#include <iostream>
#include <vector>
int main()
{
std::vector<int> primes = {2};
for (int i = 3; i <= 100; i++)
{
bool isprime = true;
for (auto x : primes)
{
if (i % x == 0)
{
isprime = false;
break;
}
}
if (isprime)
primes.emplace_back(i);
}
for (auto x : primes)
std::cout << x << ' ';
std::cout << '\n';
}
Output
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
Note
There are better ways to do this. I suggest you investigate how to build a Sieve of Eratosthenes or similar sieve. In truth, the above code is already over halfway there. It wouldn't take much more to do it.
This question already has answers here:
Sorting std::strings with numbers in them?
(4 answers)
Closed 6 years ago.
I have problem solving this problem.
The task is simple at first line I enter how many examples I have.
On second line I need to enter how many numbers im going to read.
and then we enter all the numbers separate by space.
The task itselfs do , sorting the string array wtih numbers from smalles to the biggest one. After that if we have even numbers entered we print the middle number -1, if they are uneven we just print the middle number.
So far if I use the exact same code with long long it works perfectly , but it is limited only to 19 digit number and I want to expand the program so it can use bigger numbers.
Using that way the sort func , when I try to sort 16 elements from 160 to 10 , they all messed it start from 110 then in the midle is 160 and so one , which makes absolutly non sense, using 5 numbers or 8 works perfectly w/o any problem , using more numbers fails.
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int main() {
int examples;
cin >> examples;
for (size_t i = 0; i < examples; i++)
{
long long unsigned int n;
cin >> n;
string * numbers = new string[n];
for (size_t i = 0; i < n; i++)
{
cin >> numbers[i];
}
sort(numbers, numbers + n);
if (n % 2 == 0) {
cout << numbers[n / 2 - 1];
}
else
cout << numbers[n / 2];
}
system("pause");
return 0;
}
First, if you allocate memory with operator new, you must release it with operator delete[].
Second, when you sort strings instead of values, they are sorted just like strings would do, and here is where your problem lies. You see, 100 is alphabetically less than 2 or 20, that's why it would appear earlier.
Here's the output your program gives. Check this rule out, and you'll see that i'm right.
10 100 110 120 130 140 150 160 20 30 40 50 60 70 80 90
Third, using operator new is discouraged for pretty much anything. You have STL, and you seem to be using it extensively - why not vector?
Fourth, you don't check if anything we write into numbers[i] is actually a number. Think on that.
Fifth, for N being long enough(more than 2^sizeof(size_t)) your problem will NEVER stop due to integer overflow.
Sixth, you don't check for n == 0, and you will ultimately get memory access violation if you enter it.
A fast-right-off-the-bat fix for your problem:
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
using namespace std;
int main() {
int examples;
cin >> examples;
for (size_t i = 0; i < examples; i++)
{
size_t n;
cin >> n;
if (n <= 0)
break;
vector<string> numbers(n);
for (size_t i = 0; i < n; i++)
cin >> numbers[i];
//here we add a predicate for string checking,
//which evaluates the length of string
//before using the usual operator<.
sort(begin(numbers), end(numbers), [](const string& s1, const string& s2){
if (s1.length() < s2.length())
return true;
if (s2.length() < s1.length())
return false;
else
return (s1 < s2);
});
if (n % 2 == 0) {
cout << numbers[n / 2 - 1];
}
else
cout << numbers[n / 2];
}
system("pause");
return 0;
}
Still, it has a number of problems:
Checking if numbers[i] is actually a number
I'm not sure that
predicate I wrote doesn't have bugs - I'm just trying to give you
the idea of how it should work.
Here is my assignment:
A prime number is a number greater than 1 which is only evenly divisible by 1 and itself. For this assignment you will find which numbers from 2 to n (where n is a user-specified number) are prime.
Ask the user for a number, n, greater than 2. Keep asking for a number until a number greater than 2 is provided. Assume that the user will only enter numbers (that is, you do not need to check if a user enters text).
Use a loop to iterate on a variable, i, from 2 through n. For each iteration, check all numbers from 2 through i to determine whether the number is prime. If it is prime, print out i and the word "Prime".
Use the modulus operator, %, to determine if a number is prime
Here is what I have so far. It doesnt work. And I dont know why. please help, im a business student taking basic programming as an elective.
#include <iostream>
using namespace std;
int main()
{
int n;
int i;
int x;
while (n<=2)
{
cout << "Enter a number greater then 2: \n";
cin >> n;
for (x=n; x>=2; x--)
{
bool prime = false;
for (i=2; i<x; i++)
{
if (x%i==0)
{
prime = true;
}
}
if (prime==false)
{
cout << x << " Prime.\n";
}
}
}
return 0;
}
I didn't actually used your code because of indentication it was little bit of hard to read. But I wrote a new method for you. I suggest always divide your code into methods to make it more managable. You can call this in your main method
bool checkPrime(int number)
{ // input: num an integer > 1
// Returns: true if num is prime
// false otherwise.
int i;
for (i=2; i<number; i++)
{
if (number % i == 0)
{
return false;
}
}
return true;
}
And here is how can you call this method in the main:
int main()
{
int number;
cout << "Enter an integer (>1): ";
cin >> number;
if (checkPrime(number))
{
cout << number << " is prime." << endl;
}
else
{
cout << number << " is not prime." << endl;
}
// I think this is more convention than anything.
return 0;
}
It may not be the optimal program out there, but this should work:
#include <iostream>
using namespace std;
int main()
{
int n;
int i;
int x;
cout << "Enter a number greater then 2: \n";
cin >> n;
while (n<=2)
{
cout << "Enter a number greater then 2: \n";
cin >> n;
}
for (x=n; x>=2; --x)
{
for (i=2; i<x; ++i)
{
bool prime = true;
for (j=2; j<i/2; ++j)
{
if (i%j==0)
{
prime = false;
break;
}
}
if (prime)
{
cout << j << " Prime.\n";
}
}
}
return 0;
}
There are two easy means to go faster: first there is no need to test potential divisors that are too big (as pointed out by arne), and second, there is no need to test even numbers except 2.
Something like this:
#include <cassert>
bool is_prime(unsigned n)
{
if (n == 2)
return true;
if (n <= 1
|| n % 2 == 0)
return false;
for (int d = 3; d * d < n; ++d)
if (n % d == 0)
return false;
return true;
}
int main()
{
assert(!is_prime(0));
assert(!is_prime(1));
assert(is_prime(2));
assert(is_prime(3));
assert(!is_prime(4));
assert(is_prime(5));
assert(!is_prime(6));
assert(!is_prime(256));
assert(is_prime(257));
}
Of course, even faster is building a table of primes, and using this table as potential divisors, instead of every odd number. Makes sense if you have several numbers to check.
Please, say, why it let say you it does not work? Among others I get this output.
Enter a number greater then 2:
100
97 Prime.
89 Prime.
83 Prime.
79 Prime.
73 Prime.
71 Prime.
67 Prime.
61 Prime.
59 Prime.
53 Prime.
47 Prime.
43 Prime.
41 Prime.
37 Prime.
31 Prime.
29 Prime.
23 Prime.
19 Prime.
17 Prime.
13 Prime.
11 Prime.
7 Prime.
5 Prime.
3 Prime.
2 Prime.
But as int n; leaves n uninitialized, the while loop might not be entered.
I think the Answer 1 function checkprime(int number) can improved but purely on preformance basis, consider the fact that prime numbers cannot be even.So if add an extra check to see if (number % 2 == 0) will reduce a lot of iteration of the for loop, and for the remaining i think iterating the loop from 2 to 9 is enough rather than 2 to n. Too many iterations will slow you down on larger numbers.
I have to code a program that counts how many prime numbers are between 2 and "n".
The first input have to be the total number of tests and other ones have to be the "n" (number limit of the range of numbers to check).
The problem:
My inputs: 7 10 15 50 100 1000 10000 7
The right outputs for the inputs above: 4 6 15 25 168 1229 4
What my code outputs: 4 6 15 25 800 9800 4
My code:
#include <iostream>
using namespace std;
int f(int number){
int m=0,k=1;
for(k; k<=number; k++)
if(number%k==0)
m++;
if(m==2)
return true;
}
int main (){
int limit=0, counter=0, test=0;
bool n;
cin>>test;
for(int v=0; v<test; v++){
cin>>limit;
for(int i=2; i<=limit; i++){
n=f(i);
if (n==true)
counter++;
}
cout<<counter<<endl;
counter=0;
}
return 0;
}
You probably need to turn on warnings in your compiler. The function f returns a bool (not an int as declared) and does not do so unless the number of divisors of x is equal to two. This are fairly trivial mistakes that any decent C++ compiler should warn you about. Do not ignore warnings.