C++ c++;STL按int和string向量排序

C++ c++;STL按int和string向量排序,c++,algorithm,stl,C++,Algorithm,Stl,今天我在topcoder上解决了一个问题,我必须根据奥运会奖牌对国家进行排序。我有一个STL容器vectorv矢量不包含一个国家赢得的金、银和铜。我必须按照黄金、白银、青铜和国家(字母顺序)的特定顺序对结构进行排序 我使用了sort(v.begin(),v.end()),但这种排序只根据两个国家的g、s、b奖牌相同时的第一个值,即金、银和铜,而不是按字母顺序排列国家 您必须提供比较函数对象 typedef pair<vector<int>, string> Country

今天我在topcoder上解决了一个问题,我必须根据奥运会奖牌对国家进行排序。我有一个STL容器
vectorv矢量
不包含一个国家赢得的金、银和铜。我必须按照黄金、白银、青铜和国家(字母顺序)的特定顺序对结构进行排序


我使用了sort(v.begin(),v.end()),但这种排序只根据两个国家的g、s、b奖牌相同时的第一个值,即金、银和铜,而不是按字母顺序排列国家

您必须提供比较函数对象

typedef pair<vector<int>, string> Country;
struct CmpCountry {
    bool operator()(const Country& lhs, const Country& rhs)
    {
        if(lhs.first[0] != rhs.first[0])
            return lhs.first[0] > rhs.first[0];
        if(lhs.first[1] != rhs.first[1])
            return lhs.first[1] > rhs.first[1];
        if(lhs.first[2] != rhs.first[2])
            return lhs.first[2] > rhs.first[2];
        return lhs.second < rhs.second;
    }
};

// then, call sort as following
std::sort(v.begin(), v.end(), CmpCountry());
typedef对国家/地区;
结构CmpCountry{
布尔运算符()(常数国家和左侧、常数国家和右侧)
{
如果(左首[0]!=右首[0])
返回左首[0]>右首[0];
如果(左首[1]!=右首[1])
返回左首[1]>右首[1];
如果(左首[2]!=右首[2])
返回左首[2]>右首[2];
返回左秒<右秒;
}
};
//然后,调用sort,如下所示
std::sort(v.begin()、v.end()、CmpCountry());

您必须提供比较功能对象

typedef pair<vector<int>, string> Country;
struct CmpCountry {
    bool operator()(const Country& lhs, const Country& rhs)
    {
        if(lhs.first[0] != rhs.first[0])
            return lhs.first[0] > rhs.first[0];
        if(lhs.first[1] != rhs.first[1])
            return lhs.first[1] > rhs.first[1];
        if(lhs.first[2] != rhs.first[2])
            return lhs.first[2] > rhs.first[2];
        return lhs.second < rhs.second;
    }
};

// then, call sort as following
std::sort(v.begin(), v.end(), CmpCountry());
typedef对国家/地区;
结构CmpCountry{
布尔运算符()(常数国家和左侧、常数国家和右侧)
{
如果(左首[0]!=右首[0])
返回左首[0]>右首[0];
如果(左首[1]!=右首[1])
返回左首[1]>右首[1];
如果(左首[2]!=右首[2])
返回左首[2]>右首[2];
返回左秒<右秒;
}
};
//然后,调用sort,如下所示
std::sort(v.begin()、v.end()、CmpCountry());

您需要一个自定义比较器,以便STL排序可以比较向量。最简单的方法是将向量定义为struct,然后添加一个比较器

struct country {
    vector<int> medals;
    string country_name;
}

struct compare { 
    bool operator()(country const &a, country const &b) { 
        for(int i = 0; i <  3; i++){ // 3 medals, right?
            if(a.medals[i] != b.medals[i]) 
                return a.medals[i] < b.medals[i];
        //else both countries have same number of medals
        return a.country_name < b.country_name;
    }
};
struct country{
矢量奖牌;
字符串国家/地区名称;
}
结构比较{
布尔运算符()(国家常量和a,国家常量和b){
对于(inti=0;i<3;i++){//3枚奖牌,对吗?
如果(a.奖牌[i]!=b.奖牌[i])
返回a.奖牌[i]
您需要一个自定义比较器,以便STL排序可以比较向量。最简单的方法是将向量定义为struct,然后添加一个比较器

struct country {
    vector<int> medals;
    string country_name;
}

struct compare { 
    bool operator()(country const &a, country const &b) { 
        for(int i = 0; i <  3; i++){ // 3 medals, right?
            if(a.medals[i] != b.medals[i]) 
                return a.medals[i] < b.medals[i];
        //else both countries have same number of medals
        return a.country_name < b.country_name;
    }
};
struct country{
矢量奖牌;
字符串国家/地区名称;
}
结构比较{
布尔运算符()(国家常量和a,国家常量和b){
对于(inti=0;i<3;i++){//3枚奖牌,对吗?
如果(a.奖牌[i]!=b.奖牌[i])
返回a.奖牌[i]
如果您实际编写了所描述的代码,它将完全满足您的要求:

比较.cpp:

#include <vector>
#include <utility>
#include <algorithm>
#include <iostream>

using namespace std;

typedef pair<vector<int>, string> Country;

int main(int, char*[]) {
  vector<Country> v;
  while (cin.good()) {
    string name;
    int g, s, b;
    cin >> name >> g >> s >> b;
    vector<int> c;
    c.push_back(g);
    c.push_back(s);
    c.push_back(b);
    v.push_back(make_pair(c, name));
  }
  sort(v.begin(), v.end());
  for (vector<Country>::const_iterator it = v.begin(); it != v.end(); ++it) {
    cout << it->second << " " << it->first[0]
     << " " << it->first[1] << " " << it->first[2] << "\n";
  }
  return 0;
}
现在,请执行以下操作:

$ clang++ -o compare compare.cpp
$ ./compare < compare.in
BE 1 3 5
DE 1 3 5
FR 1 3 5
RU 3 1 2
US 3 2 1
CA 4 1 3

(请注意,我特意只使用
==
如果您实际编写了所描述的代码,它将完全满足您的要求:

比较.cpp:

#include <vector>
#include <utility>
#include <algorithm>
#include <iostream>

using namespace std;

typedef pair<vector<int>, string> Country;

int main(int, char*[]) {
  vector<Country> v;
  while (cin.good()) {
    string name;
    int g, s, b;
    cin >> name >> g >> s >> b;
    vector<int> c;
    c.push_back(g);
    c.push_back(s);
    c.push_back(b);
    v.push_back(make_pair(c, name));
  }
  sort(v.begin(), v.end());
  for (vector<Country>::const_iterator it = v.begin(); it != v.end(); ++it) {
    cout << it->second << " " << it->first[0]
     << " " << it->first[1] << " " << it->first[2] << "\n";
  }
  return 0;
}
现在,请执行以下操作:

$ clang++ -o compare compare.cpp
$ ./compare < compare.in
BE 1 3 5
DE 1 3 5
FR 1 3 5
RU 3 1 2
US 3 2 1
CA 4 1 3

(请注意,我特意只使用
==
pair
的确切含义是什么?另外,将其声明为结构而不是typedef(如timrau先前的回答)如何更容易定义比较函数?另外,您真的想创建一个名为“compare”仅针对这种特殊情况?
strcmp
char*
一起工作,您可以直接将
std::string
s与
运算符进行比较,但该运算符仍然无法编译。如果它编译了,它将完全等同于OP开始时使用的默认比较器(假定.size()保证为3),所以很难看出这应该解决什么问题。
pair
到底意味着什么?另外,将其声明为结构而不是typedef(如timrau先前的回答中所述)如何更容易定义比较函数?另外,您真的想创建一个名为“compare”的全局命名空间结构吗“仅针对这种特殊情况?
strcmp
char*
一起工作,您可以直接将
std::string
s与
运算符进行比较,这仍然无法编译。如果它编译了,它将完全等同于OP开始时使用的默认比较器(假定.size()保证为3),因此很难看出这应该解决什么问题。这是错误的。成对的默认比较被定义为字典比较(这意味着它将首先比较向量,然后比较字符串),再次定义为vector的字典比较,这意味着最终它将执行与您尝试执行的完全相同的操作,但不会出现使用索引0代替1或2的拼写错误。此外,这不会编译,因为
CmpCountry()
不能用作比较器,因为没有
运算符()
;您称之为
operatorOK,它现在可以工作了,但它仍然不是很好。没有理由明确地打破向量排序,因为您要做的就是
lhs.first>rhs.first
。而事实上,您的打字错误是使用0或1或2,直到我指出它才注意到问题,这就是原因你不想这样写。在更次要的注释中,你通常需要函子的
操作符()
是常量,通常最好使用
rhs.first
而不是
lhs.first>rhs.first
,因为这样它可以处理不定义所有比较的类型。这是错误的。默认比较是为pair定义为字典比较(这意味着它将首先比较向量,然后比较字符串),然后再次定义为词典比较
$ ./compare < compare.in
CA 4 1 3
US 3 2 1
RU 3 1 2
BE 1 3 5
DE 1 3 5
FR 1 3 5