C++ for loop multiple condition inconsistency - c++

Code in question :
#include<iostream>
using namespace std;
int main() {
int a[10] = {0, 1, 0, 1, 0, 1, 1, 0, 0, 1};
for (int i = 0; i < 10; ++i) if (a[i] == 1) cout<<i<<" ";
cout<<endl;
for (int i = 0; i < 10 && a[i] == 1; ++i) cout<<i<<" ";
cout<<endl;
}
Output:
1 3 5 6 9
// and an empty line
If my understanding of condition evaluation is correct, then both the outputs should be the same. As the condition a[i] == 1 is checked each time, i is incremented. So, why is this happening?
I have tested this with g++ and an online ide called ideone link to code.
I believe that I am missing something very basic here and it is a very dumb issue, so please forgive me for asking this in advance.

the condition loop finish in i = 0 because a[0]=0 . your condition to continue is a[i]=1. therefore it finish in first case

The condition in the for loop is evaluated before each iteration, and if it yields false, the loop is exited.
In the first case the condition is i < 10 and this becomes false only after i reaches 10, so the condition in the if is evaluated 10 times and you get the output 1 3 5 6 9.
In the second case the condition is i < 10 && a[i] == 1 which becomes false on the very first iteration when i is 0 as a[0] is 0. The for loop is then terminated and the condition in the if statement is never evaluated and so you do not get any output.

No. The results are not the same. In the first one, the for loop scrolls over 0 to 9 and each time the inner if checks whether the corresponding index of a is equal to 1 or not. So the performance of the first one is clear. The second one acts quite different. The second for holds as long as the condition holds (while it doesn't even hold at the beginning since a[0]=0).
A better example is:
int x[]={1, 1, 1, 0, 0, 0, 0, 0, 1, 1};
the first loop prints out 0 1 2 8 9 and the second one's output is 0 1 2.

Related

C++ Variable mysteriously changed after calling unrelated function

I have the following code for a board game program that I am making. The function "copyMap" simply copies the contents of the first array map to the second array map_copy. In the function "solver", I have a loop that iterates over the game grid, and for each cell, call copyMap.
The issue is, when solver is called, it runs for 1 iteration then promptly crashes the program. Moreover, the iterators, x_pos and y_pos, which are supposed to start at 0 and 0, gets changed to 2 and 5 after calling copyMap and before the program crashes.
void copyMap(int map[][WIDTH], int map_copy[][WIDTH], int rows_to_copy) {
// copy the contents of the first rows_to_copy rows of map to map_copy
for( int i = 0 ; i < rows_to_copy ; i++ ) {
for( int j = 0 ; j < WIDTH ; j++ ) {
map_copy[i][j] = map[i][j];
cout<<i<<" "<<j<<endl;
}
}
}
int solver(int map[][WIDTH]) {
int map_copy[HEIGHT][WIDTH];
for(int x_pos = 0 ; x_pos < HEIGHT ; x_pos++ ) {
for(int y_pos = 0 ; y_pos < WIDTH ; y_pos++ ) {
copyMap(map, map_copy, MAX_ROWS);
cout<<x_pos<<" "<<y_pos<<endl;
}
}
}
This is the console output: (For the first iteration of the loop)
0 0
0 1
0 2
...
81 8
2 5
The game grid has 81 rows and 9 columns, so copyMap prints 0 0, 0 1, ..., 81 8.
Then, solver prints 2 5. However, the iterators are still supposed to be 0 0.
The iterators are not passed to the function copyMap at all. Why are their values being changed, and why is my program crashing?
I would appreciate any help on this issue, thank you.
Copymap iterates through each element. I don't think you need to call it inside a nested loop inside solver. You should take it outside of the loop and set a breakpoint inside the loop to watch x_pos and y_pos.
Solved, turns out map has 81 rows and 9 columns but map_copy only has 9 rows and 9 columns, so copyMap tried to access out-of-bounds memory locations.

Sum of array elements by order until target reached or end of the array reached

Let's say that I have this array:
int A[6] = {1, 7, 2, 4, 3, 9};
And I have the target number at 6. We want to add the numbers until target reached or at least close to the target.
The numbers that comes first have bigger priority, so it would look like this:
Add 1 and 7, which results in 8.
8 is bigger than 6, so ignore this sum and keep 1.
Add 1 and 2.
1 plus 2 results in 3, which is smaller than 6, so we go to the next element after 2,
while holding the successful result.
Right now, result is 3, and the next element is 4, but 3 plus 4 is bigger than 6,
so we don't do anything with our result, and go to the next element.
Result is still 3.
3 plus 3 is 6, so we succesfully reached our target.
We don't need to check the last element (9).
In the end, we added 1, 2 and 3.
Another example:
int B[4] = {5, 4, 3, 2};
Procedure:
Add 5 and 4.
Result is bigger than 6, so ignore the sum and keep 5.
Add 5 and 3. Still bigger than 6, ignore the sum and keep 5.
5 plus 2, 7. Bigger than 6 again.
The final result is 5.
In the end we didn't add anything, and kept 5.
I can't seem to figure the code for this pattern.
EDIT: I've come up with a code that works. Also, it executes until there's no leftovers in the array, dividing the array into parts, redoing the process until theres no element left in the array to be processed. Here it is:
int array[5] = { 500, 1000, 500, 500, 400 };
int arraySize = sizeof(array) / sizeof(array[0]);
int i = 1;
int j = 0;
int sum;
while (j < arraySize)
{
sum = 0;
sum += array[j];
while (i < arraySize)
{
if (sum + array[i] <= 1500)
{
sum += array[i];
array[i] = 0;
i++;
}
else
i++;
}
if (sum != 0)
cout << "Part " << j + 1 << ": " << sum << endl;
j++;
i = j + 1;
}
In this example, we have the target number at 1500, with this array:
int array[5] = { 500, 1000, 500, 500, 400 };
The code returns
Part 1: 1500
Part 2: 1400
it does the same procedure as the other two examples that I gave, but redoing it with all the elements:
Add 500 and 1000, which results in 1500.
1500 is the target number, so doing a sum is not needed anymore,
so it prints the first part that fit in the target,
while maintaining the priority protocol.
Now, add 500 (the 3rd element) plus 500, which results in 1000.
1000 is smaller than 1500, so we keep going.
1000 plus 400 is 1400, which is smaller than 1500, but is the last
element, so we finish here.
Well, the code works, but it was kind of a "trial and error" success. Also, I have a new problem, which is: getting the indexes of the elements that were successful in the sum. It should print something like this:
Part 1: 1500
0, 1
Part 2: 1400
2, 3, 4

Remove the first smallest number in a vector in C++ (and keep the order)

I have an vector<int> number_vector that contains {1, 0, 0, 0, 0, 0 ,0}. I need to iterate over this number_vector, e.g 4 times, and remove the first smallest number at each iteration, i.e at the first iteration I will remove the value 0 at the index 1, at the next iteration I will remove the 0 that is at the index 1, etc. I'm doing this right now the following way:
int n = 7;
int d = 4;
vector<int> number_vector{1, 0, 0, 0, 0, 0 ,0};
for (int counter = 0; counter < n - d; counter++)
{
int index = distance(number_vector.begin(), min_element(number_vector.begin(), number_vector.end()));
if (index != number_vector.size() - 1)
{
number_vector[index] = move(number_vector.back());
}
number_vector.pop_back();
// number_vector.erase(number_vector.begin() + index);
}
The problem it's that if I run the code above, at the end number_vector has {1, 0, 0, 0} while it should have {1, 0, 0}, and for other cases like n = 4, d = 2 and number_vector{3, 7, 5, 9}, the final number_vector has the right value, that is 79. Some tips?
First of all you're iterating three times, not four. Secondly, if the vector isn't required, you can just use a map and pop the front iterator since it will always be the lowest value. Finally, there is no need for a swap or distance, just erase the result of min_element if it's not invalid.
When you iterate from 0 to n-d, with n=7 and d=4. you will iterate from counter=0 to counter < 7-4, i.e., 3. So your loop will iterate 3 times with values 0, 1 and 2. This will remove three zeros from number_vector. So your code is behaving as expected.
I think what you want is to iterate from 0 to d. Also you are unnecessarily complicating the code by using index. You can use the iterator directly like below.
for (int counter = 0; counter < d; counter++)
{
*min_element(number_vector.begin(), number_vector.end()) = *number_vector.rbegin();
number_vector.pop_back();
}
Is your d represents the times of pop minimum number from vector?
Then modify counter < n - d to counter < d, it will have {1, 0, 0}
11.04
if you want to keep the order,you can modify
for (int counter = 0; counter < d; ++counter)
{
auto iter = min_element(number_vector.begin(), number_vector.end());
number_vector.erase(iter);
}
PS:std::list maybe a better choice?

Bitwise operator in if statement

While going through a code i saw this.
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
{
if(i & (1<<j))
{
//code
}
}
}
can anyone how this loop will work?
I know that right part will give be pow(2,j), but i don't understand how will & work here.
It loops over all values from 0 to n, and for each of these:
It loops over each bit in the value. if the value is set:
It executes //code
Lets examine the complex part:
if(i & (1<<j))
1<<j is a common way to set the jth bit (starting from zero). If j==0, then it's 0b00001, if j==3 then it's 0b01000. Then i & <bit> evaluates to <bit> if that bit is set in i, and otherwise it evaluates to 0. So this checks to see if the jth bit is set in i.
The value pairs that trigger the code are these:
i binary js
0 000
1 001 0
2 010 1
3 011 0, 1
4 100 2
5 101 0, 2
6 110 1, 2
etc...
31 11111 0, 1, 2, 3, 4,
Notice how the 1s in the binary mirror the j values for which the code triggers.
Note that if n>=32 then it tries to shift the values too far, and that's undefined behavior. Be sure that doesn't happen.

Calculating Hamming Sequence in C++ (a sequence of numbers that has only 2, 3, and 5 as dividers) [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Generating a sequence using prime numbers 2, 3, and 5 only, and then displaying an nth term (C++)
I've been brainstorming over this forever, and I just can't figure this out. I need to solve the following problem:
Generate the following sequence and display the nth term in the
sequence
2,3,4,5,6,8,9,10,12,15, etc..... Sequence only has Prime numbers
2,3,5
I need to use basic C++, such as while, for, if, etc. Nothing fancy. I can't use arrays simply because I don't know much about them yet, and I want to understand the code for the solution.
I'm not asking for a complete solution, but I am asking for guidance to get through this... please.
My problem is that I can't figure out how to check if the number if the number in the sequence is divisible by any other prime numbers other than 2, 3, and 5.
Also let's say I'm checking the number like this:
for(int i=2; i<n; i++){
if(i%2==0){
cout<<i<<", ";
}else if(i%3==0){
cout<<i<<", ";
}else if(i%5==0){
cout<<i<<", ";
}
It doesn't work simply due to the fact that it'll produce numbers such as 14, which can be divided by prime number 7. So I need to figure out how to ensure that that sequence is only divisible by 2, 3, and 5..... I've found lots of material online with solutions for the problem, but the solutions they have are far too advance, and I can't use them (also most of them are in other languages... not C++). I'm sure there's a simpler way.
The problem with your code is that you just check one of the prime factors, not all of them.
Take your example of 14. Your code only checks if 2,3 or 5 is a factor of 14, which is not exactly what you need. Indeed, you find that 2 is a factor of 14, but the other factor is 7, as you said. What you are missing is to further check if 7 has as only factors 2,3 and 5 (which is not the case). What you need to do is to eliminate all the factors 2,3 and 5 and see what is remaining.
Let's take two examples: 60 and 42
For 60
Start with factors 2
60 % 2 = 0, so now check 60 / 2 = 30.
30 % 2 = 0, so now check 30 / 2 = 15.
15 % 2 = 1, so no more factors of 2.
Go on with factors 3
15 % 3 = 0, so now check 15 / 3 = 5.
5 % 3 = 2, so no more factors of 3.
Finish with factors 5
5 % 5 = 0, so now check 5 / 5 = 1
1 % 5 = 1, so no more factors of 5.
We end up with 1, so this number is part of the sequence.
For 42
Again, start with factors 2
42 % 2 = 0, so now check 42 / 2 = 21.
21 % 2 = 1, so no more factors of 2.
Go on with factors 3
21 % 3 = 0, so now check 21 / 3 = 7.
7 % 3 = 1, so no more factors of 3.
Finish with factors 5
7 % 5 = 2, so no more factors of 5.
We end up with 7 (something different from 1), so this number is NOT part of the sequence.
So in your implementation, you should probably nest 3 while loops in your for loop to reflect this reasoning.
Store the next i value in temporary variable and then divide it by 2 as long as you can (eg. as long as i%2 == 0). Then divide by 3 as long as you can. Then by 5. And then check, what is left.
What about this?
bool try_hamming(int n)
{
while(n%2 == 0)
{
n = n/2;
}
while(n%3 == 0)
{
n = n/3;
}
while(n%5 == 0)
{
n = n/5;
}
return n==1;
}
This should return true when n is a hamming nummer and false other wise. So the main function could look something like this
#include<iostream>
using namespace std;
main()
{
for(int i=2;i<100;++i)
{
if(try_hamming(i) )
cout<< i <<",";
}
cout<<end;
}
this schould print out all Hamming numbers less then 100