gooday programers. I have to design a C++ program that reads a sequence of positive integer values that ends with zero and find the length of the longest increasing subsequence in the given sequence. For example, for the following
sequence of integer numbers:
1 2 3 4 5 2 3 4 1 2 5 6 8 9 1 2 3 0
the program should return 6
i have written my code which seems correct but for some reason is always returning zero, could someone please help me with this problem.
Here is my code:
#include <iostream>
using namespace std;
int main()
{
int x = 1; // note x is initialised as one so it can enter the while loop
int y = 0;
int n = 0;
while (x != 0) // users can enter a zero at end of input to say they have entered all their numbers
{
cout << "Enter sequence of numbers(0 to end): ";
cin >> x;
if (x == (y + 1)) // <<<<< i think for some reason this if statement if never happening
{
n = n + 1;
y = x;
}
else
{
n = 0;
}
}
cout << "longest sequence is: " << n << endl;
return 0;
}
In your program, you have made some assumptions, you need to validate them first.
That the subsequence always starts at 1
That the subsequence always increments by 1
If those are correct assumptions, then here are some tweaks
Move the cout outside of the loop
The canonical way in C++ of testing whether an input operation from a stream has worked, is simply test the stream in operation, i.e. if (cin >> x) {...}
Given the above, you can re-write your while loop to read in x and test that x != 0
If both above conditions hold, enter the loop
Now given the above assumptions, your first check is correct, however in the event the check fails, remember that the new subsequence starts at the current input number (value x), so there is no sense is setting n to 0.
Either way, y must always be current value of x.
If you make the above logic changes to your code, it should work.
In the last loop, your n=0 is execute before x != 0 is check, so it'll always return n = 0. This should work.
if(x == 0) {
break;
} else if (x > y ) {
...
} else {
...
}
You also need to reset your y variable when you come to the end of a sequence.
If you just want a list of increasing numbers, then your "if" condition is only testing that x is equal to one more than y. Change the condition to:
if (x > y) {
and you should have more luck.
You always return 0, because the last number that you read and process is 0 and, of course, never make x == (y + 1) comes true, so the last statement that its always executed before exiting the loop its n=0
Hope helps!
this is wrong logically:
if (x == (y + 1)) // <<<<< i think for some reason this if statement if never happening
{
Should be
if(x >= (y+1))
{
I think that there are more than one problem, the first and most important that you might have not understood the problem correctly. By the common definition of longest increasing subsequence, the result to that input would not be 6 but rather 8.
The problem is much more complex than the simple loop you are trying to implement and it is usually tackled with Dynamic Programming techniques.
On your particular code, you are trying to count in the if the length of the sequence for which each element is exactly the successor of the last read element. But if the next element is not in the sequence you reset the length to 0 (else { n = 0; }), which is what is giving your result. You should be keeping a max value that never gets reset back to 0, something like adding in the if block: max = std::max( max, n ); (or in pure C: max = (n > max? n : max );. Then the result will be that max value.
Related
I am a beginner currently in first semester. I have been practising on Code Chef and am stuck at this problem. They are asking to reduce the execution time of my code. The problem goes as follows:
Meliodas and Ban are fighting over chocolates. Meliodas has X chocolates, while Ban has Y. Whoever has lesser number of chocolates eats as many chocolates as he has from the other's collection. This eatfest war continues till either they have the same number of chocolates, or at least one of them is left with no chocolates.
Can you help Elizabeth predict the total no of chocolates they'll be left with at the end of their war?
Input:
First line will contain T, number of testcases. Then the testcases follow.
Each testcase contains of a single line of input, which contains two integers X,Y, the no of chocolates Meliodas and Ban have, respectively.
Output:
For each testcase, output in a single line the no of chocolates that remain after Ban and Meliodas stop fighting.
Sample Input:
3
5 3
10 10
4 8
Sample Output:
2
20
8
My code is as follows:
#include <iostream>
using namespace std;
int main()
{
unsigned int t,B,M;
cin>>t;
while(t--)
{
cin>>M>>B;
if(B==M)
{
cout<<B+M<<endl;
}
else
{
for(int i=1;B!=M;i++)
{
if(B>M)
B=B-M;
else
M=M-B;
}
cout<<M+B<<endl;
}
}
return 0;
}
Assuming that Band Mare different from 0, this algorithm corresponds to one version of the Euclidean algorithm. Therefore, you can simply:
std::cout << 2 * std::gcd(B, M) << "\n";
If at least one of the quantity is equal to 0, then just print B + M.
After realizing that your code was correct, I wondered where could be any algorithmic improvement. And I realized that eating as many chocolate from the peer as one has was in fact close to a modulo operation. If both number are close, a minus operation could be slightly faster than a modulo one, but if one number is high, while the other is 1, you immediately get it instead of looping a great number of times...
The key to prevent stupid errors is to realize that if a modulo is 0, that means that the high number is a multiple of the small one and we must stop immediately writing twice the lower value.
And care should be taken that if one of the initial counts are 0, the total number will never change.
So the outer loop should become:
if(B==M || B == 0 || M == 0)
{
cout<<B+M<<"\0";
}
else {
for (;;) {
if (M < B) {
B = B % M;
if (B == 0) {
cout << M * 2 << '\n';
break;
}
}
else {
M = M % B;
if (M == 0) {
cout << B * 2 << '\n';
break;
}
}
}
}
...
Note: no infinite loop is possible here because a modulo ensures that for example is M > B > 0' after M = M % Byou will haveB > M >= 0and as the case== 0` is explicitely handled the number of loops cannot be higher than the lower number.
I want to write a program that get the numbers with this rule :
every number be greater or smaller than the numbers before and after itself. like : 3 1 4 2 6 0 8 3 5 16
Whenever this rule was violated, stop getting number.
int a, b, c;
bool flag = true;
cin >> a;
while (flag)
{
cin >> b;
cin >> c;
if ((b < a && b < c) || (b > a && b > c))
{
flag = true;
a = c;
}
else
{
break;
}
}
My code works for some inputs but for this inputs : 3 1 4 6
When i enter 6 the program must be stop, but it continue to input next number. What should i do to fix it?
The solution to this problems involves a lot of logical evaluations. So, we need many boolean expressions and if statements.
One key to the solution, is to keep track of 2 values:
The current read value
The preivously read, old value
We can always compare those values and then make descisions. Problem is that we do not have an "previous" value in the beginning. So, we need to do a special treatment and first read a value from the user, store this as prvious value, and then always read a current value in a loop.
At the end of the loop, we will assign the current value to the "previuosValue". Then in the next loop run, we always need to read only the current value from the user.
Ant those 2 values, we can compare in a while loop.
We compare the current value with the previous value, and, depending of the outcome, define a "direction" flag for further comparisons.
This we do after having read the 2nd number. After that the direction is always defined and will never change.
Example, if the current value is bigger than the previous value, then, in the next loop, the next value must be smaller. And vice versa.
Example:
First value: 2
2nd value: 6
The second value is bigger than the first value. So, for next values we expect
small --> big --> small --> big --> small --> big --> . . .
and so on. This will never change.
Same is valid vice versa.
First value: 9
2nd value: 1
The second value is smaller than the first value. So, for next values we expect
big --> small --> big --> small --> big --> small --> big --> . . .
The direction flag will always be inverted after having processed the "next" number.
We can then evaluate the stop condition in the next loop run. Does the comparision result to a value, to a direction, that we expect?
If not, or if the values are equal, then we stop the input.
Of course, we will not do this evaluation in the first loop, because then, we have always a valid pair and calculate the direction afterwards.
So, you see. We always need only 2 variables.
There are many possible implementations, as always. Please see the below as an example for a solution:
#include <iostream>
int main() {
// Read initial previous number (The first number)
if (int previousNumber{}; std::cin >> previousNumber) {
// Flag that indicates, if we should continue reading new numbers or not
bool continueToRead{ true };
// First number needs special treatment, there is no other number
bool firstCheck{ true };
// The "direction" of the comparison
bool nextNumberMustBeSmaller{false};
// Read numbers in a loop
while (continueToRead) {
// Read current (next) number
if (int currentNumber{}; std::cin >> currentNumber) {
// After heaving read the first value in the loop, we can detect the direction
if (firstCheck) {
// Get the "direction" of the comparison for the next numbers
// If the number is bigger than last number
if (currentNumber > previousNumber)
// Then next value muste be smaller
nextNumberMustBeSmaller = true;
// If this number is smaller
else if (currentNumber < previousNumber)
// then next number must be bigger
nextNumberMustBeSmaller = false;
else
continueToRead = false;
// First check has been done
firstCheck = false;
}
else {
// Find out the stop condition
if (
// Direction is smaller but number is bigger or
(nextNumberMustBeSmaller and (currentNumber > previousNumber)) ||
// Direction is bigger but number is smaller or
(not nextNumberMustBeSmaller and (currentNumber < previousNumber)) ||
// Or numbers are equal
(currentNumber == previousNumber)) {
// Then: Stop reading values
continueToRead = false;
}
nextNumberMustBeSmaller = not nextNumberMustBeSmaller;
}
// Remember the last value. So, for the next loop rund, the current value will become the previous one
previousNumber = currentNumber;
}
else {
std::cerr << "\n\nInvalid input\n\n";
continueToRead = false;
}
}
}
else std::cerr << "\n\nInvalid input\n\n";
return 0;
}
To be compiled with C++17 enabled.
Here are some observations if we take the task as given in your question, but I think you may have misunderstood the task in one way or another.
every number be greater or smaller than the numbers before and after itself
greater or smaller means not equal.
you can't check the next number. You don't even know if there is a next number, so you can only check against the previous number
The final condition then becomes "stop if current and last number are equal"
In code this could look like this:
int a, b;
cin >> a;
while (cin >> b && a != b)
{
a = b; // current number becomes the last number
}
Note that I removed flag, because it was never set to false. The break will be enough. And I moved the cin >> b into the loop condition to validate the input. Then it turned out that we can merge the if-block into the loop condition as well.
When I try to solve this problem I write the following code:
int x = 1;
while(x%2 != 0 && x <= 50) { //x%2 != 0 defines odd integers and x<=50 gives the first 25
cout << pow(x,0.5) << endl;
x = x + 1;
}
This code only prints out the value of the square root of 1. So I edit the code like so:
int x = 1;
while(x%2 != 0 && x <= 50) {
cout << pow(x,0.5) << endl;
x = x + 2;
}
Now it prints out all the 25 odd integer square roots.
So the problem with the first code is clearly that the while loop is stopping once the square root cannot be executed (i.e. when the integer is even). It is executing the square root of 1, moving on to the integer 2, not executing the square root, and instead of then moving onto the integer 3 it is stopping. This is why the second code works: because I am adding 2 it is only ever meeting an odd integer, so always works and thus continues until x<=50.
How can I stop it from stopping and why is it doing this? I would have thought that it would register each and every integer that satisfies the condition but it is not doing this.
while executes while the condition is true. On the second iteration x == 2, so the condition x%2 != 0 becomes false, consequently x%2 != 0 && x <= 50 becomes false and while loop terminates.
You already solved How can I stop it from stopping part by incrementing x by 2, so it's unclear what you are asking here.
I can't understand how to count number of 1's in binary representation.
I have my code, and I hope someone can explain it for me.
Code:
int count (int x)
{
int nr=0;
while(x != 0)
{
nr+=x%2;
x/=2;
}
return nr;
}
Why while ? For example if i have 1011, it wouldn't stop at 0?
Why nr += x%2 ?
Why x/=2 ?!
First:
nr += x % 2;
Imagine x in binary:
...1001101
The Modulo operator returns the remainder from a / b.
Now the last bit of x is either a 0, in which case 2 will always go into x with 0 remainder, or a 1, in which case it returns a 1.
As you can see x % 2 will return (if the last bit is a one) a one, thus incrementing nr by one, or not, in which case nr is unchanged.
x /= 2;
This divides x by two, and because it is a integer, drops the remainder. What this means is is the binary was
....10
It will find out how many times 2 would go into it, in this case 1. It effectively drops the last digit of the binary number because in base 2 (binary) the number of times 2 goes into a number is just the same as 'shifting' everything down a space (This is a poor explanation, please ask if you need elaboration). This effectively 'iterates' through the binary number, allowing the line about to check the next bit.
This will iterate until the binary is just 1 and then half that, drop the remainder and x will equal 0,
while (x != 0)
in which case exit the loop, you have checked every bit.
Also:
'count`is possibly not the most descriptive name for a function, consider naming it something more descriptive of its purpose.
nr will always be a integer greater or equal to zero, so you should probably have the return type unsigned int
int count (int x)
{
int nr=0;
while(x != 0)
{
nr+=x%2;
x/=2;
}
return nr;
}
This program basically gives the numbers of set bits in a given integer.
For instance, lets start with the example integer 11 ( binary representation - 1011).
First flow will enter the while loop and check for the number, if it is equal to zero.
while(11 != 0)
Since 11 is not equal to zero it enter the while loop and nr is assigned the value 1 (11%2 = 1).nr += 11%2;
Then it executes the second line inside the loop (x = x/2). This line of code assigns the value 5 (11/2 = 5 ) to x.
Once done with the body of the while loop, it then again checks if x ie 5 is equal to zero.
while( 5 != 0).
Since it is not the case,the flow goes inside the while loop for the second time and nr is assigned the value 2 ( 1+ 5%2).
After that the value of x is divided by 2 (x/2, 5/2 = 2 )and it assigns 2 to x.
Similarly in the next loop, while (2 != 0 ), nr adds (2 + 2%2), since 2%2 is 0, value of nr remains 2 and value of x is decreased to 1 (2/2) in the next line.
1 is not eqaul to 0 so it enters the while loop for the third time.
In the third execution of the while loop nr value is increased to 3 (2 + 1%2).
After that value of x is reduced to 0 ( x = 1/2 which is 0).
Since it fails the check (while x != 0), the flow comes out of the loop.
At the end the value of nr (Which is the number of bits set in a given integer) is returned to the calling function.
Best way to understand the flow of a program is executing the program through a debugger. I strongly suggest you to execute the program once through a debugger.It will help you to understand the flow completely.
I am new to C++ programming and I am a bit lost. Here is what I am suppose to do and my code. Any ideas on what to do?
Write a program that uses while loops to calculate the first n Fibonacci numbers. Recall from math the following definition of the Fibonacci sequence:
The Fibonacci numbers Fn are defined as follows. F0 is 1, F1 is 1 and Fi+2 = Fi + Fi+1 for i = 0, 1, 2, ... . In other words, each number is the sum of the previous two numbers. The first few Fibonacci numbers are 1, 1, 2, 3, 5, 8, and 13.
The program should prompt the user for n (the number of Fibonacci numbers) and print the result to the screen. If the user enters an invalid value for n (n <= 0), print an error message and ask the user to re-enter n (an input validation loop for n). This MUST be a loop, not an if statement like Lab 2.
The output should be similar to the following:
Enter the number of Fibonacci numbers to compute: 3
The first 3 Fibonacci numbers are:
1 1 2
#include <iostream>
using namespace std;
int main()
{
int f0 = 0, f1 = 1,f2= 2, i = 0, n;
cout << "Enter the number of Fibonacci numbers to compute: ";
cin >> n;
if ( n <= 0)
{
cout <<"Error: Enter a positive number: ";
return 1;
}
while ( i < n){
f2 = f0 + f1;
i++;
}
cout << "The first " << n << " Fibonacci numbers are: " << endl;
cin >> n;
return 0;
}
while ( i < n){
f2 = f0 + f1;
i++;
}
See this loop, this is where the problem is, since this is homework, i'll not tell exactly what the problem is, take a pen and paper, and start executing your statements, specially this loop, you'll find your error. Just a hint, Fibonacci number is the sum of previous two fibonacci numbers.
You got the f2=f0+f1 right. However, you should note that when you increment i, then f2 becomes f1 and f1 becomes f0.
If you name them like this, it would make more sense:
int f_i_minus_2 = 0, f_i_minus_1 = 1, f_i;
and you would have
f_i = f_i_minus_1+f_i_minus_2;
Now, imagine i is 3. You have written:
f[3] = f[2]+f[1]
When you increment i, you must have:
f[4] = f[3]+f[2]
That is f_i is put in the place of f_i_minus_1 and f_i_minus_1 is put in the place of f_i_minus_2.
(Look at this:
f[3] = f[2] + f[1]
| |
\_____ \____
\ \
f[4] = f[3] + f[2]
)
So you need two assignments after computing f_i:
f_i_minus_2 = f_i_minus_1;
f_i_minus_1 = f_i;
Note that I first changed f_i_minus_2 to f_i_minus_1 because the second assignment destroys the value of f_i_minus_1.
According to wikipedia, your definition is off. F0=0, F1=1, F2=1, F3=2, ...
http://en.wikipedia.org/wiki/Fibonacci_number
Assuming wikipedia is right your loop is basically
int i = 0, f, fprev;
while( i < n )
{
if( i == 0 )
{
f = 0;
fprev = 0;
}
else if( i == 1 )
{
f = 1;
}
else
{
int fnew = f + fprev;
fprev = f;
f = fnew;
}
i++;
}
As others have pointed out, since you never modify f0 and f1 in the
loop, f2 isn't going to depend on the number of times through the
loop. Since you have to output all of the numbers at the end anyway,
why not try keeping them in an array. I'd initialize the first two
values manually, then loop until I had enough values.
(This can be done quite nicely using the STL:
// After having read n...
std::vector<int> results( 2, 1 );
while ( results.size() < n )
results.push_back( *(results.end() - 1) + *(results.end() - 2));
I'm not sure that this is what your instructor is looking for, however.
I rather suspect that he wants you to to some indexing yourself. Just
remember that if you initialize the first two values manually, your
index must start at 2, not at 0.)
Another thing: the specification you post says that you should loop if
the user enters an illegal value. This is actually a little tricky: if
the user enters something that isn't an int (say "abc"), then 1)
std::cin will remain in error state (and all further input will fail)
until cleared (by calling std::cin.clear()), and the illegal
characters will not be extracted from the stream, so your next attempt
will fail until you remove them. (I'd suggest >>ing into an
std::string for this; that will remove everything until the next white
space.) And don't ever access the variable you >>ed into until
you've checked the stream for failure—if the input fails. If the
input fails, the variable being input is not modified. If, as here, you
haven't initialized it, then anything can happen.
Finally (and I'm sure this goes beyond your assignment), you really do
need to do something to check for overflow. Beyond a certain point,
your output will become more or less random; it's better to stop and
output that you're giving up in this case.
If you are interested, there are better ways to calculate it.