C++ 5 dimensional vector? - c++

I am trying to make a 5 dimensional vector and I can’t seem to get it to work.
I know if I need to write a 3 dimensional vector, I could write it in the following way:
vector< vector< vector<string> > > block(27, vector< vector<string> > (27, vector<string>(27)));
Then I call it: block[x][y][z] = “hello”;
I wrote the 5 dimensional vector in the following way and it gives me error.
vector< vector< vector< vector< vector<string> > > > > block(27, vector< vector< vector< vector<string> > > >(27, vector< vector< vector<string> > >(27, vector< vector<string> >(27, vector<string>(27)))));
Can you please tell me how to write a 5 dimensional vector in the right way?
Thanks a lot.

The final vector in your 5 dimensional array does not have a type that it is an array of.
vector< vector< vector< vector< vector > > > >
^^
Here. What is the base vector a vector off?
To make things easy to read a couple of typedefs would be nice:
typedef std::vector<std::string> Dim1;
typedef std::vector<Dim1> Dim2;
typedef std::vector<Dim2> Dim3;
typedef std::vector<Dim3> Dim4;
typedef std::vector<Dim4> Dim5;
Dim5 block(27, Dim4(27, Dim3(27, Dim2(27, Dim1(27)))));

Consider using the Boost Multidimensional Array Library for higher dimensional arrays.
http://www.boost.org/doc/libs/1_43_0/libs/multi_array/doc/user.html
"Boost MultiArray is a more efficient and convenient way to express N-dimensional arrays than existing alternatives (especially the std::vector> formulation of N-dimensional arrays). The arrays provided by the library may be accessed using the familiar syntax of native C++ arrays. Additional features, such as resizing, reshaping, and creating views are available (and described below)."

But you should stop and think if a dictionary would work better. If the data is sparse you'll save a ton of memory.
Create a key using the 5 dimensions, and create only the members you need.

Related

Making an array of pairs of vectors

I'm trying to make an array of pairs of vectors, and in the vectors is another pair of int and float. Here is the code to help explain: pair<vector<pair<int,float> >, vector<float> >[numNodes];
At first I just had an array of a vector of pairs, but now that I changed it to an array of pairs I'm being thrown errors. I think the errors have to do with the placement of make_pair but I'm not sure.
Here is my code, but first, I little more information on what exactly I'm trying to do with the code. I'm working on a school assignment where the goal is to read in a three files of a graph and store it as an adjacency matrix and adjacency list. Right now I'm working on the list. One file has just the connections, another has the weights of the connections, and the last file has the position values of each node. Then I will search the graphs with different search algorithms. The array of vectors was the adjacency list and all the other data types involved in the pair<vector<pair<int,float> >, vector<float> >[numNodes]; were an attempt to store these variables in the list. I know another way of doing this would be to have a Node object with member variables where I can save the nodeID and position values, but I don't know exactly how this would work in terms of adding it into the list. Also would there be advantages to doing this rather than having everything stored in the list?
class AdjacencyList{
public:
pair<vector<pair<int,float> >, vector<float> > *adjList;
int numNodes;
AdjacencyList(int numNodes){//constructor
this->numNodes = numNodes;
adjList = new pair<vector<pair<int,float> >, vector<float> >[numNodes];
}
void addEdge(int sourceNode, int destNode, float weight, vector<float> posVals){
make_pair(adjList[sourceNode].push_back(make_pair(destNode, weight)), posVals);
}
}
And here is the error I'm being thrown:
main.cpp:71:39: error: no member named 'push_back' in
'std::__1::pair<std::__1::vector<std::__1::pair<int, float>,
std::__1::allocator<std::__1::pair<int, float> > >,
std::__1::vector<float, std::__1::allocator<float> > >'
make_pair(adjList[sourceNode].push_back(make_pair(destNode, weig...
Another Error I'm getting after changing the array of vectors to an array of pairs is this:
no member named 'size' in
'std::__1::pair<std::__1::vector<std::__1::pair<int, float>,
std::__1::allocator<std::__1::pair<int, float> > >,
std::__1::vector<float, std::__1::allocator<float> > >'
return adjList->size();
This size function was working before the change, which makes me think these errors are happening because its recognizing it as a pair now instead of an array. Any ideas on how to fix this?
I have no idea what vector of pairs of vectors of pairs of ints and floats and vectors of floats could possibly in any possible way represent, but anyway you could just assign to the pairs of vectors you want to assign to:
#include <vector>
class AdjacencyList{
public:
std::vector<
std::pair<
std::vector<std::pair<int,float>>,
std::vector<float>
>
> adjList;
int numNodes;
AdjacencyList(int numNodes) :
numNodes(numNodes),
// construct the vector with numNodes default-constructred elements
adjList(numNodes) {
}
void addEdge(int sourceNode, int destNode, float weight, std::vector<float> posVals){
// prefer at() instead of [] for error checking
adjList.at(sourceNode) = std::make_pair(
std::vector<std::pair<int, float>>{
// vector of pairs?? anyway:
std::make_pair(
destNode, weight
)
},
posVals
);
}
};
Do not use raw pointers - use std::vector for managing dynamic array. Your code leaks memory allocated by new.
In the first error thrown, the compiler is complaining about a missing method push_back being called. If you look at it, this makes sense because you are trying to call push_back from a pair variable (which does not have implemented any push_back method). And a similar thing goes with the second error: size() is a valid method for the vector class, but here you are calling it from a pointer pointing to an array (check this question for more info).
Instead of an array of pairs, you could use a vector of pairs, or even a set of pairs:
class AdjacencyList{
public:
vector<pair<vector<pair<int,float> >, vector<float> > > adjList;
int numNodes;
AdjacencyList(int numNodes){//constructor
this->numNodes = numNodes;
// no need to initialize the vector
//adjList = new pair<vector<pair<int,float> >, vector<float> >[numNodes];
}
void addEdge(int sourceNode, int destNode, float weight, vector<float> posVals){
// add the new pair <int, float> to the existent vector for this source node
adjList[sourceNode].first.push_back(make_pair(destNode, weight));
// define second value of the outer pair as the parameter variable posVals?
adjList[sourceNode].second = posVals;
// or you wanted to do this? I don't think so :S
make_pair(adjList[sourceNode].first, posVals);
}
}
You could do the same using an outer set instead of vector, and then you would need to change the push_back(...) for insert(...), so that you obtain the benefits of sets of pairs as well.
Actually, if you need to do it using outer arrays, then your code would be fine but changing your AddEdge function to the one proposed above.
I don't really know which is the desired performance of the code, but if you provide more information about it I might be able to help a bit more.
I think you have some inconsistencies in the type declared and the type being added.
You have declared an array (now does not matter whether it is an array, vector, or set) of pairs of vectors. Whereas on your addEdge function you are creating a pair of None (push_back returns None) and vector. The push_back on its side is adding the pair <int, float> of the first vector of the outer pair to you differently variable defined above.

What is the time complexity of sorting datatype vector< pair<int, vector<int> > > ? ( As the swap needs to swap vectors ))

My datatype and sort function look like below:
vector< pair< int, vector<int> > > data;
sort(data.begin(),data.end(),[]( auto a,auto b )
{
return a.first<b.first;
});
It will need to swap vectors too. Does the swap operation need to copy and paste all the elements of the vectors making the complexity of swap linear to the length of the two vectors to be swapped? Or will it do some trick (ex: pointer operation) to make it a constant time operation?

Why we cannot declare vector< int, pair< int, int > >

In a certain competitive coding, i need to use a data-structure mentioned above but it gave me an error, why it threw an error and which is the simplest data-structure i can use for this
A vector only contains one type. You are trying to put two into the vector. You could instead do vector<pair<int, pair<int, int>> and that would be fine.
We can not declare vector as vector < int , pair < int , int > > Because Vector is a sequence of contiguous storage of elements of same type .
And this represents the associative container having key value property like mapping .
so We cant declare vector as vector< int , pair < int ,int > > .
We can declare it as vector< pair < int , pair < int , int > > or vector< data_type>

vector inside a map is clear safe?

Just a quick question, if you have say:
using namespace std;
map< int, vector< string > > map1;
or maybe even:
map< int, map< int, vector< string > > > map2;
and just so you get the right idea:
map< int, map< int, map< int, vector< string > > > > map3;
if I do just:
map1.clear();
map2.clear();
map3.clear();
Is it safe in that it will empty everything in the map and its nested maps, vectors, lists, etc.?
Note:
I know if you use pointers you need to manually go through and delete or if the map goes out of scope it should be fine too I'm only particularly interested in this case when in scope and on the stack.
Yes, a map will destruct all components.
If its components are STL containers, their destructors will clear the containers.
Read more about STL containers notably about destructor of std::map
Yes this is perfectly safe. STL containers take care of memory management.
However, if you store pointers to objects which you allocated youself, you also have to delete them yourself:
std::vector<MyClass*> vec;
vec.push_back(new MyClass());
vec.clear(); // you get a memory leak here because you did not delete the object you allocated.

How to write 3d mapping in C++?

Can you please tell me how I can write multidimensional map. For two dimensional map, I did the following:
map<string, int> Employees
Employees[“person1”] = 200;
I was trying to use something similar to following for 3d mapping.
map<string, string, int> Employees;
Employees[“person1”, “age”] = 200;
Can you please tell me the correct way to do this?
and Is there a way I can initialize all the map elements to be 0 ? Just like on a array we can say int array[10]={0};
You need to create map of maps like that.
map<string, map<string, int> > employees;
employees["person1"]["age"] = 200;
You can use the pair class of the utility library to combine two objects:
map<pair<string, string>, int> Employees;
Employees[make_pair("person1", "age")] = 200;
See http://www.cplusplus.com/reference/std/utility/pair/
Instead of nested map, you can use tuple as keys; (this is a c++11 code, you could do the same with boost::tuple as well).
#include<map>
#include<tuple>
#include<string>
using namespace std;
map<tuple<string,string>,int> m;
int main(){
m[make_tuple("person1","age")]=33;
}
what you are doing here is not 3D mapping but 2D mapping, how to use stl::map as two dimension array
Correct 3D mapping will be like
map<string, map<string, map<int, string> > > Employees;
Employees[“person1”][“age”][20] = "26/10/2014";