質問

I just wonder if I can use a "complicated" map as the value of another map. I have self-defined several structs as follow:

typedef std::vector<std::string> pattern;
typedef std::map<int, std::vector<pattern>> dimPatternsMap;
typedef std::map<int, dimPatternsMap> supportDimMapMap;

OK let me explain these things...pattern is a vector of strings. For the "smaller" map dimPatternsMap, the key is an integer which is the dimension of pattern (the size of that vector containing strings) and the value is vector containing patterns (which is a vector of vectors...).

The "bigger" map supportDimMapMap also use an integer as the key value, but use dimPatternsMap as its value. The key means "support count".

Now I begin to construct this "complicated" map:

supportDimMapMap currReverseMap;
pattern p = getItFromSomePlace();  //I just omit the process I got pattern and its support
int support = getItFromSomePlaceToo();

if(currReverseMap.find(support) == currReverseMap.end()) {
    dimPatternsMap newDpm;

    std::vector<pattern> newPatterns;
    newPatterns.push_back(currPattern);
    newDpm[dim] = newPatterns;

    currReverseMap[support] = newDpm;

} else{
    dimPatternsMap currDpm = currReverseMap[support];

    if(currDpm.find(dim) == currDpm.end()) {
        std::vector<pattern> currDimPatterns;
        currDimPatterns.push_back(currPattern);

        currDpm[dim] = currDimPatterns;
    } else {
        currDpm[dim].push_back(currPattern);
    }
}

Forgive me the code is really a mass...

But then as I want to traverse the map like:

for(supportDimMapMap::iterator iter = currReverseMap.begin(); iter != currReverseMap.end(); ++iter) {
        int support = iter->first;
        dimPatternsMap dpm = iter->second;

        for(dimPatternsMap::iterator ittt = dpm.begin(); ittt != dpm.end(); ++ittt) {
            int dim = ittt->first;
            std::vector<pattern> patterns = ittt->second;
            int s = patterns.size();
        }
}

I found the value s is always 1, which means that for each unique support value and for each dimension of that support value, there is only one pattern! But as I debug my code in the map constructing process, I indeed found that the size is not 1 - I actually added the new patterns into the map successfully...But when it comes to traversing, all the sizes become 1 and I don't know why...

Any suggestions or explanations will be greatly appreciated! Thanks!!

役に立ちましたか?

解決

dimPatternsMap currDpm = currReverseMap[support];

currDpm is a copy of currReverseMap[support]. It is not the same object. So then when you make changes to currDpm, nothing within currReverseMap changes.

On the other hand, if you use a reference:

dimPatternsMap& currDpm = currReverseMap[support];

then currDpm and currReverseMap[support] really are the same object, so later statements using currDpm will really be changing a value within currReverseMap.

There are a few other places where your code could benefit from references too.

他のヒント

My guess: you should use a reference in your else:

dimPatternsMap& currDpm = currReverseMap[support];

Your current code creates a copy instead of using the original map.

Your problem is this line:

dimPatternsMap currDpm = currReverseMap[support];

Based on the code following it, it wants to read like this:

dimPatternsMap& currDpm = currReverseMap[support];

Without the & you modify a copy of the entry rather than the existing entry.

Your code is making several copies of the objects underneath, try using more references and iterators (find() already gives you an element if it was found, for example).

For example, dimPatternsMap currDpm = currReverseMap[support]; actually makes a copy of a map in your structure and adds an element to it (not to the original). Try using a reference instead.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top