Jack Hessel
Jack Hessel

Reputation: 103

c++ map iterator not looping over every element in the map

I'm attempting to loop over a std::map I've constructed in c++

The map is fairly strange, the keys are vectors of structs I've created (I've used a custom comparator) and the values are vectors of doubles.

My problem is that when I iterate over the map, the loop terminates before I reach the end.

typedef map<int, map<vector<svm_node>, vector<double>, CompareSparseVectors> >::iterator DataIter;
typedef map<vector<svm_node>, vector<double>, CompareSparseVectors>::iterator SVIter;

for(DataIter di = myModel.modelData.begin();
    di != myModel.modelData.end();
    ++di) {
    cout << "The size of (di->second) is " << di->second.size() << endl;
    int itercount = 0;
    for(SVIter sv = (di->second).begin();
        sv != (di->second).end();
        ++sv) {
        cout << itercount << endl;
        itercount ++;
    }
  }
}

The output of this code snippet is

The size of (di->second) is 47
0
1
The size of (di->second) is 18
0
1

myModel.modelData is a map<int, map<vector<svm_node>, vector<double>, CompareSparseVectors> > and ComparseSparseVectors is a struct containing a comparison function for vector<svm_node>. If you need more context, please let me know, but it just seems like I couldn't have a map complex enough that it claims to be one size when queried with .size(), yet isn't able to be iterated over completely.

EDIT: Here's the code for the svm_node and CompareSparseVector structs.

struct svm_node{
    int index;
    double value;

    friend bool operator==(const svm_node& a,const svm_node& b) {
        return (a.index == b.index
                        &&
                fabs(a.value - b.value) < 1E-20);
    }

    friend bool operator!=(const svm_node& a,const svm_node& b) {
        return (a.index != b.index
                        ||
                fabs(a.value - b.value) > 1E-20);}    };                                                                                                                                                             

struct CompareSparseVectors {
    bool operator()(const vector<svm_node> a, const vector<svm_node> b)
    {
      if(a.size() != b.size()) return true;
      for(int i = 0; i < a.size(); ++i) {if(!(a[i] == b[i])) return true;}
      return false;
    }
  };

Upvotes: 0

Views: 492

Answers (1)

JoshG79
JoshG79

Reputation: 1687

Make sure your ComparseSparseVectors returns true if and only if one vector is less than the other. You should be able to run:

vector<svm_mode> a, b;
cout << (CompareSparseVectors(a,b) && CompareSparseVector(b,a));

and get 0 for all possible a and b.

Upvotes: 2

Related Questions