Iterating through sub-vectors - c++

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.

Related

Traverse 2D Matrix diagonally omitting first row and first column

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";
}

C++ Array (disregarding a repeat number)

I am a beginner programmer and I need some assistance.
I need to write a program that reads an array of 10 numbers from a user, then scans it and figures out the most common number/s in the array itself and prints them. If there is only one number that is common in the array, only print that number. But, if there's more than one number that appears more than once, print them also in the order they appear in in the array.
For example- 1 2 3 3 4 5 6 7 8 9 - output would be 3
For- 1 2 3 4 1 2 3 4 5 6 - output would be 1 2 3 4
for- 1 1 1 1 2 2 2 3 3 4 - output would be 1 2 3
Now, the problem I've been running into, is that whenever I have a number that repeats more than twice (see third example above), the output I'm getting is the number of iterations of the loop for that number and not only that number once.
Any assistance would be welcome.
Code's attached below-
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
int array [10], index, checker, common;
main ()
{
for (index=0; index<10; index++)
{
cin >> array [index];
}
for (index=0; index<10; index++)
{
int tempcount=0;
for (checker=(index+1);checker<10;checker++)
{
if (array[index]==array[checker])
tempcount++;
}
if (tempcount>=1)
cout << array[index]<<" ";
}
return 0;
}
Use appropriate data structures for the task.
Create a std::unordered_map that maps value to number_of_occurrences, and make a single pass over the input data.
Then create another map from number_of_occurrences to value. Sort it, in descending order. Report the first value, plus any additional ones that occurred as many times as the first did.
The reason you are having problems is that anytime a number appears two times or more it will print out. A solution is that you create another variable maxCount, then find the maximum times a number appears. Then loop through the array and print out all the numbers that appears the maximum amount of times.
Hope this helps.
Jake
Rather than writing you a solution, I will try to give you some hints that you can hopefully use to correct your code. Try to keep track of the following things:
Remember the position of the first occurrence of each distinct number in the array.
Count the number of times each number appears
and combine the two to get your solution.
EDIT:
int array[] = {1, 2, 3, 4, 1, 2, 3, 4, 5, 6};
int first [11], cnt[11];
for(int i = 0; i < 11; i++){
first[i] = -1;
cnt[i] = 0;
}
int max = 0;
for(int i = 0; i < 10; i++){
cnt[array[i]]++;
if(max < array[i]) max = array[i];
}
for(int i = 0; i <= max; i++){
if(cnt[i] > 1 && first[i] == -1) {
printf(" %d", i);
first[i] = i;
}
}
You could do something like this. At any index in the array look for previous occurences of that element. If you find that that it is the first occurence of that element, you only need to look if there is an occurence of that element ahead in the array.
Lastly display the element whose frequency(here num) would be greater than 1.
for (int i = 0; i < 10; i++)
{
int presentBefore = 0;
for (int j = 0; j < i; j++) //if any previous occurence of element
{
if (array[i] == array[j]) presentBefore++;
}
if (presentBefore == 0)//if first occurence of the element
{
int num = 1;
for (int j = i + 1; j < 8; j++)// if occurences ahead in the array
{
if (array[i] == array[j]) num++;
}
if(num>1)cout<<array[i]<<" ";
}
}
Here is another solution using STL and std::set.
#include <iostream>
#include <algorithm>
#include <set>
#include <iterator>
int main()
{
int array[12] = { 1, 2, 3, 1, 2, 4, 5, 6, 3, 4, 1, 2 };
std::set<int> dupes;
for (auto it = std::begin(array), end = std::end(array); it != end; ++it)
{
if (std::count(it, end, *it) > 1 && dupes.insert(*it).second)
std::cout << *it << " ";
}
return 0;
}
Prints:
1 2 3 4
I will try to explain how this works:
The original array is iterated from start to finish (BTW as you can see it can be any length, not just 10, as it uses iterators of beginning and end)
We are going to store duplicates which we find with std::count in std::set
We count from current iterator until the end of the array for efficiency
When count > 1, this means we have a duplicate so we store it in set for reference.
std::set has unique keys, so trying to store another number that already exists in set will result in insert .second returning false.
Hence, we print only unique insertions, which appear to be in the order of elements appearing in the array.
In your case you can use class std::vector which allows you to Erase elements, resize the array...
Here is an example I provide which produces what you wanted:
1: Push the values into a vector.
2: Use 2 loops and compare the elements array[i] and array[j] and if they are identical push the the element j into a new vector. Index j is always equal to i + 1 in order to avoid comparing the value with itself.
3- Now you get a vector of the repeated values in the temporary vector; You use 2 loops and search for the repeated values and erase them from the vector.
4- Print the output.
NB: I overloaded the insertion operator "<<" to print a vector to avoid each time using a loop to print a vector's elements.
The code could look like :
#include <iostream>
#include <vector>
std::ostream& operator << (std::ostream& out, std::vector<int> vecInt){
for(int i(0); i < vecInt.size(); i++)
out << vecInt[i] << ", ";
return out;
}
int main() {
std::vector< int > vecInt;
//1 1 1 1 2 2 2 3 3 4
vecInt.push_back(1);
vecInt.push_back(1);
vecInt.push_back(1);
vecInt.push_back(1);
vecInt.push_back(2);
vecInt.push_back(2);
vecInt.push_back(2);
vecInt.push_back(3);
vecInt.push_back(3);
vecInt.push_back(4);
std::vector<int> vecUniq;
for(int i(0); i < vecInt.size(); i++)
for(int j(i + 1); j < vecInt.size(); j++)
if(vecInt[i] == vecInt[j])
vecUniq.push_back(vecInt[j]);
std::cout << vecUniq << std::endl;
for(int i = 0; i < vecUniq.size(); i++)
for(int j = vecUniq.size() - 1 ; j >= 0 && j > i; j--)
if(vecUniq[i] == vecUniq[j])
vecUniq.erase(&vecUniq[j]);
std::cout << vecUniq << std::endl;
std::cout << std::endl;
return 0;
}
The input: 1 2 3 3 4 5 6 7 8 9
The output: 3
The input: 1 2 3 4 1 2 3 4 5 6
The output: 1 2 3 4
The input: 1 1 1 1 2 2 2 3 3 4
The output: 1 2 3
For this problem, you can use a marking array that will count the number of times you a digit is visited by you, it's just like counting sort. let's first see the program :
#include <iostream>
using namespace std;
int print(int a[],int b[])
{
cout<<"b :: ";
for (int index=0;index<10;index++)
{
cout<<b[index]<<" ";
}
cout<<endl;
}
int main ()
{
int a[10],b[11], index, checker, common;
for (index=0; index<10; index++)
{
cin >> a [index];
b[index] = 0;
}
b[10] =0;
for (index=0;index<10;index++)
{
b[a[index]]++;
if (b[a[index]] == 2)
cout<<a[index];
//print(a,b);
}
return 0;
}
As you can see that I have used array b as marking array which counts the time a number is visited.
The size of array b depends upon what is the largest number you are going to enter, I have set the size of array b to be of length 10 that b[11] as your largest number is 10. Index 0 is of no use but you need not worry about it as it will be not pointed until your input has 0.
Intially all elements in array in b is set 0.
Now assume your input to be :: 1 2 3 4 1 2 3 4 5 6
Now value of b can be checked after each iteration by uncommenting the print function line::
b :: 0 1 0 0 0 0 0 0 0 0 ....1
b :: 0 1 1 0 0 0 0 0 0 0 ....2
b :: 0 1 1 1 0 0 0 0 0 0 ....3
b :: 0 1 1 1 1 0 0 0 0 0 ....4
b :: 0 2 1 1 1 0 0 0 0 0 ....5
b :: 0 2 2 1 1 0 0 0 0 0 ....6
b :: 0 2 2 2 1 0 0 0 0 0 ....7
b :: 0 2 2 2 2 0 0 0 0 0 ....8
b :: 0 2 2 2 2 1 0 0 0 0 ....9
b :: 0 2 2 2 2 1 1 0 0 0 ....10
In line 5 you can b's at index 1 has value 2 so it will print 1 that is a[index].
And array a's element will be printed only when it is repeated first time due to this line if(b[a[index]] == 2) .
This program uses the idea of counting sort so if you want you can check counting sort.

Pattern Printing-Where am I going wrong in this C++ code?

I wrote a program to print a N x N square pattern with alternate 0's and 1's. For eg. A 5 x 5 square would looks like this:
I used the following code-
#include<iostream.h>
int main()
{
int i, n;
cin >> n; //number of rows (and columns) in the n x n matrix
for(i = 1; i <= n*n; i++)
{
cout << " " << i%2;
if(i%n == 0)
cout << "\n";
}
fflush(stdin);
getchar();
return 0;
}
This code works fine for odd numbers but for even numbers it prints the same thing in each new line and not alternate pattern.For 4 it prints this-
Where am I going wrong?
In my opinion the best way to iterate over matrix is using loop in another loop.
I think this code will be helpful for you:
for(i = 0; i < n; i++) {
for (j = 1; j <= n; j++) {
cout<<" "<< (j + i) % 2;
}
cout<<"\n";
}
where n is number of rows, i and j are ints.
Try to understand why and how it works.
If you're a beginner programmer, then I suggest (no offence) not trying to be too clever with your methodology; the main reason why your code is not working is (apart from various syntax errors) a logic error - as pointed out by blauerschluessel.
Just use two loops, one for rows and one for columns:
for (int row = 1; row <= n; row++)
{
for (int col = 0; col < n; col++)
cout << " " << ((row % 2) ^ (col % 2));
cout << "\n";
}
EDIT: since you wanted a one-loop solution, a good way to do so would be to set a flip flag which handles the difference between even and odd n:
bool flip = false;
int nsq = n * n;
for (int i = 1; i <= nsq; i++)
{
cout << " " << (flip ^ (i % 2));
if (i % n == 0) {
if (n % 2 == 0) flip = !flip;
cout << "\n";
}
}
The reason that it isn't working and creating is because of your logic. To fix this you need to change what the code does. The easiest way to handle that is to think of what it does and compare that to what you want it to do. This sounds like it is for an assignment so we could give you the answer but then you would get nothing from our help so I've writen this answer to guide you to the logic of solving it yourself.
Lets start with what it does.
Currently it is going to print 0 or 1 n*n times. You have a counter named i that will increment every time starting from 0 and going to (n*n)-1. If you were to print this number i you would get the following table for n=5
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
Now you currently check if the value i is odd or even i%2 and this makes the value 0 or 1. Giving you the following table
1 0 1 0 1
0 1 0 1 0
1 0 1 0 1
0 1 0 1 0
1 0 1 0 1
Now in the case of n=4 your counter i would print out to give you a table
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
Now if you print out the odd or even pattern you get
1 0 1 0
1 0 1 0
1 0 1 0
1 0 1 0
This pattern diffrence is because of the changing pattern of printed numbers due to the shape of the square or more accurately matrix you are printing. To fix this you need to adjust the logic of how you determine which number to print because it will only work for matrixes that have odd widths.
You just need to add one more parameter to print the value. Below mentioned code has the updated for loop which you are using:
int num = 0;
for(i = 1; i <= n*n; i++)
{
num = !num;
std::cout << " " << num;
if(i%n == 0) {
std::cout << "\n";
num = n%2 ? num : !num;
}
}
The complete compiled code :
#include <iostream>
#include <stdio.h>
int main()
{
int i, n, num = 0;
std::cin >> n; //number of rows (and columns) in the n x n matrix
for(i = 1; i <= n*n; i++)
{
num = !num;
std::cout << " " << num;
if(i%n == 0) {
std::cout << "\n";
num = n%2 ? num : !num;
}
}
fflush(stdin);
getchar();
return 0;
}

Second part to: write two functions that reverse the order of the elements in a vect<int>

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.

How do I work with nested vectors in C++?

I'm trying to work with vectors of vectors of ints for a sudoku puzzle solver I'm writing.
Question 1:
If I'm going to access a my 2d vector by index, do I have to initialize it with the appropriate size first?
For example:
typedef vector<vector<int> > array2d_t;
void readAPuzzle(array2d_t grid)
{
for(int i = 0; i < 9; i++)
for(int j = 0; j < 9; j++)
cin >> grid[i][j];
return;
}
int main()
{
array2d_t grid;
readAPuzzle(grid);
}
Will seg fault. I assume this is because it is trying to access elments of grid that have not yet been initialized?
I've swapped out grid's declaration line with:
array2d_t grid(9, vector<int>(9, 0));
And this seems to get rid of this seg fault. Is this the right way to handle it?
Question 2:
Why is it that when I try to read into my grid from cin, and then print out the grid, the grid is blank?
I'm using the following code to do so:
void printGrid(array2d_t grid)
{
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
cout << grid[i][j] + " ";
}
cout << endl;
}
}
void readAPuzzle(array2d_t grid)
{
for(int i = 0; i < 9; i++)
for(int j = 0; j < 9; j++)
cin >> grid[i][j];
return;
}
int main()
{
array2d_t grid(9, vector<int>(9, 0));
printGrid(grid);
readAPuzzle(grid);
printGrid(grid);
}
And I attempt to run my program like:
./a.out < sudoku-test
Where sudoku-test is a file containing the following:
3 0 0 0 0 0 0 0 0
5 8 4 0 0 2 0 3 0
0 6 0 8 3 0 0 7 5
0 4 1 0 0 6 0 0 0
7 9 0 0 2 0 0 5 1
0 0 0 9 0 0 6 8 0
9 3 0 0 1 5 0 4 0
0 2 0 4 0 0 5 1 8
0 0 0 0 0 0 0 0 6
The first call to printGrid() gives a blank grid, when instead I should be seeing a 9x9 grid of 0's since that is how I initialized it. The second call should contain the grid above. However, both times it is blank.
Can anyone shed some light on this?
Q1: Yes, that is the correct way to handle it. However, notice that nested vectors are a rather inefficient way to implement a 2D array. One vector and calculating indices by x + y * width is usually a better option.
Q2A: Calculating grid[i][j] + " " does not concatenate two strings (because the left hand side is int, not a string) but instead adds the numeric value to a pointer (the memory address of the first character of the string " "). Use cout << grid[i][j] << " " instead.
Q2B: You are passing the array by value (it gets copied) for readAPuzzle. The the function reads into its local copy, which gets destroyed when the function returns. Pass by reference instead (this avoids making a copy and uses the original instead):
void readAPuzzle(array2d_t& grid)