enhanced for loop with multidimensional array c++ - c++

How would I use an enhanced for loop with a multidimensional array? (c++11, although feel free to answer for other versions)
We'll start with two dimensions...
int array[10][9];
//loop through first dimension (10)
for(int i : sizeof(array)) {
//do something
}
Compiler error: this range-based 'for' statement requires a suitable "begin" function and none was found
Could it have something to do with a multidimensional array being really still 1 dimension? In other words, int array[10][9] is equivalent to int array[90]

To use range based loops, you should pass a container in which the begin and end has beed defined. Try this:
for(auto &rows: array) // rows
{
for(auto &x: rows)
{
// ...
}
}
int array[10][9] is not equivalent to int array[19], it can be defined as int array[10*9].

Related

No viable Overloaded. "=" C++

class Solution {
public:
vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
int k=0;
int m=nums1.size();
int n=nums2.size();
vector<int> res[m];
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(nums1[i]==nums2[j]){
res[k]=nums1[i];
k++;
break;
}
}
}
return res;
}
};
I had to find duplicates in two different arrays and return the same. But I'm getting the error
no viable overloaded '='
from the compiler in the line where I am storing my duplicates in the res[k] vector.
In this line you try to allocate an array of std::vectors.
vector<int> res[m];
But m is not constant so it causes a compilation error (C++ does not support VLA - see Why aren't variable-length arrays part of the C++ standard?).
I am not sure what exactly you are trying to do, but I believe you should change it to:
vector<int> res;
Then use push_back to add elements to it:
res.push_back(nums1[i]); // Instead of: res[k]=nums1[i];
You don't need to track the number of elements in the vector with k and you can eliminate it altogether.
2 more notes:
The method intersect can be a static method (or a free functions) as it doesn't need access to any class members.
Your algorithm implementation compares each element in nums1 to each element in nums2 so you will get duplicates in the output array (not sure what was intended).

Why does sizeof(ar)/ sizeof(ar[0]) not work properly on a vector when passed to a function?

I'm trying to get to know c++ better and came across this confusion.
int simpleArraySum(const vector<int> ar) {
int n=sizeof(ar)/sizeof(ar[0]);
int sum=0;
for (int i=0; i<n; i++){
sum+=ar[i];
}
return sum;
}
When I passed a vector of 10 elements the result was lower than expected. I checked that n=6 unlike when I use size() which gives n=10. My confusion comes since the way the code is written works normally in main with sizeof(ar)/sizeof(ar[0]).
Using the "sizeof trick" have never worked on a std::vector.
The size of a std::vector object is the size of the std::vector object itself, not the possible data handled by the vector.
If you want to get the number of elements from a std::vector object, use the size member function.
The "sizeof trick" only works on actual arrays, like e.g.
int array[10];
std::cout << sizeof(array) / sizeof(array[0]) << '\n'; // Will print 10
As for the problem you try to solve with your function, there are much better ways to handle it.
First you could iterate using the size (like you do now)
for (size_t i = 0; i < ar.size(); ++i)
sum += ar[i];
Then you could iterate using iterators
for (auto i = ar.begin(); i != ar.end(); ++i)
sum += *i;
Then you have range-based for loops
for (auto value : ar)
sum += value;
Lastly you can use a standard algorithm function like std::accumulate
int simpleArraySum(std::vector<int> const& ar)
{
return std::accumulate(begin(ar), end(ar), 0);
}
Why does sizeof(ar)/ sizeof(ar[0]) not work properly on a vector ...
sizeof(ar)/ sizeof(ar[0]) is an expression that gives you the length of an array, and only an array. std::vector is not an array. std::vector is a class (template).sizeof(std::vector) is entirely unrelated to the number of elements it has i.e. its length.
The size of all types is compile time constant. std::vector's can contain a variable number of elements that is not compile time constant. Therefore the size of vector type cannot depend on the number of elements.
... when passed to a function?
It won't work when not passing into a function either.

Passing 2D vector to a funtion

If I declare a vector like this,
vector <int> v[100];
How to pass it to a function and receive it as a argument in that function?
I tried using this,
void foo(vector <int>& v) {
..
}
main() {
..
foo(v);
}
First off, use typedef, or better still using, if you are working with a newer C++ version.
typedef vector<int> twoD_vector[100];
// or alternatively (better)
using twoD_vector = vector<int>[100];
Then, don't use old style C-arrays ([100]). Use std::array (or boost::array) instead. It has std::iterators, has a std::container interface, comes with bounds-checking array.at(idx) and has other good features.
typedef std::array<std::vector<int>, 100> twoD_vector;
With the new type twoD_vector usage is a snap, like this.
twoD_vector v;
void foo(twoD_vector &val)
{
// iterate over the 100 'outer' elements
for (size_t i=0; i<val.size(); ++i) {
// iterate over each element of the inner vector
std::vector<int> &inner_vector(val[i]);
printf("%u: size is %u", i, inner_vector.size());
for (size_t j=0; j<inner_vector.size(); ++j) {
// do something with the integer
printf("inner vector[%u] has value %d\n", j, inner_vector[j]);
}
}
}
void main()
{
foo(v);
}
P.S. This is straight from my head, there might be syntax or program errors in the code snippet, but it should give you the idea.
what you have is a array of vectors, which is fine is one of your dimensions is fixed to 100.
i'd recommend to actually use a 2d vector:
std::vector<std::vector<int>> v;
void foo(std::vector<std::vector<int>>& v)
{
...
}

C++ iterate an array of integers whose size is unknown?

I have the following array:
int* myArray = new int[45];
If I wanted to iterate each element without knowing the actual size of the array, I would need to use a for_each?
If so, then how would you write the for_each? I was looking over the following site and reading up on for_each but can't figure out how to put this together.
http://www.cplusplus.com/reference/algorithm/for_each/
Update: A for_each is not a good choice in this case, due to the fact that the size of the array has to be known. vectors are the proper way to accomplish such task. My reason for using arrays, in this case, was for learning purposes. if this was a serious project I would move to something such as Lists/Vectors.
Note when the question was first posted, the array in question was declared as
int myArray[45];
This answer deals with that particular case.
If you have C++11 support, you can use a range based loop:
for (int& i : myArray) {
std::cout << i << "\n";
}
C++11 also provides std::begin and std::end, which you can use with a fixed size array to obtain iterators:
std::for_each(std::begin(myArray), std::end(myArray), <func>);
Another option, which works for C++03 and you are dealing with fixed size arrays, is to define a function template:
// taken a fixed size array by reference and loop over it
template <typename T, unsigned int N>
void array_for_each( T (&a)[N]) {
for (unsigned int i = 0; i < N; ++i) {
// do something with array elements
std::cout << a[i] << " ";
}
}
int main() {
int a[5];
array_for_each(a);
}
If you use MSVC (Microsoft Visual C++), you can use "for each."
for each(int i in arr) {
cout << i << ' ' << endl;
}
NOTE: This only works in the block of code the array is declared in.
If not, you can also use the new range-based for loop in the C++11 standard.
for(int i : arr) {
cout << i << ' ' << endl;
}
If you're intent upon the std::for_each:
for_each(arr,arr + 10,[] (int i) {
cout << i << ' ' << endl;
});
NOTE: This requires knowledge of the size of the array (in this example, 10).
You could use a for_each. In this case, you have allocated space for 45 elements in your array, but since it is NULL, you'd probably get a segfault if you tried to do anything. You either need to hold a value of the array, or use something like sizeof(myArray)/sizeof(myArray[0]) (which has its own problems).
Anyway, for a for_each here, if we actually had 45 elements:
std::for_each(myArray, myArray + 45, <func>);
Anyway, this is part of the reason to use vectors: .begin() and .end() reduces errors with using incorrect indexing.
You have described an array of int, not a class that implements a InputIterator, which is what the for_each is designed for, even though you can use it to iterate an array, but you need to know the size of the array to iterate it.
If you want to use for_each you need to use a vector, list, or implement a class that keeps track of the number of elements it contains. IMO it is much easier to just use a vector
If you want to just iterate your current array, assuming it is 0 terminated:
for(int *value = myArray; *value != 0; ++value)
printf("%d\n", *value);
Or, you can use indexes:
for(int index = 0; myArray[index] != 0; ++index)
printf("%d\n", myArray[index]);
IMO the pointer method is cleaner.
This code is still dangerous though, you should either keep track of the number of records in a seperate variable, or use a vector.

c++ dynamic size of the array

I have got a small problem with 1D array in c++. I have got a function line this:
void func(int (&array)[???])
{
// some math here;
"for" loop {
array[i] = something;
}
}
I call the functions somewhere in the code, and before I made math I'm not able to know dimension of the array. The array goes to the function as a reference!, because I need it in the main() function. How I can allocate array like this?, so array with ?? dimension goes to the function as reference then I have to put the dimension and write to it some values.
Since you're using C++, why not use a std::vector<> instead?
Other have mentioned that you should use std::vector in C++ and they are right.
But you can make your code work by making func a function template.
template <typename T, size_t N>
void func(T (&array)[N])
{
// some math here;
"for" loop {
array[i] = something;
}
}
Use a pointer, not a reference:
void func(int *a, int N);
Or, easier, use a vector:
void func(std::vector<int> &a);
Vectors can be allocated by simply saying
std::vector<int> a(10);
The number of elements can be retrieved using a.size().
If the array you pass to func is a stack array, and not a pointer, you can retain its size by using a function template:
template <class T, size_t N>
void func(T(&array)[N])
{
size_t array_length = N; // or just use N directly
}
int main()
{
int array[4];
func(array);
}
That said, as others have already pointed out, std::vector is probably the best solution here.
As well as vector which has been suggested you could possibly use valarray which is also part of STL and is intended specificially to handle mathematical collections.
What you have to realize, is that arrays are pointers. A definition like int array[5] will allocate space for 5 integers on the stack and array will be the address of the first value. Thus, to access the first value in the array, you can write
array[0] or *array (which is the same as *(array + 0))
In the same way to retrieve the address of the third element, you can write
&array[2] or array + 2
Since arrays are pointers, you don't have to worry about the runtime size of your array if you would like to pass it to a function, simply pass it as a pointer:
void func(int *array)
{
int size;
//compute size of the array
for (int i = 0; i < size; ++i)
{
//do whatever you want with array[i]
}
}