4

Lets say i have:

int array[9][9]= {

        {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, 26, 27},
        {28, 29, 30, 31, 32, 33, 34, 35, 36},
        {37, 38, 39, 40, 41, 42, 43, 44, 45},
        {46, 47, 48, 49, 50, 51, 52, 53, 54},
        {55, 56, 57, 58, 59, 60, 61, 62, 63},
        {64, 65, 66, 67, 68, 69, 70, 71, 72},
        {73, 74, 75, 76, 77, 78, 79, 80, 81}

    };

how can i only apply some function to the first row (value 1 to 9 ) or the first column only (like value 1 to 73). lets say i want to say index 0 to 9 shall all have value 0.

is it possible to save this range in a variable?

Vadim Key
  • 1,242
  • 6
  • 15
Ali RJ
  • 55
  • 1
  • 5
  • Possible duplicate of [Get the first column of a matrix represented by a vector of vectors](http://stackoverflow.com/questions/15778377/get-the-first-column-of-a-matrix-represented-by-a-vector-of-vectors) – Teivaz May 18 '16 at 07:02
  • have a look at the documentation for `std::slice` it does exactly this. – Richard Hodges May 18 '16 at 08:11

5 Answers5

1

To isolate the rows of the array, you could take a reference to a row of the array:

int (&row)[9] = array[2];

For example the above line takes a reference to the 3rd row of the array.

Live Demo

For the columns, is more complicated.

Alternatevely, you could do the following construct that returns a vector of reference wrappers to either a column or a row of a 2D array.

// if flg == true you get row at idx else if flg == false you get column at idx
template<typename T, int N, int M>
std::vector<std::reference_wrapper<T>>
getRange(T (&arr)[N][M], std::size_t const idx, bool const flg = true) {
  if(flg) {
    return typename std::vector<std::reference_wrapper<T>>(std::begin(arr[idx]), std::end(arr[idx]));
  } else {
    typename std::vector<std::reference_wrapper<T>> out;
    out.reserve(N);
    for(int i(0); i < N; ++i) out.push_back(arr[i][idx]);

    return out;
  }
}

Live Demo

101010
  • 41,839
  • 11
  • 94
  • 168
  • thank you very much. i want to make sure that there is only one 5 in that row or column. how would you do that? – Ali RJ May 18 '16 at 08:17
1

Try to do like this:

for (int i = 0; i<10; i++) 
        array[0][i] = 0;
Sergiy Shvets
  • 180
  • 2
  • 14
  • 1
    very simple and solved my problem right. thank you. now one more question. now i want to test this range see if a number is repeated or not. for example i want to make sure that there is only one 5 in that row or column. how would you do that? – Ali RJ May 18 '16 at 08:16
  • Look at this post, similar question http://stackoverflow.com/questions/4003584/more-elegant-way-to-check-for-duplicates-in-c-array – Sergiy Shvets May 18 '16 at 08:36
1

There are no true multidimensional arrays in C.

In a true multidimensional array, all dimensions are on equal standing. Whatever you can do with rows, you can also do with columns.

This is not the case with C++. The third row of your array is just

array[3]

It's an array on its own in every regard. A range of rows, like any other range, can be represented as a (start, end) pair, e.g. make_pair(array[3], array[7]).

Nothingl like that can be done with columns. The third column, unlike the third row, is not an array, it's just a virtual collection of elements not sitting under any standard data structure umbrella.

The closest thing to a multidimensional array slices are custom iterators, such that ++i moves to either the next element to the right or to the next element below. While you're at it, consider moving away from C style arrays to STL style containers.

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243
0

For rows it's easy, as you can pass them like:

void foo(int * row, int cols) {
    for (int col = 0; col < cols; ++col) {
        int * x = row + col;
    }
}
...
foo(array[3], 9);
...

For columns it's more difficult but you can thought about every column as something that have specific offset in the array:

void boo(int * col, int rows, int cols) {
    for (int row = 0; row < rows; ++row) {
        int * x = col + row * cols;
    }
}

....

// process fourth column:
boo(array[0]+4, 9, 9);

Of course using sizeof instead of '9' and C++ vectors/array instead of C-style int[][] will make life more easy and code more readable and supportable.

Another way is to use boost::matrix e.g.:

using namespace boost::numeric::ublas;
matrix<double> m(9, 9);
matrix_row<matrix <double> > row(m, 5);
matrix_column<matrix <double> > col(m, 4);
Vadim Key
  • 1,242
  • 6
  • 15
0

You can do it by specifying indices (start and end range) with your function and mention whether it should be applied on row or column. Since you are using plain C style array it's trickier to deal with pointers. I recommend you to use vectors and pairs (for ranges).

An example for C style array

void some_function(int array[][9], bool row_or_column, size_t major, size_t start, size_t end){
    if (row_or_column = true) {
        for (int i = start; i < end; i++) {
            cout << array[major][i]; //perform your operation on row
        }
    }
    else {
        for (int i = start; i < end; i++) {
            cout << array[i][major]; //perform your operation on column
        }
    }
}

Set row_or_column as either true for row or false for column, major should specify the column number or row number and the ranges in start and end. Note: end is exclusive

For processing second row with range start = 0 and end = 5 i.e 10 to 14 some_function(array, true, 1, 0, 5)

For processing second column with range start = 0 and end = 5 i.e 2 to 38 some_function(array, false, 1, 0, 5)

jblixr
  • 1,345
  • 13
  • 34