Using Vectors with functions, Pointer Issues - c++

I have gotten myself completely muddled up and confused when it comes to these points and vectors.
I have two functions
vector<int>& add(vector<int>& num1, vector<int>& num2){
vector<int> ansVec;
....
return ansVec;
}
and
vector<int>& multiply(vector<int>& num1, vector<int>& num2){
...
return add( multiply(num1, num2), multiply(num1, num2));
}
The issue seems to be that I'm returning a reference to a local variable.
How could I pass the entire vector, and not just the reference?

you cannot always return by reference,
here are some solutions to your problem :
1) put the result in a container parameter:
void add(vector<int>& num1, vector<int>& num2 ,vector<int>* result)
and fill the result vector with the result of the computation
2) return by value :
vector<int> add(vector<int>& num1, vector<int>& num2);
note that here you actually copy each element from the temporary vector you will use for the computation, to the returned vector
3) return a pointer (or a some kind of smart pointer) to a vector allocated on heap
vector<int>* add(vector<int>& num1, vector<int>& num2)
{
vector<int>* res = new vector<int>();
...
return res ;
}
note that here the clients of this code must not forget to delete the vector
or , for example with boost::shared_ptr , or std::shared_ptr if you have c++11:
shared_ptr<vector<int>> add(vector<int>& num1, vector<int>& num2)
{
shared_ptr<vector<int>> res (new vector<int>());
...
return res ;
}

I think you'll be better off using std algorithms for carrying our addition/multiplication of vector e.g. use std::transform for adding two vectors or for multiplication
//Add vec1 and vec2 and store the results in result vec
//Note: take care of the ranges of two sources/destination
transform(vec1.begin(), vec1.end(), vec2.begin(), result.begin(), std::plus<int>());
Issues with your code:
returning reference of the local variable
multiply doesn't have a terminating condition.

In C++11, life is easier. Just return by value. It will automatically apply move semantics as opposed to copy semantics. Copying vectors is expensive, but moving them is cheap. Do not bother with pointers or references unless you are willing to profile your code and prove that it is a bottleneck. Using a pointer or reference here obfuscates code, and is a premature optimization.
See this talk: https://www.youtube.com/watch?v=xnqTKD8uD64. He takes up this exact issue, and recommends return by value for any type that is cheap to move.
Edit: when I say don't bother with references/pointers, I mean for returning. Passing in a const ref to a vector for input arguments, and a non-const ref to a vector for an in/out argument, is standard and good practice.

Related

C++ | STL Sort() Function Third Argument Complexity confusions

Suppose, we have a 2D vector<vector<int>> vec;
We need to sort this 2D vector. I tried with two methods below:
Method 1: Using a comparator function
static bool cmp(vector<int> a, vector<int> b) {
return a[1] < b[1];
}
...
sort(vec.begin(),vec.end(),cmp);
Method 2: Using a lambda
sort(vec.begin(), vec.end(), [](const vector<int>& a, vector<int>& b) {
return a[1] < b[1];
});
For a problem from leetcode, Method 1 caused a "Time Limit Exceeded" verdict, while Method 2 was accepted.
Can there be that much contrast between these two methods in terms of time complexity?
vector<int> a makes a copy of the vector while const vector<int>& a just passes the address. Huge difference.
Your comparator is taking its parameters by value, which means every vector object that sort() passes to cmp() will have to be copied in memory. That increases time complexity and memory usage, multiplied out by however many elements are actually in your vectors.
Your lambda, on the other hand, is taking its parameters by reference instead, which means every vector object that sort() passes to the lambda will have only its current memory address passed, no copies are made. So there is no increase in time complexity.
Simply update your comparator to take reference parameters, and then the two methods will have similar complexity:
static bool cmp(const vector<int> &a, const vector<int> &b) {
return a[1] < b[1];
}

permutation in C++

class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int> > result;
vector<int> sofar;
permutehelper(nums, sofar, result);
return result;
}
void permutehelper(vector<int> &rest, vector<int> &sofar, vector<vector<int>> &ans){
if(rest.size() == 0) {
ans.push_back(sofar);
}
else{
for(int i = 0; i < rest.size(); i++){
sofar.push_back(rest[i]);
rest.erase(rest.begin() + i);
permutehelper(rest, sofar, ans);
}
}
}
};
How do I modify it to return all permutation, Currently it is giving only [[1,2,3]]. I know there are many solutions but I want to make it work using vectors sofar and rest.
You only have one rest vector (and only one sofar vector) because you are passing by reference. That means that when you remove an element from rest, it's gone. You never put it back, so it's gone forever. (In fact, you're removing elements from the vector passed as an argument to permute. Some would say that modifying the argument is poor interface design.)
You probably want to pass the parameter vectors by value (other than ans, which accumulates results and thus should be permanently modified). Of course, passing by value makes copies, which introduces an unnecessary quadratic complexity, but it will allow the algorithm to work as expected.

Use of * and & together in function signature

I was playing through c++ and trying to understand vector and its signature .
In below method printPrimes I need to use pointer with address of why ?
Is vector<int> &primes not enough as from main method printPrimes is already sending address .
void printPrimes(long long l, long long r, vector<int>* &primes) {
// some code
}
vector<int>* sieve() {
vector<int> *prime = new vector<int>();
return prime;
}
int main() {
vector<int> *primes = sieve();
printPrimes(l, r, primes);
return 0;
}
I need to use pointer with address of
Here, & does not mean "address of"; it means the type "reference to".
It's clearer if you write it not like this:
vector<int>* &primes
but like this:
vector<int>*& primes
Though the choice of whitespace is artificial, that better documents that this & is "part of the type".
Have some types:
std::vector<T> = A vector of Ts
std::vector<T>& = A reference to a vector of Ts
std::vector<T>* = A pointer to a vector of Ts
std::vector<T>*& = A reference to a pointer to a vector of Ts
std::vector<T>*** = A pointer to a pointer to a pointer to a vector of Ts
std::vector<T>**& = A reference to a pointer to a pointer to a vector of Ts
…and so forth.
As for why you need a vector<int>*& for printPrimes to do its job, we could not tell you without actually being able to see it. I will say that it seems unlikely it needs a pointer at all, and that if it wants to modify that pointer it's going to cause problems with the new and delete in the calling scope.
In fact, all that dynamic allocation is completely pointless and only complicates things.
The following was likely intended instead:
void printPrimes(long long l, long long r, vector<int>& primes) {
// some code
}
vector<int> sieve() {
vector<int> prime;
return prime;
}
int main() {
vector<int> primes = sieve();
printPrimes(l, r, primes);
}
vector<int>* &primes parameter has to be read this way:
Reference to a pointer of vector of int
and not
Address of a pointer of vector of int (which, you are right, would be useless)
Passing by reference allows to directly manipulate any instance outside of scope (like with pointers, but a safer way since a reference cannot be nullptr, and its existence is auto-managed (no need to delete)).
In c++ & in function parameter used to pass parameter by reference. vector<int>* &primes declares primes to be a reference to a pointer to vector<int>.
If printPrimes means to print only the vector passed to the function then the signature
void printPrimes(long long l, long long r, vector<int> &primes);
can also do the job.
Reference to a pointer is needed when the pointer passed to the function is need to be modified and it's effect is expected to seen in the caller function.
void foo(int*& p){
p = new int[10];
// rest of the code
}
if a function bar is calling foo like
void bar(/* some parameters */){
// ...
int *p;
foo(p);
// rest of the code
}
foo is modifying the pointer itself and this modification will be seen to bar also and memory allocated to p can be accessed from bar.

Return a dynamic array

So I want to make an executable with three functions:
This would be an example:
float vec(int opt, int t)
{
int i;
float * v = new float[t];
// Do stuff with v
return * v;
}
}
It gets arguments opt and t from main. Then main needs to get v back to use it in another function.
What is the best way to do this?
The return type of vec should be float *, and your return statement should be return v. Dereferencing v with * just gives you the first element of the array.
I'll note that this kind of design is bad style. It relies on the caller to free the dynamically allocated array. It would be better to have the caller create an array and pass it by reference to vec, or have vec return a different container statically. #Mat suggested std::vector; that's probably a good choice.
You also have an extra } at the end of your function. Get rid of it.
Well, your signature says that the function returns a single float, not an array of floats. To answer your question directly...
float *vec(int t)
{
float * v = new float[t];
// Do stuff with v
return v;
}
What is the best way to do this?
Well that's a different question entirely. The "best" way would be to return a std::vector<float> and avoid manual memory management altogether.

What should be returned?

I am new to the programming so I don't know how to describe the problems encountered precisely.
Here is the declaration of the function
vector<int>& operator>>(vector<int>& v, int& x){
}
I am just wondering what should be returned for this function.
I am trying to implement the operator >> for the vector class if that is relevant at all to my question.
Thanks for the help
In this case you're probably trying to chain operations: vec >> int1 >> int2;. That means you should return the first parameter so that it can be used in the next call.
vector<int>& operator>>(vector<int>& v, int& x){
x = v.back();
v.pop_back();
return v;
}
vector<int>
Should be returned. If you return vector<int>& then you can't return a new vector, else it will be destroyed going out of scope when the function finishes and the reference will be invalid. If you return the inputted vector v then you will need to mofify it, which is unwise.