vectors in range based for loop - c++

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.

Related

Why is the difference between behaviors in for loop?

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

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*.

Looping through a vector of lists

So I was learning about the stlibrary and graphs, and so I found out that graphs could be represented as a vector of lists which could be like this, where the 1 2 3 4 5 6 are the vertices, and from the vertice 1 I could go to the number 2, from the 3 to the 6, etc.
1 2 3 4 5 6
2 6 1 2
2
But, I already saved these values in the vector list, how could I loop through it to get the graph? My vector list is called _verticesEdges.
Like, to get an output like this:
Vertice 1: 2
Vertice 2:
Vertice 3: 6
Vertice 4: 1 2
Vertice 5:
Vertice 6: 2
Appreciate your help!
Assuming you have stored from index 1 to n (that means size of 0th index of your vector is zero), where n is number of vertices,
for (int i = 1; i <= n; i++)
{
cout << "Vertex " << i << ": ";
for (int j=0; j< _verticesEdges[i].size(); j++)
cout << _verticesEdges[i][j] << " ";
cout << "\n";
}
Something like this
std::vector<std::list<int>> vecOfLists;
// fill vecOfLists;
for (size_t i = 0; i < vecOfLists.size(); ++i) {
std::cout << "Vertice " << i + 1 << ": ";
for (int num : vecOfLists[i]) {
std::cout << num << " ";
}
std::cout << std::endl;
}
I am using usual for for iterating through lists, since index is required, and using range-based for for iterating through list, since this is better and modern way to iterate through whole container if you don't require indexes.

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

vector::erase does not erase the desired element, but instead erases the last element from the vector

I've been working on learning c++, but now I'm stuck with a problem that really confuses me. The problem is that when i try to erase an element from a vector, the erase function does not erase the element that i wanted to be erased, but instead erases the last element from the vector. I recreated the problem with this piece of code, so that it's easier to understand my problem than it would be with my whole code:
#include <vector>
#include <iostream>
int main()
{
std::vector<int> c;
for(int i=0; i<=10; i++){
c.push_back(i);
}
for (int i=0;i<c.size();i++) {
std::cout << i << " ";
}
std::cout << '\n';
c.erase(c.begin()+2);
for (int i=0;i<c.size();i++) {
std::cout << i << " ";
}
std::cout << '\n';
c.erase(c.begin()+2, c.begin()+5);
for (int i=0;i<c.size();i++) {
std::cout << i << " ";
}
std::cout << '\n';
}
the result is not what is expected:
0 1 2 3 4 5 6 7 8 9 10
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6
when I thought the result would be
0 1 2 3 4 5 6 7 8 9 10
0 1 3 4 5 6 7 8 9 10
0 1 2 7 8 9 10
Am I doing something completely wrong, or why is this not working as I thought it would?
If it is relevant, I'm using the MinGW compiler for windows.
After deletion, you do not print the content of the vector but only the loop variable.
Simply replace your cout sections by
for (int i=0;i<c.size();i++) {
std::cout << c[i] << " ";
}
and it will work as desired.
You print the loop variable, instead of the contents of the vector. For all instances:
Change
for (int i=0;i<c.size();i++) {
std::cout << i << " ";
}
to
for (int i=0;i<c.size();i++) {
std::cout << c.at(i) << " ";
}
for (int i=0;i<c.size();i++) {
std::cout << i << " ";
}
should be:
for (int i=0;i<c.size();i++) {
std::cout << c[i] << " ";
}
EDIT: I was late.