I am writing a function to populate a vector in ascending order using values from a binary search tree. I am also trying to keep the run time of this function to O(n). I am thinking I will need to call a recursive function that traverses the bst and gets the numbers in ascending order. I am confused about how to use the results from the recursive function. Is it okay to use a recursive function inside of push back like this?
void vector_function(){
std::vector<int> *v = new std::vector<int>();
v.pushback(recursive_function(node *p));
}
for example if the Binary Search tree had values 5, 3, 4, 7 the resulting vector would have 3, 4, 5, 7
I am confused about how to use the results from the recursive function. Is it okay to use a recursive function inside of push back like this?
I can think of two ways of doing that.
Option 1
Change recursive_function to also accept a reference to a std::vector<int>. Update its implementation to push_back elements to the vector appropriately.
Pass the vector to recursive_function when calling it.
void recursive_function(node* p, std::vector<int>& v)
{
// When appropriate...
v.push_back(p.data);
}
and use it as
void vector_function(){
std::vector<int> v;
recursive_function(p, v));
}
Option 2
Change recursive_function to also accept a std::function. Update its implementation to call the std::function with the value of the node appropriately. Use a lambda function that can be converted to a std::function that recursive_function accepts in the call to the function. Take care of calling push_back on the vector in the lambda function with the argument passed to it.
void recursive_function(node* p, std::function<void(int)> f)
{
// When appropriate...
f(p.data);
}
and use it as
void vector_function(){
std::vector<int> v;
recursive_function(p, [&v](int e) -> void { v.push_back(e); });
}
Related
Suppose I have the following function:
void sum(const std::vector<int*>& input) {
return ... ; // the sum
}
I store a vector of int pointers somewhere
...
std::vector<std::unique_ptr<int>> my_ints;
Is there a way to pass my_ints to sum() without any extra allocations such as an intermediate vector of the unique_ptrs converted to a vector of raw pointers?
Obviously, I could refacor sum() to take a vector of unique ptrs instead. Or overload it. But I'm hoping to find a way where I don't have to, and let the user decide whether or not to use a vector of unique_ptrs or raw pointers.
Not like you want, but you should think about sum() differently. It looks like an algorithm that operates on a range, so you should make it more like this:
template <typename It>
ValueType sum(It begin, It end) {
// ... iterate and calculate sum
return sum;
}
Then suddenly, you can start to use ranges to do cool things!
std::vector<std::unique_ptr<int>> my_ints;
auto range = my_ints | ranges::views::transform
(
[](auto smart_ptr) {
return smart_ptr.get();
}
);
This is a range that will transform as you use it! Then you could enter it into your sum() like this:
auto my_sum = sum(std::begin(range), std::end(range));
Also look up std::accumulate(), which does what you want here, I would say.
No, there is absolutely no way to pass those pointer values to that sum method without changing the method.
I have a vector variable named intVec, and I have a function named pushBack, that accepts a vector of type integer just like intVec, but when I actually pass that vector into the function in order to push_back the x parameter, nothing seems to happen.
Output expected from intVec.size() is 1
Output given from intVec.size() is 0
I'm genuinely confused as to what I'm doing incorrectly here.
Perhaps I'm missing something extremely obvious.
#include <vector>
std::vector<int> intVec;
void pushBack(int x, std::vector<int> vec) {
vec.push_back(x);
}
int main() {
pushBack(10, intVec);
std::cout << intVec.size();
}
That is because you pass the vector by value instead of by reference (or pointer).
This means, that when you call the function, the vector you call 'push_back' on is actually an independent copy of the original vector, which get deallocated upon leaving the function.
Try this header instead:
void pushBack(int x, std::vector<int> &vec) {
vec.push_back(x);
}
The & tells the compiler to pass by reference, meaning that whatever you do to vec, you also do to the vector you originally passed.
Write pushBack as below:
void pushBack(int x, std::vector<int>& vec) {
vec.push_back(x);
}
The only difference is that here vec is being passed by reference. In your code it is being passed by value.
So I dont understand how to use inserters in this situation. I know what are inserters, I know about std::front_inserter and std::back_inserter and std::inserter but I am confused about this problem which I will present now.
I need to make function, which will transform elemets of vector and put them in deque(or vector nevermind, its "generic" function anyway).
That function has 5 parameters, which one of them is another function(which can have only one parameter, it is not specified what type(i mean it can be reference,iterator,pointer...... whatever)).
If my vector is:
std::vector<int> v={1,2,3,4,5};
I need to make some modification, with lambda function, which will make my deque have elements like this:
25 16 9 4 1
So you see that first element of deque is last element of vector ^2 (you can see what I want to do).
So my question is:
How can the problem be done using inserters? I mean should I somehow put inserter in lambda fucntion? Maybe lambda should be like this:
[](int x) {
x=x*x;
std::front_inserter(q);
}
I was thinking about this but then I dont understand how will this lambda work when I send it as parameter of this "big" function? How it will know what is q inside big function?
I hope you understand what I want to do.
Here is example.
So I have to make some function, and this is prototype(lets say it is void):
typename<template Type1, template Type2>
void Fun(Type1 p1,Type1 p2,Type2 p3,Type2 p4,void (*f)(std::remove_reference<decltype(*p1)>::type) );
Lets say that I have the following code in main:
int main() {
std::vector<int> v={1,2,3,4,5};
std::deque<int> d(5);
Fun(v.begin(),v.end(),d.begin(),d.end(), /* some lambda function */);
If you're only interested in the transformation, not in implementing a function with that type,
std::deque<int> d;
std::transform(v.begin(), v.end(), std::front_inserter(d), [](int x){return x * x;});
or
std::deque<int> d;
std::transform(v.rbegin(), v.rend(), std::back_inserter(d), [](int x){return x * x;});
I have an Eigen::Matrix and I would like to generate a new matrix where all its elements are generated by the some function call to the elements of the matrix:
Matrix< Foo,2,2 > m = ...;
Matrix< int, 2, 2> new_m;
for each m[i][j]:
new_m[i][j] = m[i][j].member_of_foo_returns_int()
I had a look on Eigen::unaryExpr but the elements changed and the return have to be the same. However, I have Foo objects in the first matrix, and an int returned in the new matrix. Is this possible without a vanilla loop?
You can pass a lambda expression to unaryExpr, like so:
Eigen::Matrix<int,2,2> new_m = m.unaryExpr(
[](const Foo& x) {
return x.member_of_foo_returns_int();
});
If you can't use c++11, you need to write a small helper function:
int func_wrapper(const Foo& x) {
return x.member_of_foo_returns_int();
}
and pass that using std::ptr_fun:
Eigen::Matrix<int,2,2> new_m = m.unaryExpr(std::ptr_fun(func_wrapper));
For calling member functions there is actually a nice helper function already implemented named std::mem_fun_ref (this takes a member function pointer and returns a functor object which is accepted by unaryExpr):
Eigen::Matrix<int,2,2> new_m = m.unaryExpr(
std::mem_fun_ref(&Foo::member_of_foo_returns_int));
All these variants are type safe, i.e., trying to store the result in a non-int-Matrix will not compile.
I am learning recursion in c++ and was stuck on why you cant simply use the .push_back() instead of creating a function to copy the specific_previous_result elements, then .push_back().
vector<vector<int>> get_every_n_elements(vector<int> arr, int n) {
if (n == 0) {
vector<vector<int>> result;
vector<int> empty_list;
result.push_back(empty_list);
return result;
}
vector<vector<int>> previous_result = get_every_n_elements(arr, n - 1);
vector<vector<int>> current_result; //empty
for (auto specific_previous_result : previous_result) { // [[]] -> []
for (auto elem : arr) { // [1,2,3,4] -> 1
//current_result.push_back(specific_previous_result.push_back(elem));
//This does not work^^
current_result.push_back(group(specific_previous_result, elem));
//The group function copies all elements to newVec and push_back(elem) after
//Then returns newVec with elem at the end
}
}
return current_result;
}
The error that I get when I run the push_back line is error: invalid use of void expression current_result.push_back(specific_previous_result.push_back(elem));. Thank you for your help.
There doesn't seem to be a valid reason to return the vector itself after a push_back. Sometimes it's useful, but most of the time, it is not. I would recommend writing it in two lines, which is also more clearer IMO than a separate (and inefficient!) function:
current_result.push_back(specific_previous_result);
current_result.back().push_back(elem);
The reason why that line is causing the compiler to give you the invalid use of void expression current_result.push_back(specific_previous_result.push_back(elem)); error is trivial. Take a look at the line in question:
current_result.push_back(specific_previous_result.push_back(elem));
The bolded part is calling the vector's push_back function, a function which has a void return type. You are attempting to pass this void return value as a parameter to current_result.push_back.
See the documentation for std::vector::push_back. As you can see, the return value for both overloads is void.
You said it yourself, your group function is returning a vector which you are then pushing onto the back of your current_result vector. This is why the line which uses the group function compiles.