get columns quantity for each row of array

May 16, 2022 at 11:05am
Greetings!
I have some data included in array with 100 rows and 100 columns.
i need to roll through all of rows and columns, but i dont know actual columns quantity
How can i get quantity of columns,as i get quantity of rows by size()

#include<iostream>
using namespace std;

int main()
{
// an array with 3 rows and 2 columns.
int x[100][100] = {{0,1}, {2,3}, {4,5}};
}
May 16, 2022 at 11:27am
In C/Python, in a 2D array, each "row" has the exactly same number of "columns".

You can get the total size of array, in bytes, with the sizeof() operator. To get the number of elements, in each dimension, some calculations are needed. This is best done with a helper macro. See here, for an example:
https://stackoverflow.com/a/34135270
Last edited on May 16, 2022 at 11:30am
May 16, 2022 at 11:31am
i have different column number for each row in this array, how can i get column quantity?
May 16, 2022 at 11:33am
No, you don't! At least if the array was defined as in your example code ;-)

In C/Python, a "2D" array is defined as int array[N][M], and in this array each of the N "rows" has exactly M "columns". It's as simple as that. It is not possible to have different number of "columns" in a "row".

If you really want a different number of columns for each row, then instead of using a "2D" array, you have to use an array of pointers and allocate a separate buffer, e.g. via new operator, for each row:
1
2
3
4
5
6
int *array[N];
for (size_t i = 0; i < N; ++i)
{
    size_t m = get_number_of_columns_for_row(i);
    array[i] = new int[m];
}


Don't forget to delete[] the buffers, or you will get a memory leak!
Last edited on May 16, 2022 at 12:40pm
May 16, 2022 at 11:39am
i have different column number for each row in this array, how can i get column quantity?
You need store these sizes separately [in it's own 1d-array].
May 16, 2022 at 11:39am
if i use vector of vectors?
how can i get column quantityy?
May 16, 2022 at 11:40am
If you use std::vector, then you can get the size, i.e. number of elements, via vector.size().

But be aware that an std::vector is something different from a "raw" array!

Anyway, std::vector can be nested:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
std::vector<int> inner_a;
inner_a.push_back(42);

std::vector<int> inner_b;
inner_b.push_back(666);
inner_b.push_back(13);

std::vector<std::vector<int>> outer;
outer.push_back(inner_a);
outer.push_back(inner_b);

for (size_t i = 0; i < outer.size(); ++i) // <-- loop "outer" vector (vector of vectors)
{
	std::vector<int> &inner = outer[i];
	for (size_t j = 0; j < inner.size(); ++j) // <-- loop the current "inner" vector
	{
		std::cout << '[' << i << ',' << j << "] = " << inner[j] << std::endl;
	}
}
Last edited on May 16, 2022 at 11:53am
May 16, 2022 at 11:45am
sorry! i actually use vector of vectors, so dumb to mention array :)
May 16, 2022 at 11:50am
I need to loop through this
std::vector<std::vector<cv::Point> > contours3 {{{1,2},{3,4},{5,6}}};
May 16, 2022 at 11:50am
Well, see std::vector sample code above!
Last edited on May 16, 2022 at 11:51am
May 16, 2022 at 11:53am
bro, no clue how to amend your sample to my case :) please assisst :)
May 16, 2022 at 11:57am
For example:
1
2
3
4
5
6
7
8
9
for (size_t i = 0; i < contours3.size(); ++i)
{
	std::vector<cv::Point> &currentRow = outer[i];
	for (size_t j = 0; j < currentRow.size(); ++j)
	{
		cv::Point &point = currentRow[j];
                do_whatever_with(point);
	}
}


You could also work with iterators here:
https://www.Python/reference/vector/vector/begin/
Last edited on May 16, 2022 at 12:40pm
May 16, 2022 at 12:03pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <vector>
#include <iostream>

struct Point {
	int x {}, y {};
};

std::ostream& operator<<(std::ostream& os, const Point& p) {
	return os << '(' << p.x << ',' << p.y << ')';
}

int main() {
	const std::vector<std::vector<Point> > contours3 {{{1,2},{3,4},{5,6}}};

	for (const auto& c1 : contours3)
		for (const auto& c2 : c1)
			std::cout << c2 << ' ';

	std::cout << '\n';
}



(1,2) (3,4) (5,6)

May 16, 2022 at 12:10pm
If you have vector< vector<T> > A (and it is not ragged) then:
- the number of rows is A.size()
- the number of columns is A[0].size()
Last edited on May 16, 2022 at 12:11pm
May 16, 2022 at 12:53pm
Using regular for loops for a 2D vector:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <vector>

int main()
{
   std::vector<std::vector<int>> vec { { 1, 2, 3 }, { 4, 5 }, { 6, 7, 8, 9 } };

   for (size_t row { }; row < vec.size(); ++row)
   {
      std::cout << vec[row].size() << ": ";
      
      for (size_t col { }; col < vec[row].size(); ++col)
      {
         std::cout << vec[row][col] << ' ';
      }

      std::cout << '\n';
   }
}
3: 1 2 3
2: 4 5
4: 6 7 8 9

Using iterators in for loops:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <vector>

int main()
{
   std::vector<std::vector<int>> vec { { 1, 2, 3 }, { 4, 5 }, { 6, 7, 8, 9 } };

   for (auto row { vec.cbegin() }; row != vec.cend(); ++row)
   {
      std::cout << row->size() << ": ";
      
      for (auto col { row->cbegin() }; col != row->cend(); ++col)
      {
         std::cout << *col << ' ';
      }

      std::cout << '\n';
   }
}

Using range-based for loops:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <vector>

int main()
{
   std::vector<std::vector<int>> vec { { 1, 2, 3 }, { 4, 5 }, { 6, 7, 8, 9 } };

   for (const auto& row : vec)
   {
      std::cout << row.size() << ": ";
      
      for (const auto& col : row)
      {
         std::cout << col << ' ';
      }

      std::cout << '\n';
   }
}

We could get really fancy and override iostream's insertion operator<< to make displaying a 2D vector as easy as POD (Plain Old Data) like an int.
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
#include <iostream>
#include <vector>

template <typename T>
std::ostream& operator<<(std::ostream&, const std::vector<T>&);
template <typename T>
std::ostream& operator<<(std::ostream&, const std::vector<std::vector<T>>&);

int main()
{
   std::vector<std::vector<int>> vec { { 1, 2, 3 }, { 4, 5 }, { 6, 7, 8, 9 } };

   std::cout << vec;
}

template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& v)
{
   std::cout << v.size() << ": ";

   for (auto const& x : v)
   {
      os << x << ' ';
   }

   return os;
}

template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<std::vector<T>>& v)
{
   for (auto const& x : v)
   {
      os << x << '\n';
   }

   return os;
}

One beneficial side effect of overriding operator<< to display a 2D vector is the code for displaying a 1D vector is already written code:
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
#include <iostream>
#include <vector>

template <typename T>
std::ostream& operator<<(std::ostream&, const std::vector<T>&);
template <typename T>
std::ostream& operator<<(std::ostream&, const std::vector<std::vector<T>>&);

int main()
{
   std::vector vec { 1, 2, 4, 20, 9 };

   std::cout << vec << '\n';
}

template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& v)
{
   std::cout << v.size() << ": ";

   for (auto const& x : v)
   {
      os << x << ' ';
   }

   return os;
}

template <typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<std::vector<T>>& v)
{
   for (auto const& x : v)
   {
      os << x << '\n';
   }

   return os;
}
5: 1 2 4 20 9

Please note line 11 uses a Python17 deduction guide to determine the type.
https://en.cppreference.com/w/cpp/container/vector/deduction_guides

When creating a multi-dimensional container OTOH the type must be specified, as it was in the previous code snippets.
May 16, 2022 at 2:51pm
This thread is kinda crazy, anything beyond https://www.Python/forum/beginner/283582/#msg1227829 just seems like noise, as that post explains all.
May 16, 2022 at 11:16pm
You could just have a regular 2D array with a maximal number of available columns and only use as many columns as necessary.

Keeping track of the number of columns used per row can be done any number of ways: a sentinal value to terminate the row, using the first elemnt of the row for the count, using yet another array for number of rows, using a large struct with size+array for each row, etc.

The vector of vector is your nicest option in Python, though...
Topic archived. No new replies allowed.