Why is the difference between behaviors in for loop? - c++

I am confused by getting the different results after executing the same loops after one another.
The first loop Increments the different way and second is completely different.
Results:
1 , 1
1 , 2
1 , 3
2 , 1
2 , 2
2 , 3
3 , 1
3 , 2
3 , 3
Code:
#include <iostream>
using namespace std;
int main()
{
for(int outerval {1}; outerval <= 3; outerval++)
for(int innerval {1}; innerval <= 3; innerval++)
cout << outerval << " , " << innerval << '\n';
return 0;
}

You have a nested loop here. For each iteration of the outer loop, the inner loop is completed. The output is hence to be expected. If you want to tear these loops apart, you can do so by
for(int innerval {1}; innerval <= 3; innerval++)
cout << innerval << '\n';
for(int outerval {1}; outerval <= 3; outerval++)
cout << outerval << '\n';
which will print
1
2
3
1
2
3

When you execute a for loop it first finishes, whatever is inside it then it goes to the next iteration, so it first finishes the inner for loop and then the outer for loop enters the next iteration, then it finishes the inner again, etc.
If you want the two loops to iterate one after the other you'd do this:
for (int i = 0; i < 4; i++){
cout << i << endl;
}
for (int i = 0; i < 4; i++){
cout << i << endl;
}
result:
0
1
2
3
0
1
2
3

Related

Output a triangle of numbers in C++

My task is to ask the user for an int, then output a "number triangle" like the one below (in this case, the int is equal to 5).
0 1 2 3 4 5
0 1 2 3 4
0 1 2 3
0 1 2
0 1
0
However, the code which I have written for this task outputs this:
0 1 2 3 4 5
0 1 2 3 4
0 1 2 3
0 1 2
0 1
0
For reference, here is my code:
#include <iostream>
using namespace std;
int main() {
int size;
cout << "Size: " << std::endl;
cin >> size;
for(int i = size; i >= 0; i--)
{
for(int j = 0; j <= i; j++)
{
if (j < i){
cout << j << " ";
}
else{
cout << j << " ";}
}
cout << endl;
}
return 0;
}
Can somebody tell me what to change in my program to make it output the correct triangle? Thanks in advance.
You should print the spaces at the beginning of the line instead of at the end.
for(int i = size; i >= 0; --i){
for(int j = 0; j < size-i; ++j){cout << " ";} // spaces at the beginning
for(int j = 0; j <= i; ++j){
cout << j << " ";
}
cout << endl;
}

C++ - Building Addition Tables

I am having some troubles with this problem presented from my lab. My goal is to produce an addition table that looks something like this -
(From range(1-5)) :
+ 1 2 3 4 5
1 2 3 4 5 6
2 3 4 5 6 7
3 4 5 6 7 8
4 5 6 7 8 9
5 6 7 8 9 10
Mine is looking like this, however :
+ 1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
5 6 7 8 9
My code looks like this :
if (choice == ADD) {
cout << "+";
for (int i = 0; i < max; i++) {
cout << "\t";
for (int j = min; j <= max; j++) {
cout << i + j << "\t";
}
}
}
(For reference, int max = maximum number in range, int min = minimum number in range, and choice is the decision for user to do either an addition or multiplication table). How can I change my code to fit the proper format? I can't seem to figure it out. Any hints/help would be greatly appreciated :)
#include <iostream>
using namespace std;
int main(){
int max = 5;
int min = 1;
if (true){
cout << "+\t";//print out the initial +
for(int i = min; i <= max; i++) cout << i << "\t";//print out the entire first row
cout << "\n"; //start the next row
//here is the main loop where you do most of the logic
for(int i = min; i <= max; i++){
cout << i << "\t"; //this prints out the first column of numbers
for(int j = min; j <=max; j++){
cout << j+i << "\t"; //this line fills in the body of your table
}
cout << "\n";//creates the space between each row
}
}
}
This code builds the table as explained:
for (int i = 0; i <= max; i++) {
if (i == 0)
cout << '+';
else
cout << i;
cout << '\t';
for (int j = min; j <= max; j++) {
cout << i + j << '\t';
}
cout << '\n';
}
Tip: when you want to print only a character, it is more efficient to use single quotes like '+' or '\t'. Double quotes are more expensive because they represent a const char*.

vectors in range based for loop

I was testing vector to vector initialization, I used range based for loop it gives different output.
with respect to Normal for loop.
vector<int> intVector;
for(int i = 0; i < 10; i++) {
intVector.push_back(i + 1);
cout << intVector[i] << endl;
}
cout << "anotherVector" << endl;
vector<int> anotherVector(intVector);
for(auto i : anotherVector)
cout << anotherVector[i] << endl;
//for(unsigned int i = 0; i < anotherVector.size(); i++) {
// cout << anotherVector[i] << endl;
//}
this range based for loop gives the output - Linux ubuntu
Output
STLTest Cunstructor Called.
1
2
3
4
5
6
7
8
9
10
anotherVector
2
3
4
5
6
7
8
9
10
81
2.
vector<int> intVector;
for(int i = 0; i < 10; i++) {
intVector.push_back(i + 1);
cout << intVector[i] << endl;
}
cout << "anotherVector" << endl;
vector<int> anotherVector(intVector);
//for(auto i : anotherVector)
// cout << anotherVector[i] << endl;
for(unsigned int i = 0; i < anotherVector.size(); i++) {
cout << anotherVector[i] << endl;
}
This gives different output.
output
STLTest Cunstructor Called.
1
2
3
4
5
6
7
8
9
10
anotherVector
1
2
3
4
5
6
7
8
9
10
why both for loop acting differently?
for(auto i : anotherVector)
cout << anotherVector[i] << endl;
This code doesn't do what you think it does. The range-based for loop iterates over values, not over indices. In other words, the loop variable (i) is assigned all ements of the vector in turn.
To replicate the functionality of your first loop, you need this:
for (auto i : anotherVector)
cout << i << endl;
What your original code was doing was take an element of the vector, and use it to index into the vector again. That's why the numbers were off by one (since the vector held number n + 1 at position n). Then, the final output (81 in your case) was effectively random and the result of Undefined Behaviour—you were reaching past the end of the vector.

Wrong output while printing a multidimensional array

i have some trouble while printing this pseudo-multidimensional array , with elements that are set already.
And the point of it is to swap the first and third row and 2nd and 4th column, but the output looks weird...
#include <iostream>
using namespace std;
int main()
{
int arr[12]= {
1,2,3,4,5,6,7,8,6,4,5,3
};
cout << "Before change: "<<endl;
for (int row=0;row<3;row++){
for (int col=0;col<4;col++){
cout << arr[row*col]<<" ";
}
cout <<endl;
}
cout << "After the row change: "<<endl;
for (int row=2;row>=0;row--){
for(int col=0;col<4;col++){
cout<<arr[row*col]<<" ";
}
cout<<endl;
}
cout << "After the column change: "<<endl;
int temp;
for(int row=0;row<3;row++){
temp=arr[row*1];
arr[row*1]=arr[row*3];
arr[row*3]=temp;
for (int col=0;col<4;col++){
cout<<arr[row*col]<<" ";
}
cout<<endl;
}
Instead of having an output like this:
1 2 3 4
5 6 7 8
6 4 5 3
6 4 5 3
5 6 7 8
1 2 3 4
6 3 5 4
5 8 7 6
1 4 3 2
i get this :
1 1 1 1
1 2 3 4
1 3 5 7
1 3 5 7
1 2 3 4
1 1 1 1
1 1 1 1
1 4 3 2
1 7 5 3
You wrong how to calculate the element inside the array arr[row*col] will be always 0 for the first row ( row = 0). So you have to do something like this:
#include <iostream>
using namespace std;
int main()
{
int arr[12] = {
1, 2, 3, 4, 5, 6, 7, 8, 6, 4, 5, 3
};
**int dimCol = 4;**
cout << "Before change: " << endl;
for (int row = 0; row < 3; row++){
for (int col = 0; col < 4; col++){
cout << arr[**(row*dimCol) + col**] << " ";
}
cout << endl;
}
cout << "After the row change: " << endl;
for (int row = 2; row >= 0; row--){
for (int col = 0; col < 4; col++){
cout << arr[**(row*dimCol) + col**] << " ";
}
cout << endl;
}
cout << "After the column change: " << endl;
int temp;
for (int row = 0; row < 3; row++){
temp = arr[row * 1];
arr[row * 1] = arr[row * 3];
arr[row * 3] = temp;
for (int col = 0; col < 4; col++){
cout << arr[**(row*dimCol) + col**] << " ";
}
cout << endl;
}
}
The formule will be: array[row*numberOfColumn + Column]
You got a wrong argument definition:
Instead of
array[row*col]
write this
array[row*4 + col]
So the formula is:
array[row*total_col + col]
The loop you are using multiplies each time your variable with Zero that's why you are getting 1 at the beginning of every line as your first element is 1, and arr[0] is 1.
*and your line 1 is
1 1 1 1*
because value of outer loop is zero and any value of variable of inner loop multiplied will result in 0.
the reason you are not getting correct output is your logic to print all element is not correct.
go for
array[row*4 + col]

Generating N choose K Permutations in C++ [duplicate]

This question already has answers here:
Implementation of Permutation, Combinations and PowerSet in C++ [duplicate]
(2 answers)
Closed 8 years ago.
I have a function that receives n and k to create all the possible permutations of n choose k, and while it works for most combinations like 5 choose 3 or 3 choose 2, it doesn't for for others like 4 choose 2. I need some help finding and understanding the bug. Thanks for looking.
The function:
void PermGenerator(int n, int k)
{
int d[] = {1,2,3,4,5,6,7,8,9};
sort (d, d+n);
cout << "These are the Possible Permutations: " << endl;
do
{
for (int i = 0; i < k; i++)
{
cout << d[i] << " ";
if (i == k-1) cout << endl;
}
} while (next_permutation(d, d+n));
}
I'm using the next_permutation function. cplusplus
When I try 4 choose 2, I should be getting 12 permutations, instead I get this:
1 2
1 2
1 3
1 3
1 4
1 4
2 1
2 1
2 3
2 3
2 4
2 4
3 1
3 1
3 2
3 2
3 4
3 4
4 1
4 1
4 2
4 2
4 3
4 3
Whereas, 3 choose 2 works perfectly with 6 possible permutations:
1 2
1 3
2 1
2 3
3 1
3 2
The first k values are repeated n-k factorial times. Here is an easy, although inefficient, way to avoid the repetition:
int Factorial(int n)
{
int result = 1;
while (n>1) {
result *= n--;
}
return result;
}
void PermGenerator(int n, int k)
{
std::vector<int> d(n);
std::iota(d.begin(),d.end(),1);
cout << "These are the Possible Permutations: " << endl;
int repeat = Factorial(n-k);
do
{
for (int i = 0; i < k; i++)
{
cout << d[i] << " ";
}
cout << endl;
for (int i=1; i!=repeat; ++i)
{
next_permutation(d.begin(),d.end());
}
} while (next_permutation(d.begin(),d.end()));
}
However, there is an even easier and more efficient way to do it using std::reverse (from https://stackoverflow.com/a/2616837/951890)
void PermGenerator(int n, int k)
{
std::vector<int> d(n);
std::iota(d.begin(),d.end(),1);
cout << "These are the Possible Permutations: " << endl;
do
{
for (int i = 0; i < k; i++)
{
cout << d[i] << " ";
}
cout << endl;
std::reverse(d.begin()+k,d.end());
} while (next_permutation(d.begin(),d.end()));
}
The trick here is to realize that the last permutation is just the reverse of the first permutation, so by reversing the last n-k elements, you automatically skip to the last permutation of those elements.
You may use the following:
template <typename T>
void Combination(const std::vector<T>& v, std::size_t count)
{
assert(count <= v.size());
std::vector<bool> bitset(v.size() - count, 0);
bitset.resize(v.size(), 1);
do {
for (std::size_t i = 0; i != v.size(); ++i) {
if (bitset[i]) {
std::cout << v[i] << " ";
}
}
std::cout << std::endl;
} while (std::next_permutation(bitset.begin(), bitset.end()));
}
Live example
You output first k members of every n! permutations.
4! = 24 permutations. First two permutations are
1,2,3,4
1,2,4,3
and you have got 1,2 and 1,2
To get combinations (4,2), you might, for example, use vector
{0,0,1,1}
permute it, and output indexes of 1's