Recursive function and vector.

Apr 16, 2013 at 9:01am
Is there a way to get the value of the elements through each pass of the recursive function rather than just one value?

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
#include<vector>
#include<iostream>

using namespace std;


// selectContain picks the 1 of the 4 vector element in data. srchContain used for iterator arithmetics.
double getData(vector<vector<int>> da, const int selectContain, int srchContain = 0)
{
    vector<int>::iterator beg = da.at(selectContain).begin(); //Sets a begin iterator within the selected 1 of 4 vector elements in data.

    beg += srchContain; //Iterators through the selected vector element.

    if (beg == da.at(selectEle).end() - 1) //Condition to break recursion when iteration reaches the end of selected vector element.
    {
        return *beg;
    }

    return *beg, getData(da, selectEle, srchContain + 1);

}


int main()
{

    vector<vector<int>> data{ {1,2,3,4}, {12,33,44,55}, {6,7,8}, {12,3,4,5} };

    cout << getData(data, 1, 0); //Passes data, selecting {12,33,44,55}, starting from 0.

    return 0;
}
Last edited on Apr 16, 2013 at 9:19am
Apr 16, 2013 at 9:12am
I find it hard to understand what this function is doing and the parameter names doesn't help much. If you want to return many values you can put the values in a vector and return the vector.
Apr 16, 2013 at 9:20am
You set getData to return double and returning pointe? wtf?
Apr 16, 2013 at 9:24am
*beg is not a pointer.
Apr 16, 2013 at 9:26am
Added comments, I hope that manages to clarify what it's doing. I want it to return

12 33 44 55

instead of just 55. This is meant to get data from a vector defined in a class. Unless I'm going about it horribly wrong.

Also if you find it hard to understand does that mean the code is written badly?
Apr 16, 2013 at 9:28am
It's dereferencing beg which is an iterator to get the value. Unless I'm not understanding this right either.
Apr 16, 2013 at 9:29am
Add vector returned from recursive call to current vector.
Apr 16, 2013 at 9:39am
Sorry MiiNiPaa but I don't understand. So I should be making another vector to collect the value returned from the function?
Apr 16, 2013 at 9:39am
If I've understood the intent correctly:
1
2
3
4
5
6
7
vector<int> get_slice( const vector<vector<int>>& da,
                        std::size_t row, std::size_t from_col = 0 )
{
    return row < da.size() && from_col < da[row].size()
               ? vector<int>( da[row].begin() + from_col, da[row].end() )
               : vector<int>() ;
}
Apr 16, 2013 at 10:13am
I was intending that the function would return the value like:

1
2
3
4
5
6
vector<int> store {1,2,3,4,5,6,7};
    
    for (auto x : store)
    {
        cout << x << endl;
    }



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//I thought this would do the same as the above.

int getData(vector<int> da, std::size_t val = 0)
{
    if (val == da.size() - 1)
    {
        return da[val];
    }

    return da[val], getData(da, val + 1);
}


int main()
{
    vector<int> store {1,2,3,4,5,6,7};

    cout << getData(store) << endl;

}


But I forgot the fact that functions can only return one value. Unless there's a way aside for creating a new vector and copying the contents over; or rather initializing a vector with the contents of another? (Am I understanding your code right JLBorges?)
Last edited on Apr 16, 2013 at 10:15am
Apr 16, 2013 at 10:20am
By logic this statement

cout << getData(data, 1, 0); //Passes data, selecting {12,33,44,55}, starting from 0

is equivalent to

for ( int x : data[1] ) std::cout << x << ' ';

I do not see any necessarity to write a special function. If you need some range of elements of a nested vector<int> it can be done very simple

Let assume that i - is the target vector and j - is the target starting element in the vector. Then you can write

1
2
std::vector<int> v( std::next( data[i].begin(), j ), std[i].end() );
for ( int x : v ) std::cout << x << ' ';
Last edited on Apr 16, 2013 at 10:20am
Apr 16, 2013 at 10:33am
> or rather initializing a vector with the contents of another?
> (Am I understanding your code right JLBorges?)

Yes. Initializing a vector with a slice of the contents of another.

The slice can also be a slice of references instead of copied values:

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
#include <vector>
using std::vector ;

vector<int> get_slice( const vector<vector<int>>& da,
                        std::size_t row, std::size_t from_col = 0 )
{
    return row < da.size() && from_col < da[row].size()
               ? vector<int>( da[row].begin() + from_col, da[row].end() )
               : vector<int>() ;
}

#include <functional>

vector< std::reference_wrapper<int>> get_slice( vector<vector<int>>& da,
                        std::size_t row, std::size_t from_col = 0 )
{
    return row < da.size() && from_col < da[row].size()
               ? vector< std::reference_wrapper<int>>( da[row].begin() + from_col, da[row].end() )
               : vector< std::reference_wrapper<int>>() ;
}

#include <iostream>

int main()
{
    vector<vector<int>> data{ {1,2,3,4}, {12,33,44,55}, {6,7,8}, {12,3,4,5} };

    for( int i : get_slice( data, 1, 1 ) ) // {33,44,55} (starting from 1)
        std::cout << i << ' ' ;
    std::cout << '\n' ;

    for( auto& ref : get_slice( data, 1, 1 ) ) ref += 100 ;

    for( int i : get_slice( data, 1, 1 ) ) std::cout << i << ' ' ;
    std::cout << '\n' ;
}


http://liveworkspace.org/code/351scV$0
Apr 16, 2013 at 10:39am
Here is a demonstrative example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <vector>
#include <iterator>
 
int main()
{
 
    std::vector<std::vector<int>> data{ {1,2,3,4}, {12,33,44,55}, {6,7,8}, {12,3,4,5} };
 
    for ( int x : std::vector<int>( std::next( data[1].begin(), 0 ), data[1].end()  ) )
    {
        std::cout << x << ' ';
    }
    std::cout << std::endl;
 
    return 0;
}


where i == 0 because in your original code you are trying to output a vector starting from the first element.

Or a more compound example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <vector>
#include <iterator>
 
int main()
{
 
    std::vector<std::vector<int>> data{ {1,2,3,4}, {12,33,44,55}, {6,7,8}, {12,3,4,5} };
 
    for ( std::vector<int>::size_type i = 0; i < data[1].size(); i++ )
    {
        for ( int x : std::vector<int>( std::next( data[1].begin(), i ), data[1].end()  ) )
        {
            std::cout << x << ' ';
        }
        std::cout << std::endl;
    }
 
    return 0;
}


Output is

12 33 44 55 
33 44 55 
44 55 
55
Last edited on Apr 16, 2013 at 10:51am
Apr 16, 2013 at 11:01am
@JLBorges - Thanks for the second example. Admittedly I don't quite understand it, but I'll look up the terms I'm not familiar with and figure it out. Appreciate the help.

@Vlad - Thank you for the explanation of what I was actually doing with cout << getData(data, 1, 0); and also for other ways to print out a vectors within a vector.

Case closed!
Topic archived. No new replies allowed.