I have implemented the first part of this problem but failed to achieve the second part. What I'm trying to do is that I have two vectors
std::vector<double> A = {1,1,2,2};
std::vector<double> B = {3,3,4,4,5,5};
I have to go through two loops and make subtraction of two math vectors. For example,
For the first iteration:
C = [1;1] (Note: the first two elements of A vector)
Because C is 2x1, I have to construct from B three math vectors of the same size, therefore the output for the first iteration is
1 - 3
1 - 3
------
1 - 4
1 - 4
------
1 - 5
1 - 5
For the second iteration, the C matrix is expanded by two elements per iteration , therefore the new C matrix is C = [1;1;2;2]. Now we need to make the subtraction again, the output for the second iteration is
1 - 3
1 - 3
2 - 4
2 - 4
------
1 - 4
1 - 4
2 - 5
2 - 5
------
1 - 5
1 - 5
2 - 3
2 - 3
As you can see, the second math vector is shifted by two elements where the first math vector remains as it is.
A and B matrices have this assumption size % 2 = 0 where 2 is the size of C matrix.
Replicating your ouput, for first iteration you would have:
std::vector<double> A = {1,1,2,2};
std::vector<double> B = {3,3,4,4,5,5};
std::vector<double> C (A.begin(), A.begin()+2);
// bg - index of group of 2 elements in B
for (int bg = 0; bg < 3; ++bg) {
for (int ci = 0; ci < int(C.size()); ++ci) {
// bi - index of element in B
int bi = (2*bg + ci) % int(B.size());
std::cout << C[ci] << " - " << B[bi] << std::endl;
}
std::cout << "------" << std::endl;
}
For second iteration you would have to change one line:
// line changed...
std::vector<double> C (a.begin(), a.begin()+4);
Edit: OK, here's more general form that outputs both cases you specified for the change of iteration counter it. Hope it works when you extend the vectors.
for (int it = 1; it <= int(A.size())/2; ++it) {
std::vector<double> C (A.begin(), A.begin()+it*2);
// bg - index of group of 2 elements in B
for (int bg = 0; bg < int(B.size())/2; ++bg) {
for (int ci = 0; ci < int(C.size()); ++ci) {
// bi - index of element in B
int bi = (2*bg + ci) % int(B.size());
std::cout << C[ci] << " - " << B[bi] << std::endl;
}
std::cout << "------" << std::endl;
}
std::cout << std::endl;
}
Related
I am trying to traverse a 2D matrix diagonally and the function below prints all elements in a diagonal.I want to skip the first row and first column elements and start the diagonal traversal from matrix[1][1] because the values in the 0th row and 0th column are not required.So it is like slicing the matrix from the top and starting from [1][1] but not making any changes to the bottom of the matrix.
void diagonalOrder(int matrix[][COL])
{
for(int line = 1;
line <= (ROW + COL - 1);
line++)
{
int start_col = max(0, line - ROW);
int count = min(line, (COL - start_col), ROW);
/* Print elements of this line */
for(int j = 0; j < count; j++)
cout << setw(5) <<
matrix[minu(ROW, line) - j - 1][start_col + j];
cout << "\n";
}
I will update my question with an example to make it clear.Consider the following matrix.
0 1 2 3 4
matrix[5][5] = 1 8 5 3 1
2 4 5 7 1
3 6 4 3 2
4 3 4 5 6
The above function will print the values of this diagonally.
Output:
0
1 1
2 8 2
3 4 5 3
4 6 5 3 4
3 4 7 1
4 3 1
5 2
6
I want to skip the elements of the first row and the first column and starting at matrix[1][1] want to traverse the matrix diagonally.
Desired Output:
8
4 5
6 5 3
3 4 7 1
4 3 1
5 2
6
From your example it looks like you want to print antidiagonals not diagonals, ie third line is 3 4 5 3 not 3 5 4 3.
To get started keep things simple: Indices (i,j) along an antidiagonal are those i and j where i+j == some_constant. Hence this is a simple (not efficient) way to print elements along one antidiagonal:
void print_antidiagonal(int matrix[5][5],int x){
for (int i=4;i >= 0; --i) {
for (int j=0;j < 5; ++j) {
if (i+j == x) std::cout << matrix[i][j] << " ";
}
}
std::cout << "\n";
}
Further there are nrows + (ncols-1) antidiagonals, hence you can print them all via:
for (int i=0;i < 5+4; ++i) {
print_antidiagonal(matrix,i);
}
The function above isnt very efficient, but it is simple. It is obvious how to skip the first row and first column:
for (int i=4;i >= 1; --i) { // loop till 1 instead of 0
for (int j=1;j < 5; ++j) { // loop from 1 instead of 0
This is sufficient to produce desired output (https://godbolt.org/z/7KWjb7qh7). However, not only is the above rather inefficient, but also the code is not very clear about its intent. print_antidiagonal prints elements along a single anti-diagonal, hence iterating all matrix elements is a bad surprise.
I suggest to print the indices rather than the matrix elements to get a better picture of the pattern (https://godbolt.org/z/TnrbbY4jM):
1,1
2,1 1,2
3,1 2,2 1,3
4,1 3,2 2,3 1,4
4,2 3,3 2,4
4,3 3,4
4,4
Again, in each line i+j is a constant. And that constant increments by 1 in each line. In each line i decrements while j increments, until either i == 1 or j==4. The first element is such that i is maximum and j = constant - i.
Hence:
void print_antidiagonal(int matrix[5][5],int x){
int i = std::min(x-1,4);
int j = x - i;
while (i >= 1 && j <= 4) {
std::cout << matrix[i][j] << " ";
--i;
++j;
}
std::cout << "\n";
}
Live Example.
PS: I used hardcoded indices, because I considered it simpler to follow the logic. For a more realistic solution the matrix size and offset should be parametrized of course.
I don't really get what your code is trying to do but just going by the description you need to iterate over the array items with equal row and column indices until there either are no more rows or no more columns i.e.
void print_tail_of_diagonal(int matrix[ROWS][COLS])
{
int n = std::min(ROWS, COLS);
for (int i = 1; i < n; ++i) {
std::cout << matrix[i][i] << " ";
}
std::cout << "\n";
}
#include <iostream>
using namespace std;
int main ()
{
cout << "starting program" << endl;
for (int a=1; a<10; a++)
{
for (int b=1; b<10; b++)
{
for (int c=1; c<10; c++)
{
for (int d=1; d<10; d++)
{
for (int e=1; e<10; e++)
{
for (int f=1; f<10; f++)
{
for (int g=1; g<10; g++)
{
for (int h=1; h<10; h++)
{
for (int i=1; i<10; i++)
if (a+(13 * b / c) +d +(12 * e )- f - 11 + (g * h / i) - 10 == 66)
{
cout << a << b << c << d << e << f << g << h << i << endl ;
}
}
}
}
}
}
}
}
}
return 0;
}
So I have this code that finds every possible combinations between 1 and 9 to see which one will solve the equation, and as you can see I have 9 variables.
This equation can be solved in many many different combinations, however what I am aiming for is to have the variables not equal to one another. Of course I could approach this by writing each one of the conditions in the if statement conditions but that would be 81 conditions to put and that's a lot and stupid. Is there any way to approach this in a smarter way?
By the way, I am a beginner so if you have any advanced methods to offer, please explain it briefly.
As mentioned by #n.m. in the comments, since all your variables must be different, you are looking for permutations1 of the range 1 to 9. Which is great since c++ already provides you with std::next_permutation that will generate permutations for you:
// Array for your variables, vars[0] is a, vars[1] is b, and so on...
std::array<int, 9> vars;
// Fill the array from number from 1 to 9 (so a = 1, b = 2, and so on... )
std::iota(std::begin(vars), std::end(vars), 1);
// Loop through all permutations of this array (see std::next_permutation):
// 1 2 3 4 5 6 7 8 9
// 1 2 3 4 5 6 7 9 8
// 1 2 3 4 5 6 8 7 9
// ...
// 9 8 7 6 5 4 3 2 1
do {
// Check if the variables matches what you want (see below for check):
if (check(vars)) {
std::cout << "Solution found: ";
for (auto v: vars)
std::cout << v << ' ';
std::cout << '\n';
}
} while(std::next_permutation(std::begin(vars), std::end(vars)));
Where check is, e.g.2:
int check(std::array<int, 9> const& vars) {
// Remember that vars[0] is a, vars[1] is b, ..., I rewrote your comparison as:
// c * i * (a + d + 12 * e - f - 11 -10) + 13 * b * i + c * g * h == 66 * c * i
// ...in order to avoid division.
return vars[2] * vars[8] * (vars[0] + vars[3] + 12 * vars[4] - vars[5] - 11 - 10)
+ (13 * vars[1] * vars[8])
+ (vars[2] * vars[6] * vars[7]) == 66 * vars[2] * vars[8];
}
1 There are other ways to find your solution: You could reduce the domain of the next variable you are going to assign using the values of the already affected variables (e.g., there is no need to loop the last variable since there is only zero or one value possible at the end), but this is more complicated and probably overkill for what you want to do. If you want to learn more about this, you could look for constraint programming
2 I re-organize the computation since you were doing integer division which truncates the result so you could get incorrect solution.
Some details about the code you may not be familiar with as a beginner:
std::array<int, 9> (c++11) is a static array that replaces int vars[9], you should prefer using this over c-style array whenever you can.
std::iota is a function from the <algorithm> header that will fill the range std::begin(vars) to std::end(vars) with increasing values starting at 1 (the value provided as the last argument).
for (auto x: vars) is a range-based for loop (available since c++11) which allows you to iterate over any container in a simple manner.
First of all, I do know that someone asked the following question. However, they did not ask the second part. I need help in the second part.
Write two functions that reverse the order of elements in a vector. For example, 1,3,5,7,9 becomes 9,7,5,3,1. The second reverse function should reverse the elements of its vector w/o using any other vectors. (hint: swap).
But when I test my code. It doesn't reverse the order with the following loop:
for (int i = 0; i < testing.size(); i++)
swap(testing[i], testing[testing.size() - 1 - i]);
But when I divide testing.size() by 2. It works perfectly. So my question is: why does it work when it's divided by two. I've looked for a good amount of time and even tried sketching it out.
for (int i = 0; i < testing.size()/2; i++)
swap(testing[i], testing[testing.size() - 1 - i]);
Thanks in advance!
Here's the entire coding:
void replacing(vector<int>& testing)
{
for (int i = 0; i < testing.size(); i++)
cout << "original " << testing[i] << "\n";
for (int i = 0; i < testing.size(); i++)
swap(testing[i], testing[testing.size() - 1 - i]);
for (int i = 0; i < testing.size(); i++)
cout << "reversed " << testing[i] << "\n";
}
int main()
{
vector<int> original;
int numbers;
cout << "Enter random numbers: \n";
while (cin >> numbers)
original.push_back(numbers);
replacing(original);
}
To reverse a vector you need to swap its two halves. If you swap its halves two times you will get again the original vector.
So this loop
for (int i = 0; i < testing.size(); i++)
{
swap(testing[i], testing[testing.size() - 1 - i]);
}
swaps two halves when i < testing.size() / 2 and then when i >= testing.size() / 2 again swaps these halves restoring the original order of the vector.
So a correct loop will look like
for ( std::vector<int>::size_type i = 0; i < testing.size() / 2; i++ )
{
swap( testing[i], testing[testing.size() - 1 - i] );
}
In this case you swap each element with index less than testing.size() / 2 (low half) with each element with index gretaer than or equal to testing.size() / 2(upper half)
You could write the function with one statement
testing.assign( testing.rbegin(), testing.rend() );
Also there is a standard algorithm declared in header <algorithm> that does the same
#include <algorithm>
//...
std::reverse( testing.begin(), testing.end() );
Just for the purposes of illustration, here’s what’s happening in a sample run of your program. i is moving rightward and size() - 1 - i (call it j) is moving leftward:
1 2 3 4 5 6
i j
6 2 3 4 5 1
i j
6 5 3 4 2 1
i j
6 5 4 3 2 1
j i
Your loop should stop here, because i has exceeded size() / 2. Now watch:
6 5 3 4 2 1
j i
6 2 3 4 5 1
j i
1 2 3 4 5 6
j i
It actually stops here, when i reaches size(), whereupon all the elements that you swapped have been swapped back to their original locations!
This is because if you have (i < testing.size()) you will first switch all of the numbers, but you will just switch all of them back to where they were first afterwards. So if you have a vector with values {0,1,2,3}, you would switch 0 with 3, 1 with 2, then it would continue and switch 1 back with 2 and 3 back with 0 to make {0,1,2,3} again. When you divide it by 2, it stops before it can start switching the numbers back to what they were first and you get the vector you want.
I am trying to iterate through a vector of vectors neighbors and simply display its contents.
The context: Graph theory.
neighbors[i] is a vector containing all adjacent vertices to vertex i. For this example, the graph is the complete graph $K_5$ of 5 vertices all connected to each other.
Problem: I need an iterator to iterate through the sub-vectors, since I (shouldn't) know their length, but I get the wrong answer.
My attempt
for(int i = 0; i < num_vertices_h; ++i) {
for(vector<int>::iterator it = neighbors[i].begin(); it != neighbors[i].end(); ++it) {
cout << neighbors[i][*it] << " ";
}
cout << endl;
}
The (wrong) output
2 3 4 -1454373456
0 3 4 -1454373584
0 1 4 0
0 1 2 -1454373744
0 1 2 3
If I just cheat, using the fact that I know each sub-vector has 4 entries, I can avoid the iterator:
Cheat Solution
for(int i = 0; i < num_vertices_h; ++i) {
for(int j = 0; j < num_vertices_h -1; ++j) {
cout << neighbors[i][j] << " ";
}
cout << endl;
}
Correct output
1 2 3 4
0 2 3 4
0 1 3 4
0 1 2 4
0 1 2 3
If neighbors[i] is a vector itself, in your first loop attempt, *it it is actually the vector element, so you can just cout << *it and you'll have the correct result.
I've been revising on my coding skills recently and then I made a program that outputs the contents of a multidimensional array. It is simple but when I experimented with the code this is what that happened:
int dv[3][3] {
{1,2,3},
{4,5,6},
{7,8,9}
};
for (auto col = dv; col != dv + 3; ++col) {
for (auto row = *dv; row != *col + 3; ++row) {
cout << *row << " ";
}
}
Output:
1 2 3 1 2 3 4 5 6 1 2 3 4 5 6 7 8 9
Can anybody please tell me why is this happening?
Why does my code outputs so ?
Your error is inside the second loop initialization : auto row = *dv;. By doing so, you systematically come back to the beginning. Then, you go to *col + 3.
Look at it this way :
First loop turn :
col = dv;
row = *dv;
Prints each number until row == *col + 3
Output : 1 2 3
Second loop turn :
col = dv + 3;
row = *dv;
Prints each number until row == *col + 3 but col is dv + 3
Output : 1 2 3 4 5 6 --> It started from the beginning (dv)
Total output with turn 1 and 2 : 1 2 3 1 2 3 4 5 6
Try this instead :
for (auto col = dv; col != dv + 3; ++col) {
for (auto row = *col; row != *col + 3; ++row) { // (1)
cout << *row << " ";
}
}
// (1) : Starting at current `column` then printing until `column + 3`
Live example : https://ideone.com/Y0MKrW
Your inner loop is starting at *dv. That is probably not what you meant to do.