简体   繁体   中英

Range-based for loop in C++

I was trying to solve this problem on LeetCode. My solution involves keeping a hashmap with a key based on Godel's number from the counts of each letter, and if I have conflicts, I just iterate over an array and compare the counts. However I don't know why this code does not work:

class Solution {
    typedef vector<string> vs;
    const int MAX_ALPHABET = 26;
    const int MOD = 10007;
    vector<int> primes;

    void gen_primes() {
        primes.push_back(2);

        for (int i=3; primes.size() < 26; i+=2) {
            bool isPrime = true;
            for (int x : primes)
                if (i % x == 0) {
                    isPrime = false;
                    break;
                }
            if (isPrime)
                primes.push_back(i);
        }
    }

    int compute(vector<int>& v) {
        int ret = 1;
        for (int i=0; i<MAX_ALPHABET; i++) {
            for (int j=0; j<v[i]; j++)
                ret = (ret * primes[i]) % MOD;
        }
        return ret;
    }
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        gen_primes();

        unordered_map<int, vector<
            pair< vector<int>, vector<string> >
        >> hash;

        for (string s : strs) {
            vector<int> count(MAX_ALPHABET, 0);
            for (char c : s)
                count[c - 'a']++;
            int key = compute(count);

            bool inHash = false;
            // Here is the problem
            for (auto x : hash[key])
                if (x.first == count) {
                    x.second.push_back(s);
                    inHash = true;
                    break;
                }
            // Here ends the problem
            if (!inHash) {
                hash[key].push_back({count, {s}});
            }
        }

        vector<vs> ret;
        for (auto hashGroup : hash) {
            // hashGroup = {key, vector< pair<vector<int>, vector<string>> >}
            cout << hashGroup.second[0].second.size() << endl;
            for (auto anagramGroup: hashGroup.second) {
                // anagramGroup = pair<vector<int>, vector<string>>
                sort(anagramGroup.second.begin(), anagramGroup.second.end());
                ret.push_back(anagramGroup.second);
            }
        }

        return ret;
    }
};

But if I replace the for range loop with a normal for loop, it works:

        for (int i=0; i<hash[key].size(); i++)
            if (hash[key][i].first == count) {
                hash[key][i].second.push_back(s);
                inHash = true;
                break;
            }

Is this behavior normal?

The problem is here:

auto x : hash[key]

Here auto x infers to a value, not to a reference. so x is a copy of the element inside vector<pair<vector<int>,vector<string>>> , not a reference to it. Try with:

auto& x : hash[key]

The problem is not the ranged-based loop itself, you can expose the same "faulty" behavior also with normal loop:

for (int i=0; i< hash[key].size(); i++) {
  auto value = hash[key][i];
  if (value.first == count) {
    value.second.push_back(s);
    inHash = true;
    break;
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM