I have been doing problems for while loop in c++ and i got stuck on this problem. Googled the answer to see what i had to do but now i dont understand the logic behind it and why it works.
Here is the problem:
A sequence consists of natural numbers and ends with 0. Determine the value of the second largest element in the sequence, that is, the element that will be the largest if you remove the largest element from the sequence.
Examples-> Input 1: 4, 4, 2, 3, 0 Output 1: 4 ; Input 2: 2 1 0 Output 2: 1
This is the code:
#include <iostream>
using namespace std;
int main() {
int n, max, smax = 0;
cin >> n;
max = n;
while (n != 0) {
cin >> n;
if (n > max) {
smax = max;
max = n;
}
else if (n > smax) {
smax = n;
}
}
cout << smax;
return 0;
}
So, from my understanding max is n so the statement if n > max will never be True. Unless value for max resets with each loop and is 0, but then its always going to be true so there is no point for the second if statement.
Im sure i dont understand how the while loop works and i would like for someone to clear it up for me. Thanks in advance.
While loop repeats its body until the given condition become false. It's relatively easy to make an infinite while loop error in code, e.g.:
int i = 0;
while (i<10){
cout<<"something\n";
}
Please remember to put some operation that will break the loop in the body. This would work:
int i = 0;
while (i<10){
cout<<"something\n";
i++; //equivalent of i=i+1;
}
Try it yourself: https://www.onlinegdb.com/online_c++_compiler
This should help to understand the concept.
Your code actually makes no sense to me. You type some numbers and it changes them until you type 0, when it stops. It doesn't even show you the maximum value you typed. I highly recommend to learn something more clear and useful in C++.
I am working on producing C++ code to list all primes between 1 and 100 say. In order to present my question I need to provide some background.
The basic idea of what I want to do is the following:
Introduce a vector to hold all the primes in ascending order. If the first j elements of this vector are given, the j+1 element is then given as the smallest integer larger than the j'th element which is not divisible by any of the first j elements. The first element is moreover given to be 2.
Thus if v denotes the vector of primes, I want to produce code which implements the following math-type argument;
v[1]=2;
for(2<i<=100)
if i % v[j] !=0 FOR ALL 0<j< v.size()
v.push_back(i)
else
do nothing
The problem I am facing however is that C++ doesn't seem to have a for all type language construct. In order to get around this I introduced a counter variable. More precisely:
int main() {
const int max=100;
vector<int>primes; // vector holding list of primes up to some number.
for(int i=2; i<=max;++i){
if(i==2)
primes.push_back(i); // inserts 2 as first prime
else{
double counter=primes.size(); // counter to be used in following loop.
for(int j=0;j<primes.size();++j){
if(i% primes[j]==0){
break; // breaks loop if prime divisor found!
}
else{
counter-=1; //counter starts at the current size of the primes vector, and 1 is deducted each time an entry is not a prime divisor.
}
}
if (counter==0) // if the counter reaches 0 then i has no prime divisors so must be prime.
primes.push_back(i);
}
}
for(int i=0; i<primes.size(); ++i){
cout << primes[i] << '\t';
}
return 0;
}
The questions I would like to ask are then as follows:
Is there a for-all type language construct in C++?
If not, is there a more appropriate way to implement the above idea? In particular is my use of the counter variable frowned upon?
(Bonus) Is anyone aware of a more efficient way to find all the primes? The above works relatively well up to 1,,000,000 but poorly up to 1 billion.
Note I am beginner to C++ and coding in general (currently working through the book of Stroustrup) so answers provided with that in mind would be appreciated.
Thanks in advance!
EDIT:
Hello all,
Thank you for your comments. From them I learned that both use of a counter and a for all type statement are unnecessary. Instead one can assign a true or false value to each integer indicating whether a number is prime with only integers having a true value added to the vector. Setting things up in this way also allows the process of checking whether a number is prime given the currently known'' primes to be independent of the process of updating the currently known'' primes. This consequently addresses another criticism of my code which was that it was trying to do too many things at once.
Finally it was pointed out to me that there are some basic ways of improving the efficiency of the prime divisor algorithm for finding primes by, for instance, discounting all even numbers greater than 2 in the search (implemented by starting the appropriate loop at 3 and then increasing by 2 at each stage). More generally it was noted that algorithms such as the sieve of Erastothenes are much faster for finding primes, as these are based on multiplication not division. Here is the final code:
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
vector<int> primes; // vector holding list of primes up to some number.
bool is_prime(int n) {// Given integer n and a vector of primes this boolean valued function returns false if any of the primes is a prime divisor of n, and true otherwise. In the context of the main function, the list of primes will be all those that precede n, hence a return of a true value means that n is itself prime. Hence the function name.
for (int p = 0; p < primes.size(); ++p)
if (n % primes[p] == 0) {
return false;
break; // Breaks loop as soon as the first prime divisor is found.
}
return true;
}
int main() {
const int max=100;
primes.push_back(2);
for (int i = 3; i <= max; i+=2)
if (is_prime(i) == true) primes.push_back(i);
for(int i=0; i<primes.size(); ++i)
cout << primes[i] << '\t';
return 0;
}
I just have one additional question: I checked how long the algorithm takes up to 1,000,000 and the presence of the break in the is_prime function (which stops the search for a prime divisor as soon as one is found) doesn't seem to have an effect on the time. Why is this so?
thanks for all the help!
The basic idea I want to find inside a given problem is this. I have an integer variable called N where the user can input a value to.
int main()
{
int n;
std::cin >> n;
Then from this point onward, I created a for loop that replicates how you would normally find out if the integer created is indeed prime or not. However, what I'm trying to find isn't whether the number is prime but to find all the composites from a range of 2, to the number that was inputted. So if the input is 10. I should be getting composites 4 6 8 9 10 from that given range.
I do know that the first thing to do is to create a for loop like this
for (int i = 2; i <= 10; i++)
Then nest another for loop with a conditional to test if each number inside the given range is a prime or composite.
for (int i = 2; i <= n; i++)
{
for (int j = 2; j <= i; j++)
{
if (i % j == 0)
{
std::cout << i << " ";
}
}
}
However, this approach isn't really cutting it. What's really going on inside this nested for loop approach is an out put beginning with 2 3 2 4 5 2 and a bunch of numbers that aren't making much sense. What is it about this approach that's causing this wacky sequence of numbers outputted and what can I do to fix this?
After you've printed a composite number, you want the inner "for j" loop to terminate and the outer "for i" loop to advance, so after std::cout add break;. Additionally, you know if you let j == i you'll deem any number a composite, so change the "for j" loop termination condition from j <= i to j < i. link to working code....
I was stuck in my programming assignment
This assignment is using a bool array to find prime number between 2 to N
The method of it is all prime number "index" will be set on true and other will be set on false,so finally it just print out the true index
Here is my code
#include <iostream>
#include <ctime>
using namespace std;
int main(){
int n,i;
int count = 0;
cout << "Enter the value of n: ";
cin >> n;
bool* prime = new bool[n];
for (i=0;i<=n;i++)
prime[i] = true;
for (i=2;i<=n;i++)
if (prime[i])
for (int j=n;j=i;j--)
if (j%i == 0)
prime[j] = false;
cout << "Prime numbers: ";
for (i=2;i<=n;i++)
if(prime[i])
{cout << i <<", ";
count++;}
cout << count <<" primes found.";
//hold the windows
system("pause");
return 0;
}
The problem of it is after I input the value of N, the program is no response and didn't show any thing out.
Just skimming over your code, I can see that you have used the wrong operator on this line:
for (int j=n;j=i;j--)
Where j=i should be j==i. j=i uses the assignment operator (=) rather than the comparison operator (==), and will always evaluate to true if i is non-zero, thus creating an infinite loop - meaning no output, etc
Side note
You may want to look into bounds-checking for n. What if the user enters a negative number? bool* prime = new bool[n]; would try to produce a negative-sized array, which is not possible (unless the number is converted into an unsigned value, in which case you'd have a huge array of booleans)
I see a bug when looking at the initialization of the array:
bool* prime = new bool[n];
The elements in prime will be from 0 to n-1.
Then, there`s a loop setting the values to true. At some point, i == n:
for (i=0;i<=n;i++)
prime[i] = true;
When i == n, you have written too far in the array. This might overwrite the return address.
Programmers often try to create arrays that are the exact size they need. Unless there`s a lot of storage being needed, I like to create arrays a little bit too big. This reduces the chances of an buffer overflow bug causing an exploit in my code.
bool* prime = new bool[n + 20];
You`d be surprised how many times that practice will save you time.
I have a range of random numbers. The range is actually determined by the user but it will be up to 1000 integers. They are placed in this:
vector<int> n
and the values are inserted like this:
srand(1);
for (i = 0; i < n; i++)
v[i] = rand() % n;
I'm creating a separate function to find all the non-prime values. Here is what I have now, but I know it's completely wrong as I get both prime and composite in the series.
void sieve(vector<int> v, int n)
{
int i,j;
for(i = 2; i <= n; i++)
{
cout << i << " % ";
for(j = 0; j <= n; j++)
{
if(i % v[j] == 0)
cout << v[j] << endl;
}
}
}
This method typically worked when I just had a series of numbers from 0-1000, but it doesn't seem to be working now when I have numbers out of order and duplicates. Is there a better method to find non-prime numbers in a vector? I'm tempted to just create another vector, fill it with n numbers and just find the non-primes that way, but would that be inefficient?
Okay, since the range is from 0-1000 I am wondering if it's easier to just create vector with 0-n sorted, and then using a sieve to find the primes, is this getting any closer?
void sieve(vector<int> v, BST<int> t, int n)
{
vector<int> v_nonPrime(n);
int i,j;
for(i = 2; i < n; i++)
v_nonPrime[i] = i;
for(i = 2; i < n; i++)
{
for(j = i + 1; j < n; j++)
{
if(v_nonPrime[i] % j == 0)
cout << v_nonPrime[i] << endl;
}
}
}
In this code:
if(i % v[j] == 0)
cout << v[j] << endl;
You are testing your index to see if it is divisible by v[j]. I think you meant to do it the other way around, i.e.:
if(v[j] % i == 0)
Right now, you are printing random divisors of i. You are not printing out random numbers which are known not to be prime. Also, you will have duplicates in your output, perhaps that is ok.
First off, I think Knuth said it first: premature optimization is the cause of many bugs. Make the slow version first, and then figure out how to make it faster.
Second, for your outer loop, you really only need to go to sqrt(n) rather than n.
Basically, you have a lot of unrelated numbers, so for each one you will have to check if it's prime.
If you know the range of the numbers in advance, you can generate all prime numbers that can occur in that range (or the sqrt thereof), and test every number in your container for divisibility by any one of the generated primes.
Generating the primes is best done by the Erathostenes Sieve - many examples to be found of that algorithm.
You should try using a prime sieve. You need to know the maximal number for creating the sieve (O(n)) and then you can build a set of primes in that range (O(max_element) or as the problem states O(1000) == O(1))) and check whether each number is in the set of primes.
Your code is just plain wrong. First, you're testing i % v[j] == 0, which is backwards and also explains why you get all numbers. Second, your output will contain duplicates as you're testing and outputting each input number every time it fails the (broken) divisibility test.
Other suggestions:
Using n as the maximum value in the vector and the number of elements in the vector is confusing and pointless. You don't need to pass in the number of elements in the vector - you just query the vector's size. And you can figure out the max fairly quickly (but if you know it ahead of time you may as well pass it in).
As mentioned above, you only need to test to sqrt(n) [where n is the max value in the vecotr]
You could use a sieve to generate all primes up to n and then just remove those values from the input vector, as also suggested above. This may be quicker and easier to understand, especially if you store the primes somewhere.
If you're going to test each number individually (using, I guess, and inverse sieve) then I suggest testing each number individually, in order. IMHO it'll be easier to understand than the way you've written it - testing each number for divisibility by k < n for ever increasing k.
The idea of the sieve that you try to implement depends on the fact that you start at a prime (2) and cross out multitudes of that number - so all numbers that depend on the prime "2" are ruled out beforehand.
That's because all non-primes can be factorized down to primes. Whereas primes are not divisible with modulo 0 unless you divide them by 1 or by themselves.
So, if you want to rely on this algorithm, you will need some mean to actually restore this property of the algorithm.
Your code seems to have many problems:
If you want to test if your number is prime or non-prime, you would need to check for v[j] % i == 0, not the other way round
You did not check if your number is dividing by itself
You keep on checking your numbers again and again. That's very inefficient.
As other guys suggested, you need to do something like the Sieve of Eratosthenes.
So a pseudo C code for your problem would be (I haven't run this through compilers yet, so please ignore syntax errors. This code is to illustrate the algorithm only)
vector<int> inputNumbers;
// First, find all the prime numbers from 1 to n
bool isPrime[n+1] = {true};
isPrime[0]= false;
isPrime[1]= false;
for (int i = 2; i <= sqrt(n); i++)
{
if (!isPrime[i])
continue;
for (int j = 2; j <= n/i; j++)
isPrime[i*j] = false;
}
// Check the input array for non-prime numbers
for (int i = 0; i < inputNumbers.size(); i++)
{
int thisNumber = inputNumbers[i];
// Vet the input to make sure we won't blow our isPrime array
if ((0<= thisNumber) && (thisNumber <=n))
{
// Prints out non-prime numbers
if (!isPrime[thisNumber])
cout<< thisNumber;
}
}
sorting the number first might be a good start - you can do that in nLogN time. That is a small addition (I think) to your other problem - that of finding if a number is prime.
(actually, with a small set of numbers like that you can do a sort much faster with a copy of the size of the vector/set and do a hash/bucket sort/whatever)
I'd then find the highest number in the set (I assume the numbers can be unbounded - no know upper limit until your sort - or do a single pass to find the max)
then go with a sieve - as others have said
Jeremy is right, the basic problem is your i % v[j] instead of v[j] % i.
Try this:
void sieve(vector<int> v, int n) {
int i,j;
for(j = 0; j <= n; j++) {
cout << v[j] << ": ";
for(i = 2; i < v[j]; i++) {
if(v[j] % i == 0) {
cout << "is divisible by " << i << endl;
break;
}
}
if (i == v[j]) {
cout << "is prime." << endl;
}
}
}
It's not optimal, because it's attempting to divide by all numbers less than v[j] instead of just up to the square root of v[j]. And it is attempting dividion by all numbers instead of only primes.
But it will work.