How to calculate the sum of individual elements from two 2D arrays? - c++

I want to write a function addArrays which will, as parameters, take two 2D arrays of type int and of dimensions 3x4, and it's job is to add individual elements of each index from the given arrays and display it in the console.
In main(), I created two 2D arrays arrA and arrB of appropriate sizes with intitialized members and check the functionality of the created function.
My code so far:
#include <iostream>
using namespace std;
void addArrays(int x[3][4], int y[3][4]);
int main()
{
int arrA[3][4] = { {7, 8, 13, 22}, {56, 4, 78, 3}, {22, 13, 46, 5} };
int arrB[3][4] = { {32, 47, 56, 14}, {33, 100, 19, 64}, {4, 18, 157, 84} };
}
void addArrays(int x[3][4], int y[3][4])
{
}
Honestly, I know how to work with 1D arrays, but not displaying the sum of all individual elements. I know I have to use a for loop, but again, I'm confused as to how to pass in a 2D array and use it.

You mention you know how to work with 1D arrays, it's the same for 2D arrays, only with one more dimension.
In a 1D array you use arrA[0] to access the first element of the array, in a 2D array you use arrA[0][0] to access the first element in the first line of the array, arrA[0][1] to access the second element in the first line of the array. To access the first element in the second line you would use arrA[1][0] and so on, you get the idea.
So to loop through all the elements in the array you can use nested loops like so:
void addArrays(int x[3][4], int y[3][4])
{
for( int i = 0; i < 3; i++){ // make sure to use the correct dimensions
for(int j = 0; j < 4; j++){ // 3 lines and 4 columns
// x[i][j] accesses elements in array x
// y[i][j] accesses elements in array y
}
}
}
I think you'll manage to do the math yourself. After that you just need to send data to the standard output, i.e. to print data in the console. For that, as you may know, you use std::cout.
Side notes:
In the function void addArrays(int x[3][4], int y[3][4]){...} you may omit the first dimension of the array i.e. int x[][4] or int (*x)[4] instead of int x[3][4], since the argument will decay to a pointer to array.
Since it seems that you are not to change the values of the passed arrays, using const is recommend. You would have void addArrays(const int (*x)[4], const int (*y)[4]);
As you are using C++, you can take advantage of the possibility of using references, something like void addArrays(const int (&x)[3][4], const int (&y)[3][4]){/*same code*/}, the benefit being you must pass a correct object to the function otherwise the program will fail to compile whereas in the previous versions if you pass, for example, NULL, i.e. addArrays(arrA, NULL); the program will compile fine but will result in undefined behavior when you run it. References are safer and you should use them when possible.
It's more or less consensual among more experienced C++ programmers that the usage of using namespace std; is not a good practice, you can read more about it, and find alternatives following the link.

I will start this for you and try to give you an idea of the general structure, but since you have not shown your attempt at the problem I won't fill things in for you.
The basic idea here when looping through 2D arrays (of size MxN) is that you can really just think about it in terms of looping through M arrays of length N.
void loopThroughArray(int arr[M][N])
{
// Loop over M arrays
for (int m = 0; m < M; ++m) {
// For each m'th array, loop over its N contents
for (int n = 0; n < N; ++n) {
// Doing work
arr[m][n] = 1234;
}
}
}

Related

Initialization of vector of vectors

vector<vector<int>>dp(3);
for(int i = 0; i<3; i++) {
vector<int>price(10);
dp.push_back(price);
}
It is showing error while initialization. Can anyone explain the reason behind this wrong code?
If what you intend is declaring an empty two dimensional vector[3][10], you can do it at once.
#include <iostream>
#include <vector>
int main()
{
std::vector<std::vector<int>> dp(3,std::vector<int>(10));
std::cout<<dp.size(); //3
std::cout<<std::endl<<dp[0].size(); //10
}
Then you can assign values to it by using something like dp[0][4]=12; or with loops.
This statement
vector<vector<int>>dp(3);
create a vector dp with 3 default constructed int vectors and in loop, you are doing
dp.push_back(price);
the push_back() appends the given vector value to the end of the container. So, after loop, you will end up having dp vector of size 6, out of which first 3 are empty vectors and last 3 are vectors of 10 int elements.
Instead of specifying size, you can use reserve() to reserver the storage:
vector<vector<int>>dp;
dp.reserve(3);
for(int i = 0; i<3; i++) {
vector<int>price(10);
dp.push_back(price); // A suggestion: check emplace_back
}
To create a vector of 3 vectors, each having 10 int elements, you can simply do:
vector<vector<int> >dp (3, vector<int>(10));
Also, if you want to initialise all elements with some value, say -1, you can do:
vector<vector<int> >dp (3, vector<int>(10, -1));

Easy way to create multiple-dimension arrays in C++ with new operator

I need to create a lot of small 2-dimension arrays in C++ code.
The problem is that it's a lot of work to create even a simple array:
new int* [2]{
new int[2]{9, 9},
new int[2]{25, 19}
};
Is there any better way how to do that?
I wanted to avoid writing "new int[]..." every time.
If the dimensions are not decided at runtime, and all the inner arrays have the same dimensions, you do not need dynamic allocation here.
Just declare an array:
int myArray[2][2] = {
{9, 9},
{25, 19}
};
That's it!
I recommend allocating as a single dimension array. You can then treat the 1D array as a 2D array:
const unsigned int MAX_ROWS = 2U;
const unsigned int MAX_COLUMNS = 5U;
int example_array[MAX_ROWS * MAX_COLUMNS];
// Get value at [row][column]:
unsigned int one_dim_index = (row * MAX_COLUMNS) + column;
int value = example_array[one_dim_index];
For small array sizes, this would be more efficient since the processor can fit the entire contiguous array in the data cache. With your solution, an array of pointers, you have no idea where the sub-arrays are located and they may not be contiguous (thus requiring a refetch into the cache).
Edit 1: Initializing
You can initialize the array by making the rows and columns pretty:
int example_array[MAX_ROWS * MAX_COLUMNS] =
{
/* row 0 */ 1, 2, 3, 4, 5,
/* row 1 */ 6, 7, 8, 9, 10,
};
Maybe you can use nested for loops to do the task
const int ARRAY_SIZE = 2;
int **create_array() {
int **array = new int*[ARRAY_SIZE];
if (array == nullptr) { return nullptr; }
for (int i=0; i<ARRAY_SIZE; i++) {
array[i] = new int[ARRAY_SIZE];
if (array[i] == nullptr) { return nullptr; }
}
return array;
}
If you want to assing the values you can do it directly in here. But they should come from a function of i. If you want some really specific values it will need to be a manual job

Unable to access the elements of a pointer to an array

I have a following array which I am passing as a pointer. BTW, I am new to C++ and just started pointers.
int arr[3][4]= {{2,3,4,8},{5,7,9,12},{1, 0, 6, 10}};
//int *a = &arr[0][0];
BuildStringFromMatrix((int *)arr, 3, 4);
I have a a following function with which I wanna access the elements of the passed array.
void BuildStringFromMatrix(int *a, int height, int width);
My implementation of the accessing the element is as follows
for(int i=0; i<height; i++){
for(int j=0; i<width; j++){
int x = *(*(a+i) + j);
std::cout<<x;
}
}
While using this implementation I am getting an error
invalid type argument of unary β€˜*’ (have β€˜int’
)
int x = *(*(a+i) + j);
How can I fix this issue.
P.S - I wanna implement this using single pointer.
Your function receives a pointer to int. It doesn't "remember" that it is actually pointing to an int that is in a 2-D array (let alone what the array dimensions are).
So if you want to access a certain element of the 2-D array you must perform a calculation to find how many units to offset from the pointer to get to the intended element. (This is sometimes called "flattening an array").
Typically row * row_length + column is the offset for a particular row-column entry, so in your case int x = a[i*width + j]; is the right statement to use.
If this is still unclear I suggest printing out the value of i*width+j at each iteration and seeing how it iterates over the array (or follow in your debugger).

Swapping two values within a 2D array

I am currently working on a 15 puzzle programming assignment. My question here is about how I would go about swapping the empty tile with an adjacent tile.
So, for example, let's go with the initial setup board.
I have:
int originalBoard[4][4] = {
{1 , 2, 3, 4},
{5 , 6, 7, 8},
{9 ,10,11,12},
{13,14,15, 0}};
So here, the locations of 12, 15, and 0 (the empty tile) in the array are [3][4], [4][3], and [4][4] respectively. What would be a method of swapping 0 out with either 12 or 15?
What I had in mind for this was creating a loop that would keep track of the empty tile every time I made a move.
I believe an optimal method would be to have two functions. 1 that would update the location of the empty tile, and 1 to make the move.
So, right off the top of my head I would have:
void locateEmptyTile(int& blankRow, int& blankColumn, int originalBoard[4][4])
{
for (int row = 0; row < 4; row++)
{
for (int col = 0; col < 4; col++)
{
if (originalBoard[row][col] == 0)
{
blankRow = row;
blankColumn = col;
}
}
}
}
void move(int& blankRow, int& blankColumn, int originalBoard[4][4])
{
}
And in my main function I would have the variables: int blankRow and int blankColumn
Now, how would I take that data from locateEmptyTile and apply it into the move function in the relevant practical manner? The process does not currently connect within my head.
I appreciate any little bits of help.
If you're just asking for swap function you can use std::swap:
#include <algorithm> // until c++11
#include <utility> // since c++11
...
int m[3][3];
...
//somewhere in the code
std::swap(m[i][j], m[j][i]); // this swaps contents of two matrix cells
...
Or you can just write where you want to swap contents of two variables (in example int a and int b):
int temp = a;
a = b;
b = temp;
As you can see swapping is the same as with normal arrays, c++ does not know if you are swapping two matrix cells or two array elements, it just knows that you are swapping two memory blocks with certain type.
A basic swap concept (pre-C++11) is hold a temporary variable. Simply...
template<typename T, typename U>
void swap(T& lhs, U& rhs) {
T t = lhs;
lhs = rhs;
rhs = t;
}
So, you don't need to reference blankRow and blankCol, you just need to reference the values on the grid. Lets say that you want to swap what you know is blank positioned at (2, 1) with (2, 2)...
swap(originalBoard[2][1], originalBoard[2][2]);
... will swap the values within originalBoard.
If you are using C++11 or later, just use std::swap() to swap positions. That's exactly what it does.
If you would like originalBoard to be immutable an result in a totally different board, just copy it first before applying the switch.

Add a matrix of 2x2 into a vector in c++

I am trying to fill a vector with a matrix of values in c++. I'm not very self confident with this procedure (I don't know well about pointers and I don't know if I need it here) however I am trying this
int auxMat[gray.rows][gray.cols];
vector<int> collectionSum;
collectionSum.push_back(auxMat);
When I try to compile I receive an error which says
invalid arguments 'Candidates are: void push_back(const int &)
Can anyone tell me wether it's possible to do, how can I solve it?
I read something about erasing cache memory, changing my eclipse compiler, my c++ version, however I don't think the problem is so big.
You cannot push back a matrix into a vector. What you can do is preallocate memory for your vector (for speeding things up) then use the std::vector<>::assign member function to "copy" from the matrix into the vector:
vector<int> collectionSum(gray.rows * gray.cols); // reserve memory, faster
collectionSum.assign(*auxMat, *auxMat + gray.rows * gray.cols);
This should be pretty fast. Otherwise, you can push back each individual element in a loop.
EDIT
See May I treat a 2D array as a contiguous 1D array? for some technicalities regarding possible undefined behaviour (thanks #juanchopanza for the comment). I believe the code is safe, due to the fact that the storage of the matrix is contiguous.
Because the array auxMat is continuous in memory, you can just copy it directly from memory into your vector. Here, you are telling the vector constructor to copy from the start of auxMat until its end in memory using pointer arithmetic:
std::vector<int> collectionSum(auxMat, auxMat + (gray.rows * gray.cols));
EDIT:
Sorry, I read your question as being a 1D array (int*) rather than a 2D (int**) array. I honestly recommend switching over to a 1D array because often it is faster and easier to work with. Depending on whether your using row-first order or column-first order, you can access the element you want by:
elem = y * width + x; // for row-first order
elem = x * height + y; // for column-first order
For instance:
// Create a 3x3 matrix but represent it continuously as a 1D array
const int A[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
const unsigned width = 3;
const unsigned height = 3;
for (int y = 0; y < height; ++y)
{
for (int x = 0; x < width; ++x)
{
printf("%d ", A[y * width + x]);
}
printf("\n");
}