Replacing subvector in a vector - c++

I have
vector<int> my_vector;
vector<int> other_vector;
with my_vector.size() == 20 and other_vector.size() == 5.
Given int n, with 0 < n < 14, I would like to replace the subvector (my_vector[n], myvector[n+1], ..., myvector[n+4]) with other_vector.
For sure with the stupid code
for(int i=0; i<5; i++)
{
my_vector[n+i] = other_vector[i];
}
I'm done, but I was wondering if is there a more efficient way to do it. Any suggestion?
(Of course the numbers 20 and 5 are just an example, in my case I have bigger size!)

In C++11, a friendly function std::copy_n is added, so you can use it:
std::copy_n(other_vector.begin(), 5, &my_vector[n]);
In C++03, you could use std::copy as other answers has already mentioned.

You could use std::copy:
// Get the first destination iterator
auto first = std::advance(std::begin(my_vector), n);
// Do the copying
std::copy(std::begin(other_vector), std::end(other_vector), first);
Although this basically is the same as your naive solution.

I dont know about performance, but a cleaner version would be to use std::copy
std::copy(other_vector.begin(),other_vector.end(),my_vector.begin()+n);
For min-max performance, perhaps(?) memcpy is the answer..
memcpy(my_vector.begin()+n, other_vector.begin(), sizeof(int) *other_vector.size());

Related

Range-based for loop on arrays

I'm trying to do something similar to this:
int iArray[16];
int iOtherArray[16];
for ( auto &i: iArray )
{
iOtherArray[i] = iArray[i];
}
Where the for loops through the number of components the array has, not each individual component. Am I understanding the usage for Range-based for loops correctly?
You can just use the copy algorithm from the standard library:
std::copy(array, array+16, otherArray);
No, the range -based loop will give you the element values, not indexes.
For a copy operation like this a range-based loop is a poor choice as you have to keep track of two ranges and want cooresponding elements of each. Just use a normal for loop for this.
for(int i = 0; 16 > ndx; ++ndx)
otherArray[i] = array[i];

How to initialize dynamically created large integer array to a specific integer in C++?

I have created an array R like this:
int * R = new int[n];
where n takes a large value, say 100,000. I want to initialize all the integers of the array to 1 in C++. What is the best/fastest way to do this? Or, is looping through the whole array the only option?
"What is the best/fastest way to do this?"
In C++ you use std::vector<int> R(n,1); instead.
If you need the int* elsewhere, you refer to R.data().
You can std::fill from STL:
std::fill(R, R + n, 1);
But I suggest you to use std::vector instead:
std::vector<int> R(n, 1);
Don't use memset(R, 1, sizeof(int) * n), because it assigns 1 to each byte (not element) of the array.
for(int i = 0; i < n; i++){
R[i] = 1;
}
//don't forget to "delete[] R;"!
You can use vectors:
std::vector<int> R(n, 1);
But arrays and loops are best friends, in case you can't use vectors. Although the use of vector is recommended since manual deallocation is handled by the class.

Find n largest values in a vector

I currently have a vector and need to find the n largest numbers in it. For example, a user enters 5, i gotta run through it and output the 5 largest. Problem is, i can not sort this vector due to other constraints. Whats the best way to go about this?
Thanks!
Based on your description of not modifying the original vector and my assumption that you want the order to matter, I suggest std::partial_sort_copy:
//assume vector<int> as source
std::vector<int> dest(n); //largest n numbers; VLA or std::dynarray in C++14
std::partial_sort_copy(
std::begin(source), std::end(source), //.begin/.end in C++98/C++03
std::begin(dest), std::end(dest),
std::greater<int>() //remove "int" in C++14
);
//output dest however you want, e.g., std::copy
Is copying and sorting an option? I mean if your application is not that performance critical, this is the simplest (and asymptotically not too bad) way to go!
Something like this (A is incoming vector, N the number largest you want to find, v becomes the result vector):
vector<T> v(N, 0);
for each element in A:
if (element > v[N-1])
for(i = N-1; i > 0 && v[i] < element; i--)
v[i] = v[i-1];
v[i] = element;
This is some sort of "pseudo-C++", not exactly C++, but hopefully describes how you'd do this.

Convert two vectors of int with the same length into one vector of pairs of int in C++

In C++, if I have two vectors of int:
A = [1, 2, 3 ,4];
B = [1, 2, 3, 4];
How can I merge them into one vector of pairs:
[(1,1), (2,2), (3,3), (4, 4)]
Of course I can do that with a loop. But can we do that using suitable STL functions and iterators?
You can use an algorithm for this:
std::vector<std::pair<int, int>> target;
target.reserve(A.size());
std::transform(A.begin(), A.end(), B.begin(), std::back_inserter(target),
[](int a, int b) { return std::make_pair(a, b); });
I agree that Dietmar Kühl's answer does exactly what was asked in the question, but I also agree with Kakadur's comment. A loop is hidden in std::transform() so the complexity is the same. Some people will judge, but if there is no direct proof of one way being better than the other, I tend to choose the most readable and least verbose version:
// create a vector of length of the smaller vector
std::vector<std::pair<int, int>> target( A.size() < B.size() ? A.size() : B.size() );
for (unsigned i = 0; i < target.size(); i++)
target[i] = std::make_pair(A[i], B[i]);
P.S.
The code above allocates just enough space for the target vector, so that the potential overhead of push_back (in case of reallocation) can be avoided.

C++: How to pick out last quarter of elements in a vector?

What is the best way to pick out the last quarter of the elements in a vector containg N elements?
size_t n = src.size();
std::vector<int> dest(src.begin() + (3*n)/4, src.end());
dest contains the last quarter elements from the source vector src.
You can also use std::copy from <algorithm> header file as,
std::vector<int> dest_copy;
std::copy(src.begin() + (3*n)/4, src.end(), std::back_inserter(dest_copy));
See the online demo at ideone : http://ideone.com/qrVod
I think, you may want to work more on the expression (3*n)/4. Like when n is say 5, you want to pick 1 element only, but when n is 7, you may want to pick 2 instead of 1. So this decision is upto you. My solution just tells you how would you copy the elements, once you decide exactly how many!
Something like this, I guess:
size_t lastQuarter = myVector.size() * 3 / 4;
for (size_t i = lastQuarter; i < myVector.size(); i++)
{
doSomething(myVector.at(i));
}