1

I am now sorting a string in decreasing order based on the frequency of characters. For example: the input is "apple", I must output "ppale". Because character 'p' appears twice and the others only appear once. so 'p' must be placed to the left most.

Here is my code:

string frequencySort(string s) {
    if(s.size() == 0)   return "";

    unordered_map<char,int> map;
    for(auto c : s)
        map[c]++;   //record the frequency of each characters

    sort(s.begin(),s.end(),
        [=](char a, char b){return map[a] > map[b] || map[a]==map[b]&&a<b;}
        );
    return s;
}

But compiler shows error: passing ‘const std::unordered_map<char, int>’ as ‘this’ argument discards qualifiers on [=](char a, char b){return map[a] > map[b] || map[a]==map[b]&&a<b;}.

However, if I capture local variable by reference, i.e.

[&](char a, char b){return map[a] > map[b] || map[a]==map[b]&&a<b;}

it works.

Could anyone please tell my why I cannot capture by value?

Sheng
  • 49
  • 5
  • 1
    Nit picking here: Apparently, you *probably* have a `using namespace std` somewhere in your code. I will be weary of using `map` for a variable name – WhiZTiM May 17 '17 at 08:30

1 Answers1

2

A lambda's operator (...) is const by default. Capture by value will require the lambda to keep copies of all captured objects.

Make the lambda mutable to allow modifying value captures.

sort(s.begin(),s.end(), [=](char a, char b) mutable 
          {return map[a] > map[b] || map[a]==map[b]&&a<b;}
    );

I suspect the sort and unordered_map is from the namespace std. From the way you used them without a namespace resolution, you probably have a using namespace std in your code (which isn't nice). I will be weary of using map for a variable name.

Community
  • 1
  • 1
WhiZTiM
  • 21,207
  • 4
  • 43
  • 68
  • yap, `sort` and `unordered_map` are from `std` and I have a `using namespace std`. Thanks for your suggestion! – Sheng May 18 '17 at 12:11