I want to write a simple progam using WHILE loop, with which you could get all divisors of the number which you put in.
For example you want all divisors of number 30, which are: 1, 2, 3, 5, 6, 10, 15, 30.
Now you want program to display only numbers on interval (for example) from 5 - 10, which are 5, 6 and 10.
What i tried so far is getting all those divisors using FOR sentence, but without intervals, so I am stucked and don't know how could make it also in WHILE loop.
#include <iostream>
using namespace std;
int main() {
int input_number;
cin >> input_number;
cout << "All numbers are " << input_number << endl;
for (int i = 1; i <= input_number; i++) {
if (input_number % i == 0) {
cout << i << " ";
}
}
return 0;
}
Thanks for your help in addition.
Solving this problem in a while loop is probably not as simple (or brute-force) as solving it in a for loop.
Consider this rendition of the loop using while:
int input_number;
std::cin >> input_number;
int i = 1; //Start trying to divide the input number by 1
int limit = input_number; //Termination condition for the loop
while(i < limit) {
if(input_number % i == 0) { //If divisible by i, both i and input_number/i are factors
std::cout << i << " " << input_number / i << " ";
}
++i; //Try dividing by the next integer
/*Set the limit to our latest input_number/i so we don't get duplicate
results (e.g. (5, 6) and (6, 5) for input_number = 30)*/
limit = input_number / i;
}
For input_number = 30, this loop only runs for 5 iterations, while the for loop version runs for 30 iterations.
Bottom Line
for loops and while loops are interchangeable, but approaching a problem using a for loop might bring you to a different solution faster than approaching the problem with a while loop and vice versa as they help you think about the problem from different perspectives.
Extra Information
The for loop version allows for certain optimization techniques such as parallel accumulators, which are not possible in the while loop version as each iteration depends on the previous.
Why would you want to do this as a while loop? for is definitely the correct choice of loop here. Checking all divisors is done quite clearly via:
for (int i = 1; i <= input_number; i++) { ... }
If you want to add a narrower window to that, you can just change the bounds of the loop:
for (int i = lower_bound; i <= upper_bound; i++) { ... }
Turning that into a while loop would just involve unwrapping those statements into:
int i = lower_bound;
while (i <= upper_bound) {
...
i++;
}
But this is more error-prone - if you had a continue in your loop body, i would not get incremented.
Related
This is my code for finding prime numbers between two integers. It compiles alright but giving a runtime error SIGXFSZ on codechef.
#include <bits/stdc++.h>
using namespace std;
int main() {
long long n,m;
int t;
cin>>t;
while(t--)
{
cin>>m>>n;
for(long long j=m;j<=n;j++)
for(long long i=2;i<=sqrt(j);i++)
if(j%i==0)
break;
else cout<<j<<"\n";
cout<<"\n";
}
return 0;
}
Seems that you are wrong on logic.
According to my understanding, you are supposed to print the prime numbers between two numbers.
But your code has logical errors.
1) Code doesn't consider 2 and 3 as prime numbers.
Say, m = 1, n = 10. For j = 2, 3, the inner loop won't execute even for the single time. Hence, the output won't be shown to be user.
2) else cout<<j<<"\n"; statement is placed incorrectly as it will lead to prime numbers getting printed multiple times and some composite numbers also.
Example:
For j = 11, this code will print 11 twice (for i = 2, 3).
For j = 15, this code will print 15 once (for i = 2) though it is a composite number.
You've underexplained your problem and underwritten your code. Your program takes two separate inputs: first, the number of trials to perform; second, two numbers indicating the start and stop of an individual trial.
Your code logic is incorrect and incomplete. If you were to use braces consistently, this might be clear. The innermost loop needs to fail on non- prime but only it's failure to break signals a prime, so there can't be one unless the loop completes. The location where you declare a prime is incorrect. To properly deal with this situation requires some sort of flag variable or other fix to emulate labelled loops:
int main() {
int trials;
cin >> trials;
while (trials--)
{
long long start, stop;
cin >> start >> stop;
for (long long number = start; number <= stop; number++)
{
if (number < 2 || (number % 2 == 0 && number != 2))
{
continue;
}
bool prime = true;
for (long long odd = 3; odd * odd <= number; odd += 2)
{
if (number % odd == 0)
{
prime = false;
break;
}
}
if (prime)
{
cout << number << "\n";
}
}
}
return 0;
}
The code takes the approach that it's simplest to deal with even numbers and two as a special case and focus on looping over the odd numbers.
This is basically "exceeded file size", which means that the output file is having size larger than the allowed size.
Please do check the output file size of your program.
I'm trying to find all the prime numbers between two integers and place them in an integer array.
The catch is that i have to use a specific method of doing so (divide each subsequent integer by all the primes in my array). So I can't use the sieve of Eratosthanes or any other 'easier' methods.
My code successfully prompts the user for two integers, but for now I do not use either of them. First I want to make sure the program works for values between 0 and whatever, in this case 200 just to test it.
Problem is, when I run the program and print the first 20 or so values in the array, I'm getting
2, 3, 5, 7, 11, 200, 0, 0, 0, 0, 0, 0 ...... more zeroes.
The first 5 values are correct because they start in the array, but after that the whole thing goes haywire.
I've worked through my nested loop by hand for a couple values and it SEEMS like it should work. I feel like there's a specific array property that I'm overlooking.
Here's my code:
#include "stdafx.h"
#include "iostream"
#include "climits"
#include "cmath"
#include "array"
using namespace std;
int main()
{
// declare variables to store user input
int lowerBound, upperBound;
// prompt user for lesser and greater integers and store them
cout << "Program to find all primes between two integers." << endl;
cout << "Enter lesser integer: " << endl;
cin >> lowerBound;
cout << "Enter greater integer: " << endl;
cin >> upperBound;
// if statement to switch the input variables if the user accidentally enters them backwards
if (lowerBound > upperBound) {
int temp = lowerBound;
lowerBound = upperBound;
upperBound = temp;
}
// initialize int array with the first 5 primes
int primes[100] = { 2, 3, 5, 7, 11 };
// loop to find primes between 12 and 200 (since we already have primes from 1-11 in the array)
for (int i = 12; i <= 200; i++) {
// the maximum divisor needed to determine if the current integer being tested is prime
double maxDivisor = sqrt(i);
// variable for the current size of the array
int size = 5;
// boolean variable is set to true by default
bool isPrime = true;
for (int j = 0; j < size; j++) { // changed "j<=size" to "j<size"
int remainder = (i % primes[j]);
// once the maximum divisor is reached, there is no need to continue testing for the current integer
if (primes[j] > maxDivisor) {
break;
}
// if the remainder of divison by a prime is 0, the number is not prime, so set the boolean variable to false
if (remainder = 0) {
isPrime = false;
}
}
// if isPrime is still true after the nested loop, the integer value being tested will be placed in the next element of the array
if (isPrime == true) {
primes[size] = i;
// since we added to the array, increment size by 1
size++;
}
}
// display the first 20 values in the array for debugging
for (int k = 0; k < 20; k++) {
cout << primes[k] << ", ";
}
system("pause");
return 0;
}
This here
if (remainder = 0) {
isPrime = false;
}
Needs to be changed to
if (remainder == 0) {
isPrime = false;
}
Because = does assignment, not comparison. So what remainder = 0 does it setting remainder to 0, and then it returns that 0, which gets casted to false, which is on of the reasons why it's not finding any primes.
Also, as Fantastic Mr Fox pointed out, for (int j = 0; j <= size; j++) needs to be changed to for (int j = 0; j < size; j++).
Also, did your compiler issue any warnings? If not, try to see if you can set it to be more strict with warnings. I figure most modern compilers will give you a hint at if (remainder = 0). Getting useful warnings from the compiler helps a lot with preventing bugs.
Edit:
As Karsten Koop pointed out, you need to move the int size = 5; out of the loop, to before the for (int i = 12;. With those changes, it's now working on my machine.
Last but not least, a tip: instead of if (isPrime == true), you can just write if (isPrime).
I am working on a program in which I must print out the number of primes, including 1 and 239, from 1 - 239 ( I know one and or two may not be prime numbers, but we will consider them as such for this program) It must be a pretty simple program because we have only gone over some basics. So far my code is as such, which seems like decent logical flow to me, but doesnt produce output.
#include <iostream>
using namespace std;
int main()
{
int x;
int n = 1;
int y = 1;
int i = 0;
while (n<=239)
{x = n % y;
if (x = 0)
i++;
if (y < n)
y++;
n++;
while (i == 2)
cout << n;
}
return 0;
}
The way I want this to work is to take n, as long as n is 239 or less, and preform modulus division with every number from 1 leading up to n. Every time a number y goes evenly into n, a counter will be increased by 1. if the counter is equal to 2, then the number is prime and we print it to the screen. Any help would be so greatly appreciated. Thanks
std::cout << std::to_string(2) << std::endl;
for (unsigned int i = 3; i<240; i += 2) {
unsigned int j = 3;
int sq = sqrt(i);
for (; j <= sq; j += 2) if (!(i%j)) break;
if (j>sq) std::cout << std::to_string(i) << std::endl;
}
first of all, the prime definition: A prime number (or a prime) is a natural number greater than 1 that has no positive divisors other than 1 and itself.
so you can skip all the even numbers (and hence ... i+=2).
Moreover no point to try to divide for a number greater than sqrt(i), because then it will have a divisor less than sqrt(i) and the code finds that and move to the next number.
Considering only odd numbers, means that we can skip even numbers as divisors (hence ... j+=2).
In your code there are clearly beginner errors, like (x = 0) instead of x==0. but also the logic doesn't convince. I agree with #NathanOliver, you need to learn to use a debugger to find all the errors. For the rest, good luck with the studies.
lets start with common errors:
first you want to take input from user using cin
cin>>n; // write it before starting your while loop
then,
if (x = 0)
should be:
if (x == 0)
change your second while loop to:
while (i == 2){
cout << n;
i++;
}
I want a function that works.
I believe my logic is correct, thus my (vector out of range error) must be coming from the lack of familiarity and using the code correctly.
I do know that there is long code out there for this fairly simple algorithm.
Please help if you can.
Basically, I take the length as the "moving" window as it loops through j to the end of the size of the vector. This vector is filled with stock prices.
If the length equaled 2 for a 2 day moving average for numbers 1 2 3 4. I should be able to output 1.5, 2.5, and 3.5. However, I get an out of range error.
The logic is shown in the code. If an expert could help me with this simple moving average function that I am trying to create that would be great! Thanks.
void Analysis::SMA()
{
double length;
cout << "Enter number days for your Simple Moving Average:" << endl;
cin >> length;
double sum = 0;
double a;
while (length >= 2){
vector<double>::iterator it;
for (int j = 0; j < close.size(); j++){
sum = vector1[length + j - 1] + vector1[length + j - 2];
a = sum / length;
vector2.push_back(a);
vector<double>::iterator g;
for (g = vector2.begin(); g != vector2.end(); ++g){
cout << "Your SMA: " << *g;
}
}
}
}
You don't need 3 loops to calculate a moving average over an array of data, you only need 1. You iterate over the array and keep track of the sum of the last n items, and then just adjust it for each new value, adding one value and removing one each time.
For example suppose you have a data set:
4 8 1 6 9
and you want to calculate a moving average with a window size of 3, then you keep a running total like this:
iteration add subtract running-total output average
0 4 - 4 - (not enough values yet)
1 8 - 12 -
2 1 - 13 13 / 3
3 6 4 15 15 / 3
4 9 8 16 16 / 3
Notice that we add each time, we start subtracting at iteration 3 (for a window size of 3) and start outputting the average at iteration 2 (window size minus 1).
So the code will be something like this:
double runningTotal = 0.0;
int windowSize = 3;
for(int i = 0; i < length; i++)
{
runningTotal += array[i]; // add
if(i >= windowSize)
runningTotal -= array[i - windowSize]; // subtract
if(i >= (windowSize - 1)) // output moving average
cout << "Your SMA: " << runningTotal / (double)windowSize;
}
You can adapt this to use your vector data structure.
Within your outermost while loop you never change length so your function will run forever.
Then, notice that if length is two and closes.size() is four, length + j - 1 will be 5, so my psychic debugging skills tell me your vector1 is too short and you index off the end.
This question has been answered but I thought I'd post complete code for people in the future seeking information.
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<double> vector1 { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };
double length;
cout << "Enter number days for your Simple Moving Average:" << endl;
cin >> length;
double sum = 0;
int cnt = 0;
for (int i = 0; i < vector1.size(); i++) {
sum += vector1[i];
cnt++;
if (cnt >= length) {
cout << "Your SMA: " << (sum / (double) length) << endl;
sum -= vector1[cnt - length];
}
}
return 0;
}
This is slightly different than the answer. A 'cnt' variable in introduced to avoid an additional if statement.
I have X money to buy items that the price is Y[] (max 30 item) and a item can only be purchased once.
get the maximum money you can spend.
example
input:
money: 24
amount of item: 5
item price : 7, 7, 7, 5, 5
output: maximum money spend: 24 (7+7+5+5)
What is the best algorithm to achieve this?
I have tried to make the code, but it seems very not optimal
#include <iostream>
using namespace std;
int main()
{
int X;
cout << "money: ";
cin >> X;
int Y[30]; //max 30 items
int amount; //item amount
cout << "amount of items: ";
cin >> amount;
cout << "item price: ";
for(int i=1; i<=amount; i++)
{
cin >> Y[i];
}
//sort the price
bool sort = true;
while (sort == true)
{
int temp;
sort = false;
for(int x=amount; x>=2; x--)
{
if(Y[x] < Y[x-1])
{
temp = Y[x];
Y[x] = Y[x-1];
Y[x-1] = temp;
sort = true;
}
}
}
int priceTotal = 0;
int moneyLeft = X;
int maxMoneySpend = 0;
for(int j=0; j<=amount; j++)
{
priceTotal = 0;
moneyLeft = X;
for(int i=amount-j; i>=1; i--)
if(moneyLeft - Y[i] >= 0)
{
moneyLeft -= Y[i];
priceTotal += Y[i];
}
}
if (maxMoneySpend < priceTotal)
{
maxMoneySpend = priceTotal;
}
}
cout << "maximum money spend: " << maxMoneySpend << endl;
return 0;
}
This problem can be categorized as a classical 0/1 knapsack problem. You can use the following recursive implementation to do this task. Although this is having overlapping sub problem issues.
So, the best way to resolve it is using DP (Dynamic Programming).
typedef long long ll;
ll knapsack(ll id, ll a[], ll desiredVal) // array a[] contains the values ....
{
if(desiredVal<=0 || id<0)
return 0;
if(a[id]>desiredVal)
return knapsack(id-1,a,desiredVal);
else {
ll s1 = a[id] + knapsack(id-1,a,desiredVal-a[id]); // taken the weight //
ll s2 = knapsack(id-1,a,desiredVal); // Not taken the weight //
return max(s1,s2);
}
}
From main function you can call this method like the following :
knapsack(No_Item-1,a,desiredVal);
// Like in your exm : No_Item -> 5 , a[]={7,7,7,5,5}, desiredVal -> 24
As pointed out by others, this problem is NP-complete, thus there exists no efficient solution. Your solotion is even quite fast, but unfortunately incorrect.
You sum always from the cheap to the expensive elements. Let's say you have the elements (10, 4, 4, 2, 1), and an amount of 9. You will never end up taking 4, 4, 1, which fits perfectly. The reason is that you will only in the first loop take the 1. But without the 1, you cannot get an odd number (all the others are even). After you take the 1, you will add the 2, and the 4, having 7 together. The next 4 will not fit. When you take the 4 first, you can take the next 4, having 8. But will not get to 9.
Anyway, since Y is of cardinality up to 30, you will not find an algorithm for an optimal solution. 30 is too large for todays computers. The optimal solution would be to take all subsets of Y (which is called the power set of Y), calculate for each the cost, and take the most expensive of these. There are simply too many subsets for 30 items. It might work with 20 items. You cannot do much more efficient than this.