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";
}
Related
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.
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.
I have a table which consists of nonnegative integers that are layed out in this manner: Each element in the table is the minimum value that does not appear to its left or above it. Here's an example of a 6x6 grid:
0 1 2 3 4 5
1 0 3 2 5 4
2 3 0 1 6 7
3 2 1 0 7 6
4 5 6 7 0 1
5 4 7 6 1 0
The first row and column begin with 0 1 2 3 4 5... In coordinates (x,x) is always a 0, as you can see. On each tile after that, you have to place the smallest positive number that doesn't already exist on the same row or column. Much like in a sudoku-puzzle: There cannot be a number twice on the same row and column.
Now I have to print the number in the given coordinates (y,x). For example [2, 5] = 5
I came up with a working solution, but it takes way too much memory and time, and I just know there's another way of doing this. My time limit is 1 second, and the coordinates I have to find the number at can go up to (1000000, 1000000).
Here's my code at the moment:
#include <iostream>
#include <vector>
int main()
{
int y, x, grid_size;
std::vector< std::vector<int> > grid;
std::cin >> y >> x; // input the coordinates we're looking for
grid.resize(y, std::vector<int>(x, 0)); // resize the vector and initialize every tile to 0
for(int i = 0; i < y; i++)
for(int j = 0; j < x; j++)
{
int num = 1;
if(i != j) { // to keep the zero-diagonal
for(int h = 0; h < y; h++)
for(int k = 0; k < x; k++) { // scan the current row and column
if(grid[h][j] == num || grid[i][k] == num) { // if we encounter the current num
num++; // on the same row or column, increment num
h = -1; // scan the same row and column again
break;
}
}
grid[i][j] = num; // assign the smallest number possible to the current tile
}
}
/*for(int i = 0; i < y; i++) { // print the grid
for(int j = 0; j < x; j++) // for debugging
std::cout << grid[i][j] << " "; // reasons
std::cout << std::endl;
}*/
std::cout << grid[y-1][x-1] << std::endl; // print the tile number at the requested coordinates
//system("pause");
return 0;
}
So what should I do? Is this easier than I think it is?
To summarize your question: You have a table where each element is the minimum nonnegative integer that does not appear to its left or above. You need to find the element at position (x,y).
The result is surprisingly simple: If x and y are 0-based, then the element at (x,y) is x XOR y. This matches the table you have posted. I have verified it experimentally for a 200x200 table.
The proof:
It's easy to see that the same number won't appear twice on the same row or column, because if x1^y = x2^y then necessarily x1=x2.
To see that x^y is minimal: Let a be a number smaller than x^y. Let i be the index (from the right) of the leftmost bit where a differs from x^y. The ith bit of a must be 0 and the ith bit of x^y must be 1.
Therefore, either x or y must have 0 in the ith bit. Suppose WLOG it was x that had 0. Represent x and y as:
x = A0B
y = C1D
Where A,B,C,D are sequences of bits, and B and D are i bits long. Since the leftmost bits of a are the same as those in x^y:
a^x = C0E
Where E is a sequence of i bits. So we can see that a^x < y. The value that appered in the (a^x)th row on the same column was: (a^x)^x = a. So the value a must have already appeared in the same row (or column, if it was y that had 0 in the ith bit). This is true for any value smaller than x^y, so x^y is indeed the minimum possible value.