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.
Related
I want to initialize a vector of integer pairs while specifying its size (I have to use this structure). I tried:
vector<pair<int, int>> container;
container.emplace_back(size);
And:
container.emplace_back(size, make_pair(0, 0));
But I keep having this error:
error: no matching function for call to 'std::pair<int, int>::pair(long long unsigned int&, std::pair<int, int>)'
Is there any solution or different approach?
Thank you!
emplace_back forwards its parameters to the elements constructor. std::pair<int,int> has no constructor that takes a size and a pair, hence the error. To emplace an element:
std::vector<std::pair<int, int>> container;
container.emplace_back(0,0);
However, if you want to construct a vector of certain size upfront, you need not emplace elements, because they are already there:
std::vector<std::pair<int, int>> container(size);
container[42] = make_pair(1,2); // 42 < size !
I'm guessing what you really want is something like:
vector<pair<int, int>> container(size);
This will initialize the vector constainer with size number of default-constructed elements.
I am trying to construct a map that maps a string to a vector of unsigned integers. The way that I construct this map is as follows:
void PixelP1ROCDACSettings::getDACs(map<string,vector<unsigned int>>& dacs) const
{
dacs.clear();
dacs.insert(pair<string, vector<unsigned int> > (k_DACName_Vdd, make_vector(Vdd_, k_DACAddress_Vdd)));
dacs.insert(pair<string, vector<unsigned int> > (k_DACName_Vana,make_vector(Vana_, k_DACAddress_Vana)));
...
}
Where make_vector is defined as follows:
std::vector<unsigned int> make_vector(unsigned int DACValue,
unsigned int DACAddress) const ;
My questions are:
1) I would like to get access each individual value in my vector, I've tried to do,
dacs[key][index] but that didn't seem to work. Is there a special syntax to do this?
2) Additionally, I would like to iterate across my map, How would I do that?
Thanks in advance.
If you are using c++11 you can iterate with
for (auto& keyvaluepair : dacs) {
//keyvaluepair.first is your string
//keyvaluepair.second is your vector
}
also dacs[key][index] is the correct way to access the indexth element in the vector mapped to by key.
I have a vector of pairs, which is empty at the beginning. I implemented a custom insert and remove method, and I would also like to be able to assign NULL to certain elements, but I can't because it's not a pointer to pair.
If I try to illustrate it more specifically - given a vector V
std::vector< std::pair<A,B> > V;
neither
V.assign(number,NULL);
nor
V[n]=NULL;
would work.
I need to do this to check if there already is an element saved in a certain slot. Is there anywork around or should I just create another vector of booleans to save wheter a certian slot is full or not?
NOTE: I know any kind of map would solve it elegantly, but it has to be a vector.
I think solution with map would be optimal in your case:
std::map<int, std::pair<A, B> > M;
Then you can do
M.erase(M.find(number))
To NULL-ify to the element.
If I had to do it I would do something like
vector< pair< pair<A,B> ,int > >V , V[i].second can be 0 or 1 depending whether the element
pair has to be NULL or not.This if if you want to mark the pair NULL but still keep it for refernece.Otherwise use map as Alex1985 said.
I advise you to look at boost::optional
boost::optional< std::vector< std::pair<A,B> > > V;
if (V) {
// V was initialized
} else {
// wasn't initialized
}
documentation examples: http://www.boost.org/doc/libs/1_54_0/libs/optional/doc/html/boost_optional/examples.html
Use shared_ptr as the second type in the pair.
std::vector< std::pair<A,std::shared_ptr<B> > > V;
V.assign(number, std::shared_ptr<B>());
V[n] = std::shared_ptr<B>();
V[n] = std::shared_ptr<B>(new B());
if (V[n].get() == NULL) { /* process empty here */ }
The shared_ptr class was introduced to C++ in TR1, and is part of the C++11 specification. It works well with standard containers because it
I have the following multi-dimensional vector
int main()
{
vector< vector<string> > tempVec;
someFunction(&tempVec);
}
void someFunction(vector< vector<string> > *temp)
{
//this does not work
temp[0]->push_back("hello");
}
How do i push data into the vector when i have a vector pointer?
The below code does not work.
temp[0]->push_back("hello");
You need
(*temp)[0].push_back("hello")
That's:
dereference temp to get a vector<vector<string> > &
get first element, a vector<string> &
use . instead of -> because you're no longer handling pointers
That said, it would be easier if someFunction took a vector< vector<string> >& instead of a pointer: temp[0].push_back("hello"). References do not allow pointer arithmetic or null pointers, so they make it harder to screw up and are more suggestive of the actual kind of input required (a single vector, not an optional one or an array of them).
I have this new class Seq that inherits vector and has some additional features. I can use all methods of vector with Seq.
Having this data structure:
Seq< vector<int> > sweepEvents;
I want to have a function that takes an element vector edge search for it in sweepEvents and returns the iterator to the position of the found element in sweepEvents (if and only if edge is found) and the iterator to the last elements of the vector (if and only if edge is not found).
Then I want to work with this iterator, in that I want to compare the elements from the prev and the next position of iterator.
I have the following function for founding and returning the iterator:
Seq< vector<int> >::iterator QSweep::insertSweepEvents(edge_t edge,int currentDim){
int changePosition;
int found=0;
for (int i=0;i<currentDim;i++){
if (edge[0]==sweepEvents[i][1]){
changePosition=i;
found=1;
return sweepEvents.begin()+changePosition;
}
}
if (found==1){
sweepEvents.rep().insert(sweepEvents.begin()+changePosition,edge);
sweepEvents.rep().erase(sweepEvents.begin()+changePosition+1);
}
else{
sweepEvents.rep().insert(sweepEvents.end(),edge);
}
return sweepEvents.end()-1;
}
I then call this iterator in the main function. I actually tried but it does not compile and I do not know what syntax to use other than this:
int main(){
Seq< vector<int> > sweepEvents;
vector<int> edge;
//.....initialize sweepEvents and edge
//declare iterator but not working
Seq< vector<int> >::iterator comparePosition;
//not working neither
comparePosition=insertSweepEvents(edge,sweepEvents.size());
}
Any idea on how I should correctly call the iterator? I see it does not work as an integer index from an array?
Is Seq< vector< T > >::iterator defined in your Seq class?
Making the parameter of the template 'vector' does not imply that exists the type Seq< vector< int > >::iterator
What compilation error ? How is defined Seq<X>::iterator ?
#include <vector>
template<typename T>
struct Seq
: public std::vector<T>
{ };
typedef Seq< std::vector<int> > SeqI;
SeqI::iterator insertSweepEvents(SeqI &s)
{
return s.begin();
}
int main()
{
SeqI s;
SeqI::iterator e = insertSweepEvents(s);
}
This works fine.
Something illogical in your code. See my comments:
int found = 0;
for (int i=0;i<currentDim;i++){
if (edge[0]==sweepEvents[i][1]){
changePosition=i;
found=1;
// This place is one, where we assign 1 to found, and we do return after that (maybe you want do break/?)
return sweepEvents.begin()+changePosition;
}
}
if (found==1){ // as you see we reach this place only when found == 0
A little sidenote:
After a vector is changed, especially when appended to or inserted in, iterators to it become invalid. That's due to the fact that the vector tries to allocate a minimally sized contiguous block of memory for it's internal data, while at the same time it tries to minimize the number of times it needs to allocate a new, bigger chunk. So the data may move through memory, so iterators to it before a push are no longer valid after it.
Another little note:
You can find the difference between two iterators by using std::difference( it1, it2 ). You can re-apply that difference by using std::advance( it1, d ).
A third little note:
You seem to have a 'return' statement inside the for-loop, but the rest of the code uses variables that are set only when returning...