I understand I can just use for-loop to define prime number, but before I implement for loop into that topic, I had a thought that I maybe could make one with while loop or do-while.
Somehow, my do-while loop seems not to be working correctly.
My theory was that I could find prime number for checking the remainder of divisor where divisor keeps decreasing by 1 until divisor reaches 1. (Although 'until divisor reaches 1.' part is not in the code, I would assumed remainder of 0 would appear anyway before divisor goes below 0.)
However, it keeps halting before remainder reaches 0.
What did I do wrong?
I've even tried both instead of (remainder<1 && remainder!=1)below but still no luck.
while (remainder<1)
while (remainder==1)
#include <iostream>
using namespace std;
int main()
{
int number, divisor, remainder;
cin >> number;
divisor=number-1;
cout << "You've put " << number << ".\n";
do {
divisor = divisor - 1;
remainder=number%divisor;
}
while (remainder<1 && remainder!=1);
cout << divisor << " " << remainder << " " << number << " " << "Divisor, remainder, number\n";
return 0;
}
First, you have a typo in your variable assignment. This line:
number = divisor - 1;
should be:
divisor = number - 1;
The while() condition should be while (remainder != 0), so that the loop keeps repeating as long as you haven't found a divisor. If you want to be more explicit, you could use while (divisor > 1 && remainder != 0). There's no need to repeat when divisor == 1 because that's a divisor of all integers.
Related
I've been playing with finding divisors of numbers recently and decided to try and make a program, which prints all ways to express a number N as a product of two integers. I wrote one which works on positive numbers and only considers positive numbers to make up the product.
#include <iostream>
#include <cmath>
int main()
{
int n;
std::cin >> n;
int root = std::sqrt(n);
for(int i = 1; i <= root; i++)
{
if(n % i != 0)
continue;
int j = n / i;
std::cout << i << ", " << j << std::endl;
}
return 0;
}
The code above just finds all divisors of N and prints them as pairs. It works fine, but I wanted to try and make it find all possible ways to get to N, not only with positive numbers.
For example, if I input 10 in the program above, the results will be (1, 10), (2, 5); These are correct, but there are other ways to multiply two numbers and get to 10. It involves negative numbers: (-1, -10), (-2, -5) are also solutions, since when you multiply two negative numbers, you end up with a positive one.
If I wanted the program to only work on positive N values but also find negative multiples, I could just print the negative versions of i and j, since you can only get to a positive number by either multiplying two positive or two negative together.
That works, but now I want to get this code to work on negative N values. For example, an expected output for N = -10 would be: (-1, 10), (1, -10), (2, -5), (-2, 5);
The problem is, the algorithm above can only find positive divisors for positive numbers, since it involves square root, which is only defined for positive numbers, and the loop starts at a positive and ends at a positive.
I noticed that I can just calculate the square root of the absolute value of N, then make the loop start at -root and end at root to go over the negative divisors of N as well. I had to make sure to skip 0, though, because division with 0 isn't defined and that made it crash. The code I ended up with looks like this:
#include <iostream>
#include <cmath>
int main()
{
int n;
std::cin >> n;
int root_n = std::sqrt(std::abs(n));
for(int i = -root_n; i <= root_n; i++)
{
if(i == 0 || n % i != 0)
continue;
int j = n / i;
std::cout << i << ", " << j << std::endl;
}
return 0;
}
It worked properly for all the tests I came up with, but I am not sure if it's the best way to write it. Is there anything that I can improve?
Thanks in advance!
EDIT: Tried using std::div as suggested by Caleth (also used ReSharper addon in VS to give me refactoring suggestions):
#include <iostream>
#include <cstdlib>
int main()
{
int n;
std::cin >> n;
const int sqrt_n = std::sqrt(std::abs(n));
for(auto i = -sqrt_n; i <= sqrt_n; i++)
{
if (i == 0)
continue;
const auto div_res = std::div(n, i);
if (div_res.rem)
continue;
std::cout << i << ", " << div_res.quot << std::endl;
}
return 0;
}
Instead of calculating the remainder, then calculating the quotient, I can just do a single call to std::div, which returns a struct, containing both values.
A major observation is that the negative divisors and the positive divisors of a number are the same, except for sign. You could save half of the time if you looked only at positive numbers and handled signs on your own. For example,
int main()
{
int n;
std::cin >> n;
int root_n = std::sqrt(std::abs(n));
for(int i = 1; i <= root_n; i++) \\ don't loop over negative numbers now
{
if(n % i != 0) \\ not necessary to check for 0 anymore
continue;
int j = n / i;
std::cout << i << ", " << j << "\n";
std::cout << -i << ", " << -j << "\n"; \\ corresponding negative
}
return 0;
}
You might notice that I removed std::endl --- you don't really need to flush the stream that often. It's faster to let output buffer as it wants.
If you are looking for other ways to modify your program, you might try finding the prime factorization and then computing lists of divisors from it. For large, highly composite inputs, this will be faster. But it's also quite different.
I'm very very new to C++. Here I'm trying to write a program without any extra library. Using loops to find both the smallest value and the second smallest value from the user's inputs ( 0 is excluded and exits the program ).
Here is what I tried to do.
#include <iostream>
using namespace std;
int main()
{
int value=0;
int SmallestNumber=0;
int SmallestNumber2=0;
cout << "Enter number to find the smallest and second smallest(or 0 to exit): ";
cin >> value;
while (value != 0) {
if (value< SmallestNumber && value != 0 )
{
SmallestNumber = value;
}
else if (value<SmallestNumber && SmallestNumber2 >SmallestNumber && value != 0)
{
SmallestNumber2 = value;
}
cout << "Enter number to find the smallest and second smallest(or 0 to quit): ";
cin >> value;
}
cout << "Smallest number is: " << SmallestNumber << '\n' << endl;
cout << "Second Smallest number is: " << SmallestNumber2 << '\n' << endl;
return 0;
}
However, this program is not functioning properly. The smallest number finder works only if I input a negative value **, and the second smallest number value always outputs **0.
Since I'm very new to C++, I tried many other solutions, but this is what I can really think of.
Can somebody please tell me what is wrong with the program, and how I can correct it?
A million thanks! Please help me :'(
Thanks for answering my question!
I changed the initialization into this.
int value;
int SmallestNumber=0;
int SmallestNumber2=0;
but how do I initialize the smallest and the second smallest values..?
This is what I wanted my program to do
displaying the smallest and second smallest
50
1
61
93
-35
38
0
-35 smallest
1 second smallest
You start with a smallest value set to 0, so you will always get values only smaller than 0, that's why you have std::numeric_limits<int>::max().
Then for your second smallest, you are never checking against the current second smallest value, you are just checking against the biggest, which you now is going to work. So change this:
if (value>SmallestNumber2 && value != 0)
You should probably check value != 0 outside the main if statements as well. And as #Caleb reminded me, what happens to the previous largest value if it gets replaced?
Also, if you want to keep the same concept and do the algorithm "yourself" there is few things to change.
First the initial value of SmallestNumber and SmallestNumber2 need to be as high as possible otherwise the numbers saved can only be the one lower than your initial value. Therefore you can use INT_MAX.
Second, the second smallest number, need to be set in 2 cases :
when a new value is entered that is the second smallest
when a new smallest value is set, the old smallest value become the new second smallest.
Third there are a lot of unnecessary code here. You check too many time if value is not null which you know from the while condition. And you have code duplication with the cout/cin statement. Which is prone to mistakes.
Here is a version of what it could look like :
int value= INT_MAX;
int SmallestNumber=INT_MAX;
int SmallestNumber2=INT_MAX;
while (value != 0) {
if(value > SmallestNumber && value < SmallestNumber2)
{
SmallestNumber2 = value;
}
else if (value< SmallestNumber)
{
SmallestNumber2 = SmallestNumber;
SmallestNumber = value;
}
cout << "Enter number to find the smallest and second smallest(or 0 to quit): ";
cin >> value;
}
cout << "Smallest number is: " << SmallestNumber << '\n' << endl;
cout << "Second Smallest number is: " << SmallestNumber2 << '\n' << endl;
return 0;
ps : the version of #darune is a nicer solution.
You have no position at which the former smallest value becomes the second smallest value, which can't work.
Consider this code:
int value;
int smallest = std::numeric_limits<int>::max()-1;
int second_smallest = std::numeric_limits<int>::max();
while(true)
{
cin >> value;
if(value == 0) break;
if(value >= second_smallest) continue;
if(value == smallest) continue; // assuming that a double value does not change anything
if(value > smallest) // is between them
{
second_smallest = value;
continue;
}
//now the case left is that the new value is the smallest
second_smallest = smallest;
smallest = value;
}
Basic idea: first of all, rule out things and from then on, assume that they do not hold. We begin with the break case (I prefer a while(true) in such cases to have manual control over breaking it inside). Then we rule out the case in which nothing happens. The two cases left are that we are between the old values and that we are below both, and we handle them accordingly.
In your code, your ifs get to bloated. Makes it hard to keep track of what is done and what is to be done.
One example of this is that you have several times && value != 0 in your code despite this always being true due to the condition of your while.
In general, you should really learn how to use a debugger, or at least how to use helpful messages for debugging. Your mistake of setting your variables to zero at the start would have been easy to detect.
Other minor things: You should decide for a style and stick to it. It is quite unusual to name variables with a major first letter. Camel case is fine though, smallestNumber would have been fine. Second, try to avoid using namespace std;. This can lead to collissions. Rather use single members of std, like using std::cout;. It is not that problematic in a source file (very problematic in a header) but I recommend to do it consistently to keep a good routine.
A thing left to do in the code would be to later catch if the variables are still at std::numeric_limits<int>::max() and that minus one, signalling that there was no user input, and printing a fitting message instead of those values.
Note that as you read in an integer, negative values are legal, which might not be what you want, given that you use zero to break. You might want to add a case
if(value < 0)
{
cout << "Value was ignored due to being negative" << endl;
}
This is relatively simpel by using a a few different concepts, namely stdvector, stdstream and last stdsort
First off, the input part can be simplified to:
std::vector<int> numbers;
std::cout << "Enter multiple numbers, separated by spaces: ";
std::getline(std::cin, line);
std::istringstream stream(line);
while (stream >> number) {
numbers.push_back(number);
}
Now, since you would like the 2 smallest numbers, my suggested method would be to simply sort the vector at this point:
std::sort(numbers.begin(), numbers.end());
Now the list of numbers are sorted in ascending order and it is matter of printing the 2 first values. I leave that as an exercise to you.
I am new to coding and my task is to make the variable 'sum' greater than (not equal to) m by summing up 1/n for an increasing 'n'.
I need to solve the same problem twice (one using a for-loop and once using a while-loop). But both ways end in an infinte loop.
My code is working fine when I replace the "<=" with "<". But that
Can someone help me?
#include <iostream>
using namespace std;
int main () {
unsigned int m = 1;
double sum = 0;
long n;
n = 1;
while (sum <= m) //THIS LINE
{
double sumsum = 1/n;
sum += sumsum;
n++;
}
cout << "n = " << n << endl ;
cout << "sum = " << sum << endl ;
return 0;
}
Epression 1/n with n being of type long and having a value > 1 will always yield 0, since you operate with integral types. Hence, sum will be assigned 1 in the first run, but will never come to a value > 1, as forth on always 0 is added.
Change your code to
double sumsum = 1.0/n;
and it should work. Note that 1.0 enforces to operate with floating points.
This is my code for finding the sum of a harmonic series of 1/n. I want it to stop when the sum is greater than or equal to 15, but the code cannot run. Can anyone let me know what I'm doing wrong? It seems to follow the correct while loop structure. Thanks!
#include <iostream>
using namespace std;
int main ()
{
int divisor = 1;
int sum = 1;
while ((sum <= 15) && (divisor >=1))
{
sum = sum + (1/divisor);
divisor++;
}
cout << "You need " << divisor << " terms to get a sum <= 15" << endl;
return 0;
}
Your loop is actually running. However, your sum variable is of type int, and so is divisor.
1 (an int) / divisor (also an int) will return 1 or 0. This is because you are doing integer division. 1/1 == 1. However, 1/2 == 0, 1/3 == 0, etc... To solve this, cast divisor to double:
(1 / (double)divisor)
So that solves the issue of that segment returning only 1 or 0. However, you will still gain a sum of 1 as sum is of type int. Attempting to assign a double to an int variable will result in a truncation, or floor rounding. Sum will add the first 1, but it will remain 1 indefinitely after that. In order to solve this, change the type of sum to double.
Your assignment of sum = 1; is a logical error. Your result will be 1 higher than it should be. Your output statement is also mistaken... It should be...
cout << "You need " << divisor << " terms to get a sum > 15" << endl;
In addition, the condition of divisor >= 1 is needless... It is always greater than or equal to one because you assign it as 1 and are incrementing... If you do want a sum that is >= 15, change the while condition to...
while (sum < 15)
Your code should look like this...
#include <iostream>
using namespace std;
int main()
{
int divisor = 1;
double sum = 0; //Changed the type to double and assigned 0 rather than 1
while (sum <= 15) //While condition shortened...
{
sum = sum + (1 / (double)divisor); //Added type cast to divisor
divisor++;
}
//cout statement adjusted...
cout << "You need " << divisor << " terms to get a sum > 15" << endl;
return 0;
}
I have finished my program, and it runs perfectly fine, but i have one last question to ask.
I need to count how many times the number 5 appears in my vector - disqualify.
My code is below, and any help on how to determine how many times 5 appears as a disqualifying prime is greatly appreciated.
I can only get the contents of the entire vector to appear so im at a loss.
Thank you!
#include <iostream>
#include <iomanip>
#include <vector>
#include <iterator>
using namespace std;
int main()
{
const int MAX(100); // Number of primes to be identified
long primes[MAX] = { 2, 3, 5 }; // Initialize with first three primes
long trial(5); // Hold a candidate prime
int count(3); // Count primes found - reflects initial values
bool found(false); // Indicates when a prime is found
vector <long> nonPrimes; //Vector to hold non prime numbers
vector <long> disqualify; //Vector to hold prime numbers that disqualify the non prime numbers as prime numbers.
vector<long>::iterator fives;//Vector iterator which will be used to find how many times the number 5 disqualifies a nonPrime number.
do
{
trial += 2; // Produce next candidate value
found = false; // Reset indicator - assume it is not prime
for (int i = 0; i < count; i++) // Try division by existing primes
{
found = (trial % primes[i]) == 0; // True if no remainder
if (found) // No remainder means number is not a prime
{
nonPrimes.push_back(trial); // push_back trial values to vector nonPrimes
disqualify.push_back(primes[i]); //push back disqualifying prime numbers to disqualify vector
break; // Terminate the division loop
}
}
// The above loop will exit either due to a break or after trying all
// existing primes as a divisor. found was initialized to false. If
// found is false after exiting the loop, a divisor was not found.
if (!found) // We have a new prime: found = true! -- add numbers to vectors
primes[count++] = trial; // Save candidate in next array position
} while (count < MAX);
// Main loop has completed - we have found MAX prime numbers.
// Display the prime numbers, presenting five numbers on one line.
cout << "Prime numbers found during the program execution:" << endl;
for (int i = 0; i < MAX; i++)
{
if (i % 5 == 0) // For a new line on first line of output
cout << endl; // and on every fifth line that follows
cout << setw(10) << primes[i]; // Provide space between numbers
}
cout << endl; // All primes displayed - for a new line
/*
Display Non-primes and their disqualifiers
*/
cout << "Non-Primes identified: " << count << endl; // Identify how many nonprimes appear and display the value.
for (int i = 0; i < MAX; i++) //For loop to clarify position of output
{
if (i % 5 == 0) // For a new line on first line of output
cout << endl; // and on every fifth line that follows
cout << setw(10) << nonPrimes[i] << ":" << disqualify[i] << setw(10); // outputs nonPrime numbers and their disqualifying primes
}
cout << endl;
//Use iterator (fives) to produce how many times the digit 5 appears as a disqualifying prime number
for (fives = disqualify.begin(); fives < disqualify.end(); fives++) // bounds checking for how many times 5 appears.
{
cout << "Numer of times 5 was a disqualifier: " << *fives << endl; // output number of times 5 appears as a disqualifying prime
}
system("Pause");
return 0;
}
If I understand the question correctly, the last few lines are almost right.
//Use iterator (fives) to produce how many times the digit 5 appears as a disqualifying prime number
for (fives = disqualify.begin(); fives < disqualify.end(); fives++) // bounds checking for how many times 5 appears.
{
cout << "Numer of times 5 was a disqualifier: " << *fives << endl; // output number of times 5 appears as a disqualifying prime
}
This loop says to run one-by-one through the elements of disqualify and print "Number of times 5 was a disqualifier: " followed by the element at that point in disqualify.
You can simply change that loop to count the fives by incrementing a counter every time it hits a 5, then put the print afterward like so (I changed the name of fives to ittr, a generic iterator name, to clear up confusion):
int five_count = 0;
vector<long>::iterator ittr;
for (ittr = disqualify.begin(); ittr < disqualify.end(); ittr++)
{
if (*ittr == 5)
++five_count;
}
cout << "Number of times 5 was a disqualifier: " << five_count << endl;