A good way to construct a vector of 2d array - c++

What I want to do is
double A[2][2] = {
{4, 7},
{2, 6}
};
std::vector<double[2][2]> B;
for (int i = 1; i <= 5; i++)
{
B.push_back(A);
}
But C++ cannot store an array in std::vector, what is the proper (speed) way to do that? Is A[2][2] faster than std::arraydue to cache coherency?

std::array is probably the best way to go here. It should preform nearly identically to the C style array you've got:
#include <array>
#include <vector>
int main() {
using Array2d = std::array<std::array<double, 2>, 2>;
Array2d A = {{{4, 7}, {2, 6}}};
std::vector<Array2d> B;
for (int i = 1; i <= 5; i++) {
B.push_back(A);
}
}

Related

How to push_back() C array into std::vector [duplicate]

This question already has answers here:
Correct way to work with vector of arrays
(4 answers)
Closed 2 years ago.
This doesn't compile:
vector<int[2]> v;
int p[2] = {1, 2};
v.push_back(p); //< compile error here
https://godbolt.org/z/Kabq8Y
What's the alternative? I don't want to use std::array.
The std::vector declaration on itself compiles. It's the push_back that doesn't compile.
You could use a structure containing an array, or a structure containing two integers, if you really don't want to use std::array:
struct coords {
int x, y;
};
vector<coords> v;
coords c = {1, 2};
v.push_back(c);
alternatively, as mentioned, you could use a structure containing an array:
struct coords {
int x[2];
};
vector<coords> v;
coords c = {1, 2};
v.push_back(c);
Use std::array:
vector<std::array<int, 2>> v;
std::array<int, 2> p = {1, 2};
v.push_back(p);
I think you should check the C++ reference for vectors.
http://www.cplusplus.com/reference/vector/vector/vector/
You can see in the example, there is explained every way you can initialize a vector.
I think that for your case you need to do:
std::vector<int> v({ 1, 2 });
v.push_back(3);
As an alternative, as you explicitly state that std::array is not to be used, you could use pointers, it's kind of an oddball solution but it would work:
#include <iostream>
#include <vector>
int main()
{
const int SIZE = 2;
std::vector<int*> v;
static int p[SIZE] = {1, 2}; //extended lifetime, static storage duration
int *ptr[SIZE]; //array of pointers, one for each member of the array
for(int i = 0; i < SIZE; i++){
ptr[i] = &p[i]; //assign pointers
}
v.push_back(*ptr); //insert pointer to the beginning of ptr
for(auto& n : v){
for(int i = 0; i < SIZE; i++){
std::cout << n[i] << " "; //output: 1 2
}
}
}

How to declare a static 2D array within a function in C++?

I need to declare a 2D array within a function and call the function repeatedly but the array should be declared only once at the beginning.
How can I do this? I'm new to this.
thanks in advance
Static Variables inside Functions
Static variables when used inside function are initialized only once, and then they hold there value even through function calls.
These static variables are stored on static storage area, not in stack.
consider the following code:
#include <iostream>
#include <string>
void counter()
{
static int count[][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
static int index = 0;
std::cout << count[index / 3][index % 3];
index++;
}
int main()
{
for(int i=0; i < 9; i++)
{
counter();
}
}
Output:
123456789
void func1()
{
static int myArra[10][20];
}
As Razack mentioned. That is the first way.
and the second way is using std::array so you can accomplish like this.
#include <array>
void fun(){
static std::array<std::array<int, 5>,5> matrix;
}
In C++ you can use a std::array of std::arrays to create a 2D array:
#include <array>
std::array<std::array<int, 3>, 3> arr = { {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}} };
This is a 3 x 3 2D array with each element initialised to 0. The syntax for accessing an element is the same as a C-style 2D array: arr[row][col].
It could be declared static within your function, but it could also be declared within an anonymous namespace at the top of your .cpp file like this:
namespace
{
std::array<std::array<int, 3>, 3> arr = { {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}} };
}
This is generally better practice than static variables. The array is initialised only once before the main thread starts and only functions within your translation unit (your .cpp file) have access to it.
void process(int ele, int index) {
static std::vector<std::vector<int>> xx_vec = {{1,2,3}, {11,12}, {}};
// example:
for (int i = 0; i < xx_vec.size(); i++) {
// add
if (index == i) {
xx_vec[i].push_back(ele);
}
// read
for (int j = 0; j < xx_vec[i].size(); j++) {
std::cout << "xx_vec" << "place:" << i << "," << j << ":" << xx_vec[i][j] << std::endl;
}
}
}

set multiple array variables at the same time (c++)

I'm trying to make an ASCII art using C++, and having some problems in arrays.
Is there any way to set multiple array variables at the same time?
Let me be more specific.
When you initialize an array, you can do this way.
int arr[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
By the way shown above, you can set 10 array variables at the same time.
However, I want to (re) set some of the array variables like this?
a[1] = 3;
a[4] = 2;
a[5] = 2;
a[7] = 2;
Since there is NO rule in the variables, I can't do
for(int i=0; i<10; i++) a[i] = i+1;
fill(n);
I can't use an for statement or the fill, fill_n function, since there is no regularity.
To sum up,
Is there any way to set more than 1 array variables at the same time? (Like the second code snipplet above?
Given a index-value mapping list, and assign it one by one.
template<typename T, size_t N>
void Update(T(&arr)[N], const std::vector<std::pair<size_t, T>>& mappings)
{
for (const auto& mapping : mappings)
if(mapping.first < N)
arr[mapping.first] = arr[mapping.second];
}
int main()
{
int arr[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Update(arr, { {1, 3}, {4, 2}, {5, 2}, {7, 2} });
return 0;
}
As far as I'm aware without a pattern a control structure is kind of redundant, you might be better served reading from a file.
// for user input
int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
for (int i = 0; i < 10; i++) {
cout << "Please input your value for array index " << i << endl;
cin >> arr[i];
}
// for manual input in initalization
int arr[10] = { 0, 3, 2, 2, 2, 5, 6, 7, 8, 9 };
However a better approach might be to read it from a file, http://www.cplusplus.com/forum/general/58945/ Read "TheMassiveChipmunk"'s post there for exactly how to do it.
Assuming you know which indices you will be changing upfront you can use a separate index array:
int ind[4]= {1,4,5,7};
..and an accompanying array with values
int new_val[4] = {3,2,2,2};
The you can use the following for loop to assign the values:
for (int i=0; i<4; i++)
arr[ind[i]] = new_val[i];
You should also use some variable signifying the number of indices to be changed like int val_num = 4 instead of plain number 4.
Changes that are defined in runtime to an array can be easily implemented by using a list to save tuples that represent the changes you want to make. As an example, we can write:
#include <tuple>
#include <list>
#include <iostream>
using namespace std;
typedef tuple <int, int> Change;
int main() {
int a[5] = {1,2,3,4,5};
list<Change> changes;
//represents changing the 2-th entry to 8.
Change change(2,8);
changes.push_back(change);
for(auto current_change: changes)
a[get<0>(current_change)] = get<1>(current_change);
cout << a[2] << '\n';
}
Prints 8.

How to efficiently fill-in a structure with vectors?

I am not expert in C++ but I believe this is not the most elegant solution:
#include <iostream>
#include <vector>
struct coord {
int x;
int y;
};
int main()
{ std::vector<int> a {1,2,3,4,5};
std::vector<int> b {10,20,30,40,50};
int i;
std::vector<coord> loc (5);
for (i=0;i<5;i++)
{ loc[i].x = a[i];
loc[i].y = b[i];
}
return 0;
}
Does anyone has a better solution ?
It looks like you are using C++11. While I'm not 100% sure this should work:
std::vector<coord> loc { {1, 10}, {2, 20}, {3, 30}, {4, 40}, {5, 50} };
What are you trying to accomplish by creating two vectors just to fill one vector? Your method is inefficient when it comes to declaring two independent vectors to assign into one single vector, and also messy. Remove the two vectors and set the values of your vector using brackets
= { {val1,val2} {val1,val2} {val1,val2} }
But if you would like to stick with your vector filling method and HAVE to use a vector, just one one vector that holds both the values of a and b and loop as such
//check to make sure size is even
for(int i = 0; i < vect.size(); i +=2)
{
vect[i].x = a[i];
vect[i].y = a[i+1];
}

Why won't this array initialize?

This is essentially what I'm trying to do, but not the actual source code.
namespace namespace {
int array [3];
}
namespace::array={1,2,3}
my gcc asks for an expression, and I'm not sure of what to do. Must I namespace::array[1]; each individual element?
You can only use an initializer list in a definition:
int array[3] = { 1, 2, 3 };
If you use:
int array[3];
then you need to initialize the array in a function, using
array[0] = 1;
array[1] = 2;
array[2] = 3;
Although it an odd mixture of C99 and C++, gcc allows this:
#include <string.h>
int a[3];
int main()
{
memcpy(a, (int[3]){ 1, 2, 3}, sizeof(a));
}
!
How about namespace ns { int array[3] = {1, 2, 3}; }?
There are several ways:
1) Explicitly set values for each element:
namespace ns {
int array [3];
}
ns::array[0]=1;
ns::array[1]=2;
ns::array[2]=3;
\\ or if they should contain consequtive values:
\\ for (size_t i = 0; i < 3; ++i)
\\ ns::array[i] = i + 1;
2) If you want initialize static array in place of its declaration, then you could move it initializer list as follows:
namespace ns {
int array[3] = {1, 2, 3};
}
3) Use typedef:
namespace ns {
typedef int array_t[3];
}
ns::array_t array = {1, 2, 3};
3) Also you can make some research of std::tr1::array, which may be used as such:
std::tr1::array<int, 3> arr = {1, 2, 3};