3

我正在尝试解决一个问题,即我将字符插入到 type 的地图中<char, int>。如果 char 已经存在于地图中,我会将 int 增加 1。我创建了自己的比较器,用于对地图中的元素进行优先级排序。优先级不能以我希望的方式起作用,因为最终输出不遵循顺序。

#include <iostream>
#include <string>
#include <map>
#include <iterator>

using namespace std;

struct classcomp {
  bool operator()(const int& a, const int& b) const {
        return a < b;
    }
};

bool isPresent(map<char,int,classcomp> mymap, char c){
    return (mymap.find('b') != mymap.end());
}

int main(){
    string input="dadbadddddddcabca";
    map<char,int,classcomp> mymap;
    char temp;

    for(string::iterator it = input.begin(); it!=input.end(); ++it){
        temp = *it;
        if(!isPresent(mymap, temp))
            mymap.insert(pair<char,int>(*it,1));
        else
            mymap[temp]++;
    }

    for (auto& x: mymap) {
        cout << x.first << ": " << x.second << '\n';
    }


    return 0;
}

给出以下输出:

a: 4
b: 2
c: 2
d: 8
4

5 回答 5

2

比较器用于排序chars 而不是ints。

它正在对键进行排序,并且似乎工作得很好 - a b c d

于 2013-03-19T18:04:03.347 回答
2

std::map 被设计为按键排序,并且为值类型提供比较器不会改变任何内容。想象一下std::map<char,char>,您认为如何提供价值比较器(如果可能的话)?
所以解决方案是使用允许按多个键排序的容器,如 boost::multi_index 或只是创建另一个映射 - 反转:

#include <iostream>
#include <string>
#include <map>
#include <iterator>

using namespace std;

int main(){
    string input="dadbadddddddcabca";
    map<char,int> mymap;

    for(string::iterator it = input.begin(); it!=input.end(); ++it){
        mymap[*it]++;
    }
    map<int,char> reversemap;
    for (auto& x: mymap) {
        reversemap.insert( make_pair( x.second, x.first ) );
    }

    for (auto& x: reversemap ) {
        cout << x.first << ": " << x.second << '\n';
    }


    return 0;
}

请注意,您对元素存在的预检查是完全多余的,如果它不存在,std::map operator[] 会创建新元素并对其进行初始化。您可能会注意到,在输出中您现在缺少一些值(尽管它们已排序),如果这不是您需要的,请将 reversemap 类型从 map 更改为 multimap,这允许键重复。

于 2013-03-19T18:21:11.647 回答
1

map按键而不是值对其条目进行排序。char钥匙被默默地投射到int你的classcomp::operator()

于 2013-03-19T18:03:03.420 回答
1

为什么

mymap.find('b') != mymap.end());

并不是

mymap.find(c) != mymap.end());
于 2013-03-19T18:05:29.640 回答
0

也许这就是你想要的

int main() {
    std::string input="dadbadddddddcabca";
    typedef std::map< char, int > map_t;
    map_t mymap;
    char temp;

    for ( std::string::const_iterator it = input.begin(), e = input.end(); it != e; ++it ) {
        temp = *it;
        mymap[ temp ] = mymap[ temp ] + 1; // Hopufuly operator[] inserts zero initialized value, if can't find a key
    }
    typedef std::pair< typename map_t::key_type, typename map_t::mapped_type > pair_t;
    std::vector< pair_t > sortedByValue;
    sortedByValue.assign( mymap.begin(), mymap.end() );
    std::sort( sortedByValue.begin(), sortedByValue.end(), []( const pair_t & left, const pair_t & right ) {
        return left.second < right.second;
        // change to
        // return left.second > right.second;
        // for descend order
    } );

    for ( const auto & x: sortedByValue ) {
        std::cout << x.first << ": " << x.second << std::endl;
    }    
}

LWS链接

于 2013-03-19T18:21:39.577 回答