Best method for swapping rows in 2d array? - c++

I want to do this in C++ code:
Initialize an array with 4 rows and 5 columns;
Ask the user about two row numbers in the range 0 to 4;
Swap the rows defined by the user in a 2D array.

You can use the following algorithm:
let arr be array
let a,b be row indices that are swapped
for each column index i
swap arr[a][i] and arr[b][i]
However, if instead of a 2d array you were to use an array of row pointers, you could instead simply swap the pointers.

You could declare an extra variable to temporarily hold each value as you swap it from row A to B.
Not sure what you mean by "best", is this in terms of speed or memory requirements?

Related

Isolate a column of a vector in c++

I have a 2d vector of string and need to isolate out three of the columns into 3 separate 1d arrays so i can convert them to doubles and perform operations on them.
Simply using:
for (int i = 0; i < 100; i++)
{
vectorname[i][2] = arrayname[i];
}
doesn't work and I don't understand why.
Sorry im new to coding and thanks in advance.
Thanks to first reply, i don't care if i remove the data or not, i just need it so i can operate on it, my vectors are declared as:
string vectorname[101][5];
string arrayname[99];
string arrayname2[99];
string arrayname3[99];
Ok I dont have my vectorname defined as a vector, it's just a 2d string, can i extract a column from that?
Do the columns still need to remain in the 2D vector, or be pulled out completely as independent data?
If you need independent data, I would do
vector<double> col(vectorname[i]);
Then manipulate col as needed. You could even do move construction if you don't need that data in the 2D vector anymore.
I think you have actual logic problems elsewhere though. Show us your vector declarations.
EDIT: What...? You're not declaring vectors at all. You're using pure arrays. And a 2D array shouldn't be called a vector. You're confusing other programmers with your name scheme.
The proper way to declare a vector of strings is
std::vector<string> vectorname(100);
And a vector of vector of strings (a 2D vector) is
std::vector<std::vector<string>(5)> vectorname(101);
But moreover, your dimensions mismatch. Your 1D vectors need to be the same length as the given dimension of your 2D, or 5 (101?) in this case.
If you're trying to copy the values along the first dimension of values, there's no direct constructor for that. You have to manually loop from 0 to 100 and say
arrayname[i] = vectorname[i][n];
Where n is your column number.

Merging a 2D array with sorted rows into a big 1D array

Given a 2d array which each row is sorted from left to right, from the smallest to the biggest, I want to sort the entire array into a 1D array from the smallest to the biggest.
the number of rows is N and the number of columns is M.
the complexity I need for it is MNlog(N)
What I had in mind to do, is do some kind of a merge sort on the 2d array and each time send 2 rows for the function and there is the point I got stuck.
the signature I'm given for the function is
void sort_rect(int a[N][M], int b[])
I'm promised the the 1d array of b has enough space for all the element of the 2d array.#C!!!
Using the standard approach (of merging the sorted arrays and then sorting) will give you O(NMLog(NM)).If you want an efficient approach then you should use min Heap data structure.You might want to read about heap data structure.
Create an output array of size N*M.This will hold the output sorted array.
Create a min heap of size N.Insert first element of every sorted array.
Remove the top element(minimum) from heap and put it in the output array.Replace this removed element with the next element from the same array of which this removed element was part.Repeat this until all elements are accounted for.
Complexity will be O(NMLog(N)).
Since all the elements in a[M][N] reside in sequential memory, you can treat that memory as flat. So you sort in place like this:
int *c = (int *)a;
and sort c, given that the size of the array is M*N.
Or you can copy it to b, by defining b like this:
int b[sizeof(a) / sizeof(int)];
memcpy(b, a, sizeof(a));
and now sort b.
Think of a merge sort, but applied to N arrays instead of 2. For each row you could keep an index of currently considered element. Now we need something to compare all the N values (instead of just 2). What you could do is use a heap (priority_queue) with an element structure like this:
struct Element {
int Value;
int Row; //tells you which row in the 2d array the value comes from
}
The algorithm would be as follows:
You add all the values from the column 0 to the priority
queue
Declare an array which will keep your currently considered index for each row. Initialize it to zeros.
In a loop (until you run out of elements)
check the element on the top of the queue (element = queue.top())
add element.Value to the 1d array
increment currently considered index for element.Row
remove the element from the top of the priority queue (queue.pop())
The resulting 1d array is sorted and the complexity is O(MNlog(N)). This is because you considered M*N elements and for each element adding/removing it from the priority_queue took log(N) time, because at any given moment the heap keeps no more than N elements.
I think that treating the 2d array as 1d and sorting would result in MNlog(MN) complexity which is a bit worse.

Pointer to array as a whole

I have 4 arrays that I need to combine into 1 by adding all the corresponding cells. So I would add up Cell 1,1 (row 1, column 1) of all 4 matrices and put that into Cell 1,1 of the resultant matrix.
Well the 4 matrices are coming from another program and instead of writing an adder function that takes 4 matrices as the argument, I just had 1 vector. So my function looks like this:
void combine_matrix(vector<int*> all_arrays) {
vector<int> cell_values; //Vector that stores the value of a particular cell of each matrix
for (int i = 0; i<all_arrays[0].size(); i++)
}
vector<int*> all_arrays is a vector of pointers that points to the 4 arrays. This way, the matrices can be of any size (all 4 have to be the same dimensions though) and the function would still work.
Basicaly I want a vector of pointers pointing to the array as a whole so I can use the size() function but all the examples I've seen are only giving me pointers to the actual elements in the matrix. Any idea on how to do what I need? Thanks
Make a Matrix class that contains the pointer to array and the size and other things you might need to work with, and even better, make a CombinedMatrix class that contains vector<Matrix>

Delete column from 2D array in C++

I have a quesion that I found in internet but it was not has best solution. My question is that I have one 2D matrix and I want to delete one column at ith position. Example the matrix can be represent as A[2][3]={1,2,3,4,5,6}. And I want to delete the column at postion 2. So the output is B={1,3,4,6}. Can you help me please?
A=[1 2 3
4 5 6]
The output
B=[1 3
4 6]
The function is
int** delete_column(int** inputMatrix,int position)
{
//The size of outMatrix must be smaller than inputMatrix
return outMatrix;
}
You can not do this in-place with static arrays in c++. You will need to create another array and copy data there. If you use an array of pointers to dynamic arrays however, you can move the elements in-place and than call realloc to shrink the arrays. You can Also use a vector of vectors and call remove on them.

Flattening a 3D array in c++ for use with MPI

Can anyone help with the general format for flattening a 3D array using MPI? I think I can get the array 1 dimensional just by using (i+xlength*j+xlength*ylength*k), but then I have trouble using equations that reference particular cells of the array.
I tried chunking the code into chunks based on how many processors I had, but then when I needed a value that another processor had, I had a hard time. Is there a way to make this easier (and more efficient) using ghost cells or pointer juggling?
You have two options at least. The simpler one is to declare a preprocessor macro that hides the complexity of the index calculation, e.g.:
#define ARR(A,i,j,k) A[(i)*ylength*zlength+(j)*zlength+(k)]
ARR(myarray,i,j,k) = ARR(myarray,i+1,j,k) + ARR(myarray,i,j+1,k) + ...
This is clumsy since the macro will only work with arrays of fixed leading dimensions, e.g. whatever x ylength x zlength.
Much better way to do it is to use so-called dope vectors. Dope vectors are basically indices into the big array. You allocate one big flat chunk of size xlength * ylength * zlength to hold the actual data and then create an index vector (actually a tree in the 3D case). In your case the index has two levels:
top level, consisting of xlength pointers to the
second level, consisting of xlength arrays of pointers, each containing ylength pointers to the beginning of a block of zlength elements in memory.
Let's call the top level pointer array A. Then A[i] is a pointer to a pointer array that describes the i-th slab of data. A[i][j] is the j-th element of the i-th pointer array, which points to data[i][j][0] (if data was a 3D array). Construction of the dope vector works similar to this:
double *data = new double[xlength*ylength*zlength];
double ***A;
A = new double**[xlength];
for (int i = 0; i < xlength; i++)
{
A[i] = new double*[ylength];
for (int j = 0; j < ylength; j++)
A[i][j] = data + i*ylength*zlength + j*zlength;
}
Dope vectors are as easy to use as normal arrays with some special considerations. For example, A[i][j][k] will give you access to the desired element of data. One caveat of dope vectors is that the top level consist of pointers to other pointer tables and not of pointers to the data itself, hence A cannot be used as shortcut for &A[0][0][0], nor A[i] used as shortcut for &A[i][0][0]. Still A[i][j] is equivalent to &A[i][j][0]. Another caveat is that this form of array indexing is slower than normal 3D array indexing since it involves pointer chasing.
Some people tend to allocate a single storage block for both data and dope vectors. They simply place the index at the beginning of the allocated block and the actual data goes after that. The advantage of this method is that disposing the array is as simple as deleting the whole memory block, while disposing dope vectors, created with the code from the previous section, requires multiple invocations of the free operator.