Multi-Dimensional Array sorting in c++ - c++

I am using sort() function for single array it works well.
I also used this for multi-dimensional array but this is not work.
Here is code:
#include <iostream>
using namespace std;
int main(){
int a[2][3];
a[0][1]=7;
a[1][0]=1;
a[1][1]=3;
sort(a,a+3);
cout<<a[0][1]<<"\t"<<a[1][0]<<"\t"<<a[1][1];
return 0;
}
I know I use single array for these value but this is example and I want it in multi-dimensional array.

Using your code just use std::sort on each row of the multidimensional array. ie.
#include <iostream>
using namespace std;
int main(){
int a[2][3];
a[0][0]=1;
a[0][1]=7;
a[0][2]=3;
a[1][0]=6;
a[1][1]=2;
a[1][2]=5;
for(int i = 0; i < 2; i++) {
sort(a[i],a[i]+3);
}
for(int row = 0; row < 2; row++) {
for(int col = 0; col < 2; col++) {
cout << a[row][col] << " ";
}
}
return 0;
}
I initiated every element of your multidimensional array a, since your declared a to be size 6 (2 rows, 3 columns). This would output 1 3 7 2 5 6, because it sorts the rows from least to greatest. If you wanted to sort the multidimensional array so that the output would read 1 2 3 5 6 7 then you would need to do something like this:
#include <iostream>
using namespace std;
int main(){
int a[2][3];
int b[6];
int count = 0;
a[0][0]=1;
a[0][1]=7;
a[0][2]=3;
a[1][0]=6;
a[1][1]=2;
a[1][2]=5;
for(int row = 0; row < 2; row++) {
for(int col = 0; col < 3; col++) {
b[count] = a[row][col];
count++;
}
}
sort(b, b+6);
count = 0;
for(int row = 0; row < 2; row++) {
for(int col = 0; col < 3; col++) {
a[row][col] = b[count];
count++;
}
}
for(int row = 0; row < 2; row++) {
for(int col = 0; col < 3; col++) {
cout << a[row][col] << " ";
}
}
return 0;
}
This second example is probably the worst possible way to go about sorting a multidimensional array though. Let me know if you find an error in my code, I was unable to test, or need additional help.

As the multidimensional arrays are contiguous you can also try:
int main()
{
int a[2][3];
a[0][0]=1;
a[0][1]=7;
a[0][2]=3;
a[1][0]=6;
a[1][1]=2;
a[1][2]=5;
std::sort(&a[0][0], &a[1][3]);
for(int row = 0; row < 2; row++) {
for(int col = 0; col < 3; col++) {
std::cout << a[row][col] << " ";
}
}
}
Depending on what you want. It is also possible to write a begin() and end() for multidimensional arrays.

Related

Ordering 2d array in lexical order

I have an 2d array of char, and I am trying to order them in alphabetical order. In each rows there is a word build of chars and I am trying to sort it.
I built something, but I don't understand why this is not working. If you have a solution for me, please explain what you are doing, in order to understand why I don't success.
Thanks !
char matrix[4][5] = {
{'h','e','l','l','o'},
{'r','e','a','d','y'},
{'a','p','p','l','e'},
{'p','o','i','n','t'},
};
char temp;
bool flag = false;
display(matrix);
for (int i = 0; i < 4 - 1; i++)
{
for (int rows = 0; rows < 10-1; rows++)
{
flag = false;
for (int cols = 0; cols < 5; cols++)
{
if (matrix[rows][cols] > matrix[rows + 1][cols])
{
flag = true;
break;
}
}
if (flag)
{
for (int index = 0; index < 5; index++)
{
temp=matrix[rows][index];
matrix[rows][index]=matrix[rows+1][index];
matrix[rows+1][index]=temp;
}
}
}
}
I will post this answer, even if it may not be what you want to do (but will be helpful for others who may want to do things this way).
Instead of sorting the 2D array, the trick is to not sort it, and instead sort an array of indices that point into the array. That is much more simpler than trying to manipulate the array itself.
Here is a very simple example:
#include <algorithm>
#include <cstring>
#include <iostream>
int main()
{
char matrix[4][5] = {
{'h','e','l','l','o'},
{'r','e','a','d','y'},
{'a','p','p','l','e'},
{'p','o','i','n','t'},
};
// create the indices
int index[] = { 0,1,2,3 };
// sort the indices based on the data in the array
std::sort(index, index + 4, [&](int n1, int n2)
{ return strncmp(matrix[n1], matrix[n2], 5) < 0; });
// Output the results
for (int i = 0; i < 4; ++i)
{
// Note how we access the original matrix using the index array
std::cout.write(matrix[index[i]], 5);
std::cout << " -- Using array at row " << index[i] << "\n";
}
}
Output:
apple -- Using array at row 2
hello -- Using array at row 0
point -- Using array at row 3
ready -- Using array at row 1
The final results show that the indices just point to the row that would be used if we want to access the array in a sorted manner. The original array was not adjusted.
That's it.
#include <bits/stdc++.h>
using namespace std;
char matrix[4][5] = {
{'h','e','l','l','o'},
{'r','e','a','d','y'},
{'a','p','p','l','e'},
{'p','o','i','n','t'} };
int n = 4, m = 5, k = 0;// number of rows and columns
char temp;
int main()
{
for ( int i = 0; i < n; i++ )
for ( int j = i + 1; j < n; j++ )
{
k = 0;
while ( matrix[i][k] == matrix[j][k] && k < m )
k++;
if ( k < m && matrix[i][k] > matrix[j][k] ) // ASCII code comparison
for ( int k = 0; k < m; k++ )
{
temp = matrix[i][k];
matrix[i][k] = matrix[j][k];
matrix[j][k] = temp;
}
}
for ( int i = 0; i < n; i++ )
{
for ( int j = 0; j < m; j++ )
cout << matrix[i][j];
cout << "\n";
}
}

Create 2D array of integers that will fill in the matrix with random numbers using two functions. What have I done wrong?

Here is the code. I need to have fixed rows and cols that get filled in with random numbers when the matrix function is called. There needs to be 2 functions, one for displaying and 1 for randomizing.
#include "stdafx.h"
#include <iostream>
#include <cstdlib>
#include <time.h>
using namespace std;
const int ROWS = 10;
const int COLS = 8;
int matrix[ROWS][COLS];
void RandMatrix(int **arr, int row) {
for (int i = 0; i < row; i++)
for (int j = 0; j < COLS; j++)
*((*arr + i) + j) = rand() % 10;
}
void DisplayMatrix(int **arr, int row) {
for (int i = 0; i < ROWS; ++i) {
for (int j = 0; j < COLS; ++j)
cout << matrix[i][j];
cout << endl;
}
}
int main()
{
srand(time(NULL));
int matrix[ROWS][COLS];
for (int i = 0; i < ROWS; ++i) {
for (int j = 0; j < COLS; ++j) {
matrix[i][j] = -1;
}
}
int *ptr[ROWS];
int **arr = &ptr[0];
int row = 10;
for (int i = 0; i < ROWS; i++) {
ptr[i] = &matrix[i][0];
}
RandMatrix(arr, row);
DisplayMatrix(arr, row);
}
Main problem
The pointer arithmetic is wrong in the line
*((*arr + i) + j) = rand() % 10;
It needs to be
*(*(arr + i) + j) = rand() % 10;
It will be easier to just use:
arr[i][j] = rand() % 10;
Minor problems
You are passing arr as argument to DisplayMatrix but you are not using it. Instead, you are using matrix. It works ok by lucky coincidence. It will be better to not use arr in the function.
You are passing row as argument to DisplayMatrix but you are using ROWS in the for loop. Once again, it works because of lucky coincidence.
You pass arr to DisplayMatrix - but you don't actually use it there. Instead, the function prints the values in the global variable named matrix. But those values were never initalized - RandMatrix populates a different variable named matrix, the one local to main.
You are calling the DisplayMatrix function with arr as an argument but you are not using arr in it at all. Instead, you are using matrix.
In the DisplayMatrix function, change the following line:
cout << matrix[i][j];
to
cout << *((*arr + i) + j);
And it will work as intended.

Can someone explain me, why my code is not working?

I am completely new in C++ and I have to solve a task for college, where I have to make a struct Matrix and fill it with random integers. I marked the line with a "!" where the error appears.
It is the error C2131(Visual C++ Compiler). It says "expression did not evaluate to a constant".
struct Matrix{
int rows;
int columns;
Matrix(int r, int c){
rows = r, columns = c;
}
int produceMatrix(){
int matrix[rows][columns]; "!"
for(int i = 0; i != rows; i++){
for(int j = 0; j != columns; j++){
matrix[i][j] = rand() %10 +1;
}
}
return 0;
}
int showMatrix(){
for(int i = 0; i != rows; i++){
for(int j = 0; j != columns; j++){
cout << matrix[i][j]<< endl;
}
}
}
};
int main()
{
srand(time(0));
Matrix a(3, 4);
}
If you are planning to create your matrix with rows and columns values only known at runtime, you are better off using std::vector<std::vector<int>> to hold your data, as the static array you use needs to know its size at compile time. But if all your sizes are known at compile time and you just want flexibility of creating different matrix sizes, you can use template, for example:
#include <iostream>
#include <ctime>
template <int ROWS, int COLUMNS>
struct Matrix
{
int rows = ROWS;
int columns = COLUMNS;
int matrix[ROWS][COLUMNS] = {};
void produceMatrix()
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < columns; j++)
{
matrix[i][j] = rand() % 10 + 1;
}
}
}
void showMatrix()
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < columns; j++)
{
std::cout << matrix[i][j] << "\t";
}
std::cout << std::endl;
}
}
};
int main()
{
srand(time(0));
Matrix<3,4> a;
a.produceMatrix();
a.showMatrix();
}
https://ideone.com/rCLxSn
4 10 5 5
3 8 3 6
2 4 9 10
One thing is that you cannot make variable-length arrays this way.
Another thing is that if you create a variable within a function (like you were doing here with int matrix in produceMatrix()), it is then not visible in another function.
Therefore, the array containing the elements of the matrix should be declared in your struct there, where you have declared rows and columns.
To store the elements of your matrix, you can use one-dimensional array of length equal to rows*columns.
Now, you need some kind of dynamic array to be able to make it of the length not known in the compilation time.
One solution is to use a pointer and define an array with new operator in the constructor. However, if you use new, then you have to use delete at some point to deallocate memory, which here means that the destructor is needed. Another problem would be with copying of your matrices.
Another, simpler solution is to use std::vector, a container provided by c++ standard library. Here's how to do it with std::vector (you need to add #include<vector> to your file):
struct Matrix{
int rows;
int columns;
vector<int> matrix;
Matrix(int r, int c){
rows = r, columns = c;
matrix = vector<int>(c*r);
}
int produceMatrix(){
for(int i = 0; i < matrix.size(); i++){
matrix[i] = rand() %10 +1;
}
return 0;
}
int showMatrix(){
for(int i = 1; i <= matrix.size(); i++){
cout << matrix[i-1];
if(i%columns == 0) cout << endl;
else cout << " ";
}
return 0;
}
};
As many people commented, please go through a good C++ book to learn about arrays, classes, structs etc. As for your code, the following might produce what I think you want:
#include <iostream>
#include <vector>
struct Matrix
{
int rows;
int columns;
std::vector<std::vector<int>> matrix;
Matrix(int r, int c): rows(r), columns(c)
{
matrix.resize(r);
for(int i = 0; i < r; i++)
matrix[i].resize(c);
}
int produceMatrix()
{
for(int i = 0; i != rows; i++)
for(int j = 0; j != columns; j++)
matrix[i][j] = rand() %10 +1;
return 0;
}
int showMatrix()
{
for(int i = 0; i != rows; i++)
{
for(int j = 0; j != columns; j++)
std::cout << matrix[i][j]<<" ";
}
std::cout<<'\n';
}
};
int main()
{
srand(time(0));
Matrix a(3, 4);
a.produceMatrix();
a.showMatrix();
}

2D vector push_back

I have the code below and I'm strugling to add values to the vector. The end goal is to itterate through a list and for each itteration add a value to 2 rows of a vector but I'm strugling to understand how to push_back to a 2d vector.
std::vector<std::vector<int> >nns;
int i = 5;
nns.push_back(i, i);
for(int i = 0; i <nns.size(); i++)
{
for(int j = 0; j < nns[i].size(); j++)
{
std::cout << nns[i][j] << std::endl;
}
}
How would I add one column to this vector?
so
vector[0][0] = 0
vector[1][0] = 0?
Answer provided by Algirdas Works perfectly.
#include <iostream>
#include <vector>
using namespace std;
int main() {
std::vector<std::vector<int> > nns;
int i = 5;
nns.push_back(std::vector<int>{i});
for (int i = 0; i < nns.size(); i++) {
for (int j = 0; j < nns[i].size(); j++) {
std::cout << nns[i][j] << std::endl;
}
}
}

How to sort elements into C++ matrix?

I'm new to C++ programming. I need to sort this matrix:
#include <iostream>
#include <iomanip>
#include <cstdlib>
using namespace std;
int main(int argc, char** argv) {
Mat10 a;
fillRand(a, 5, 5);
prnMat(a, 5, 5);
cout << endl;
return 0;
}
void fillRand(Mat10 m, int n, int k) {
for (int i = 0; i < n; i++)
for (int j = 0; j < k; j++)
m[i][j] = rand() % 1000;
}
void prnMat(Mat10 a, int m, int n) {
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++)
cout << setw(8) << a[i][j];
cout << endl;
}
}
I need to sort the matrix from the beginning from the beginning. The smallest value must be at the beginning of the of the first column. The next must be below it and so on. The result must be sorted matrix - the smallest number must be at the beginning of the left column - the biggest value must be at the end of the matrix. Would you please help to solve the problem?
EDIT
Maybe I found possible solution:
void sort(int pin[10][2], int n)
{
int y,d;
for(int i=0;i<n-1;i++)
{
for(int j=0; j<n-1-i; j++)
{
if(pin[j+1][1] < pin[j][1]) // swap the elements depending on the second row if the next value is smaller
{
y = pin[j][1];
pin[j][1] = pin[j+1][1];
pin[j+1][1] = y;
d = pin[j][0];
pin[j][0] = pin[j+1][0];
pin[j+1][0] = d;
}
else if(pin[j+1][1] == pin[j][1]) // else if the two elements are equal, sort them depending on the first row
{
if(pin[j+1][0] < pin[j][0])
{
y = pin[j][1];
pin[j][1] = pin[j+1][1];
pin[j+1][1] = y;
d = pin[j][0];
pin[j][0] = pin[j+1][0];
pin[j+1][0] = d;
}
}
}
}
}
But since I'm new to programming I don't understand is this the solution?
Here is a simple example for you:
#include <vector>
#include <algorithm>
using namespace std;
//This is the comparation function needed for sort()
bool compareFunction (int i,int j)
{
return (i<j);
}
int main()
{
//let's say you have this matrix
int matrix[10][10];
//filling it with random numbers.
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
matrix[i][j] = rand() % 1000;
//Now we get all the data from the matrix into a vector.
std::vector<int> vect;
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
vect.push_back(matrix[i][j]);
//and sort the vector using standart sort() function
std::sort( vect.begin(), vect.end(), compareFunction );
//Finally, we put the data back into the matrix
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
matrix[i][j] = vect.at(i*10 + j);
}
After this, the matrix will be sorted by rows:
1 2
3 4
If you want it to be sorted by cols:
1 3
2 4
You need to replace matrix[i][j] in the last cycle only with matrix[j][i]
If you need to read about the the sort() function, you can do it here
Hope this helps.
You can simply call std::sort on the array:
#include <algorithm> // for std::sort
int main() {
int mat[10][10];
// fill in the matrix
...
// sort it
std::sort(&mat[0][0], &mat[0][0]+10*10);
}