creating a two dimensional std::vector - c++

I want to create a two-dimensional vector where the first dimension is constant by the second dimension is different, for example
int const mysize = 3;
int vecSizes[3] = {7, 2, 10};
vector<vector<int>> out_buff(mysize);
I want my inner vectors to be according to the sizes in vecSizes as the following
out_buff[0] // has size 7
out_buff[1] // has size 2
out_buff[2] // has size 10
I do not want to use push_back or resize because it takes time when using large vectors, is there a way to do that?

Elements in a std::vector have to be constructed, so in order to create the vectors of the size you want, you will have to use push_back or resize (preferably resize because it only will perform 1 allocation)
One alternative could be instead of actually changing the size, just calling reserve, which just allocates memory but doesn't actually insert any elements. The reported size will still be zero, but capacity will return at least what was passed to reserve.

Here is a complete program with minor modifications to OP's code. Note the assertions (i.e. verifications) of the sizes and capacities.
#include <vector>
#include <cassert>
using namespace std;
int main() {
enum {N = 3};
int const vecSizes[N] = {7, 2, 10};
vector<vector<int>> out_buff{N};
assert(out_buff.size() == N);
assert(out_buff.capacity() == N);
for (int i = 0; i != N; ++i) {
out_buff.at(i).reserve(vecSizes[i]);
}
int i = 0;
for (auto const& vec : out_buff) {
assert(vec.size() == 0);
assert(vec.capacity() == vecSizes[i++]);
}
}
Live example: http://ideone.com/ikm1LR

Related

Getting the length of an array when passed to another function

int *getNewArray(int arr[])
{
int newArray[15];
int len = sizeof(arr) / sizeof(arr[0]);
std::cout << len;
return newArray;
}
int main()
{
int arr[3] = {1, 2, 3};
int * newArr = getNewArray(arr);
return 0;
}
Why is the sizeof(arr) / sizeof(arr[0]) returning me 2 instead of 3? What is the right way to get the length of the passed array?
You have two problems:
Firstly, your array has automatic storage. Automatic objects are destroyed automatically at the end of scope. As such, the array no longer exists after the function returns. You return a pointer to the first element of array that does not exist after the function. The returned pointer is always invalid and therefore useless.
Secondly, there is no general way to know the size of the pointer based on a pointer to element of that array. Typically, you would pass the size of the array along with the pointer.
sizeof(arr) = 8 (on 64 bit system). Its a plain pointer
sizeof(arr[0]0 = 4 (if int is 32 bit)
hence the 2.
use std::vector or std::array
I guess the Optimized code will look something like this , maintaining the actual functionality as it is by using std::vector.
For more details I will recommend this link Vector in C++.
#include<iostream>
#include<vector>
using namespace std;
vector<int > getNewArray(vector<int >& arr)
{
int *newArray = new int[15];//creating an array of size 15 in heap
int len = arr.size();
std::cout << len;
return newArray;
}
int main()
{
vector<int > arr = {1, 2, 3};
vector<int > newArr = getNewArray(arr);
return 0;
}

What is the recommended way loop through an array in C++?

I'm learning C++ (reasonably confident in JavaScript) and I can't find a C++ equivalent to the JS array.length;. I want a simple way to loop through an array based on the array length?
I have followed a number of tutorials but all seam to require the array length to be manually stated in the for loop (or pushed into the function)?
Below code gets an error and adding the #include causes a compiler error (DEV++).
Is there a C++ or reason why there is no simple call of the array length?
#include <iostream>
using namespace std;
int main () {
int shoppingList [3] = {1, 2, 3};
for (int i=0; i < shoppingList.size(); i++) {
cout << shoppingList[i] << endl;
}
}
For a C-style array like you have you can use range-based for loops:
for (int value : shoppingList)
{
std::cout << value << '\n';
}
As for getting the number of elements from an array, there's a "trick": You know the size of the array itself, and you know the size of each element in the array. That means if you divide the size of the array with the size of each element, you will get the number of elements.
In short
size_t numberElements = sizeof shoppingList / sizeof shoppingList[0];
Important note: This "trick" only works with actual arrays! Once an array have decayed to a pointer (to its first element, which often happens) all you're left with is the pointer. There's no way to get the size of the memory it points to, and this "trick" can not be used.
And as mentioned in my comment, the "best" solution is to use either std::array or std::vector.
Built-in types don’t have member functions with C++. However, there is a non-member std::size(array) function:
for (std::size_t i{}; i != std::size(shoppingList); ++i) {
// ...
}
Note that the counter is usinf std::size_t to match the signedness of the result of std::size(...). Also, do not use the sizeof hack suggested in other answers: it is a trap! The cde will happily compile when passing pointers to it but it will also produce the wrong result.
Of course, the idiomatic way to iterate over a range in C++, including arrays, is (assuming you only need the values and not their position):
for (int val: shoppingList) {
// ...
}
Array doesn't have a direct size() member function, you can find the size of an array like this int size = sizeof(arr)/sizeof(arr[0]); and use it in the for loop.
#include <iostream>
using namespace std;
int main () {
int shoppingList [3] = {1, 2, 3};
int size = sizeof(shoppingList)/sizeof(shoppingList[0]);
for (int i=0; i < size(); i++) {
cout << shoppingList[i] << endl;
}
}
You can do something like, sizeof(A)/sizeof(A[0]). This would give you the total number of elements in the array.
Let's take an example A = {1,2,3,4,5} // all ints
If you evaluate sizeof(A)/sizeof(A[0]), it would give you 5 and as you see, you would not need to manually enter the size of the array.
Hope this helps. :)
#include <iostream>
using namespace std;
int main()
{
A = {1,2,3,4,5};
for (int i = 0; i< sizeof(A)/sizeof(A[0]); i++)
//whatever you want to do with this
return 1;
}

How to remove integers in array less than X in C++?

I found the same question for PHP and I tried to do the same in C++.
I tried following:
// returns new array with numbers lower then "number", len is set to
// new length.
int * filter(int array[], int &len, int number) {
int cnt = 0;
for (int i = 0; i < len; i++) {
if (array[i] < number) {
cnt++;
}
}
int *ret = new int[cnt];
cnt = 0;
for (int i = 0; i < len; i++) {
if (array[i] < number) {
ret[cnt] = array[i];
cnt++;
}
}
len = cnt;
return ret;
}
This function will create a new array with the integers that are lower than the integer number. I tried to bypass the problem that I don't know how long the new array should be.
Is there any better way to solve this problem?
Yes, use std::vector type. It will automatically handles allocations for you each time you push value to it (using push_back method).
Example
#include <iostream>
#include <vector>
int main() {
std::vector<int> a;
a.push_back(1);
a.push_back(2);
for (int value : a) {
std::cout << value << '\n';
}
}
It's also a good idea to avoid new syntax, as it doesn't automatically deallocate, unlike std::vector.
Also, while this is unrelated to question, C++ provides a function that does what you want already called std::copy_if.
std::remove is the algorithm you're looking for.
#include <iterator>
#include <algorithm>
int main()
{
int array[4] = {1, 42, 314, 42};
// If you only know `array` as a pointer, and `len`, then
// `std::begin(array)` becomes `array`, and
// `std::end(array)` becomes `array + len`.
auto end = std::remove(std::begin(array), std::end(array), 42);
// Now `end` points to the "new end" of the array.
// And `std::distance(std::begin(array), end)` is the "new length".
}
It moves all matched elements (42 in the example) to the end of the array. When inspecting array after std::remove runs, you get {1, 314, 42, 42}, and end points past the last nonmatching element (the first 42 in this case).
It's also possible to copy the nonmatching elements to another array using std::remove_copy, or std::copy_if, but in order to do this, you'll have to allocate another array of elements. At this point, you're better off using a dynamic growing array such as std::vector. In that case, use std::vector::erase like here in the answers with std::remove.

How to remove the elements of an array within a certain range

I have a one-dimensional array of size 10. I want to remove the elements from 5 to 8. Can somebody give me an example of how to do it? This is how I defined my array but I have no idea about how to start.
#include <iostream>
#include <iomanip>
using namespace std;
int array[10] = {1,2,3,4,5,6,7,8,9,10};
So, the output should be 1,2,3,4,5,10. (index 0 = element 1)
Thanks
An alternative to arrays is to use a vector. In this case you can do:
#include <vector>
// create vector for integers
std::vector<int> v;
// set values from 1 to 10
for (int i=1; i<=10; i++)
v.push_back(i);
// erase from 5 to 8
v.erase (v.begin()+5, v.begin()+9);
BTW, if your compiler supports C++11, you can initialize your vector as:
std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
In the above case, its an array of 10 elements array[10]. As the array size is fixed, it may not be possible to remove an item from the array.
Rather, you can assign null or someother value to the corresponding element.
BTW, I would rather use, std::list or std:: vector instead of array.
Anyhow, If you mean to get rid of that element, you'd need to shift all the ones to the right of that element one to the left:
for (int i = index; i < /* length */; i++)
array[index] = array[index+1];
array[length-1] = 0;
You can't literally remove them because C++'s built-in arrays (like C's) are fixed-size.
What you can do is overwrite them with the values that come after them, and then (if you want to) zero out the four now-extra positions at the end of the array. e.g.:
// copy latter values over the values we don't want
for (int i=4; i<6; i++) array[i] = array[i+4];
// zero out the no-longer-necessary values at the end, just so they won't appear valid anymore
for (int i=6; i<10; i++) array[i] = 0;
and then when printing the array, print only the first 6 values rather than all 10, since your array is (conceptually, even if not actually) "shorter" now.
Not sure what exactly you want your output to be, so I'm just providing another possible solution here:
// your input
int array[10] = {1,2,3,4,5,6,7,8,9,10};
// 1. put all invalid element in the back of the array
// "it" points to the first invalid element
int* it = std::remove_if(std::begin(array), std::end(array),
[](int e)
{
return (e >= 5) && (e <= 8);
});
// 2. then, mark them as -1 (from "it" to the last element)
std::transform(it, std::end(array), it,
[](int e) -> int
{
return -1;
});
// now the array contains:
// {1,2,3,4,9,10,-1,-1,-1,-1}

Concatenation of vectors [duplicate]

This question already has answers here:
Appending a vector to a vector [duplicate]
(4 answers)
Closed 9 years ago.
My apologies for the title, I did not know of a better one.
So, basically, I have a 1D vector, which I extract 256 pieces of data from this, until there is no more data left.
std::size_t begin = 0;
std::size_t nextEnd = 0;
while (nextEnd < signal.size()) {
begin = nextEnd;
nextEnd += 256;
Transform(signal, begin, std::min(nextEnd, signal.size()));
}
Inside the "Transform" function, there is a new, temp vector created called temp_vector and inside my main I have a global 1D vector.
What I want to do is, every iteration of this loop, the values of the temp_vector is pushed back into the global 1D vector at the right position.
So for example:
std::vector<double> global;
std::vector<double> actual = {1,1,0,0,2, 3, 4 ....., n};
// here loop over n number of elements
// TRANSFORM:
// std::vector<double> temp_vector = {10, 50}; // after calculations
// global.push_back(temp_vector);
So at the end result, the global_vector will still be a 1D vector, however, will contain all of the values, in the same place for each of the elements.
I hope I have explained myself enough!
Here is code for array merging:
#include <vector>
#include <iostream>
int main() {
std::vector<int> glob = {1, 2, 3};
std::vector<int> temp_vector = {4, 5, 6};
glob.insert(glob.end(), temp_vector.begin(), temp_vector.end());
std::vector<int>::const_iterator it = glob.begin();
for(; it != glob.end(); ++it) {
std::cout << *it << ", ";
}
return 0;
}
Output:
./a.out
1, 2, 3, 4, 5, 6,
Consider to use an ordered container like std::set or std::priority_queue and insert into that container directly, not using a temporary.