STL地图排序

use*_*815 6 c++ sorting stl map

更新:我遵循了John的指导并修改了他的代码,通过创建比较器函数解决了我的问题,并将其插入到STL map中的Compare参数中.由于我的字符串日期严格采用所示格式,因此使用substr会很好.我的输出和代码如下,供您参考.

Date            Total Sales
01JAN1900       $4
20JAN1902       $40
18NOV1912       $2500
19NOV1912       $2500
19OCT1923       $25
01JAN1991       $22
15NOV1991       $300
Grand Total:    $5391


 struct CompareDates 
:
  public std::binary_function <bool, std::string, std::string>
{
  bool operator() (const std::string& lhs, const std::string& rhs)
  {


     if(lhs.substr(5,4) < rhs.substr(5,4))
     {
         return true;

     }
     else if (lhs.substr(5,4) == rhs.substr(5,4) && lhs.substr(2,3) < rhs.substr(2,3))
     {
         return true;
     }
     else if (lhs.substr(5,4) == rhs.substr(5,4) && lhs.substr(2,3) == rhs.substr(2,3) && lhs.substr(0,2) < rhs.substr(0,2))
     {
         return true;

     }
     else
     {
         return false;
     }


  }
};

map<string, double,CompareDates> dailyDatePrices;
Run Code Online (Sandbox Code Playgroud)

初始问题:我需要将原始数据分类为每日报告格式.因此我使用STL map将日期作为键存储,将项目价格作为值存储.根据我的阅读,STL地图会自动排序.但是我不希望它按地图排序,因为它会生成下面所述的不需要的当前报告输出.我想根据字符串日期(最早到最晚)排序,并希望它是那种确切的格式.我已经使用向量和函数比较器来对使用map之前的日期进行排序.有没有办法去做呢?谢谢!

Raw Data
STRAW:10:15NOV1991
TOY:10:15NOV1991
BARLEY:5:01OCT1992

Undesired Current Report Output
01OCT1992 5
15NOV1991 20

Expected Report Output
15NOV1991 20
01OCT1992 5
Run Code Online (Sandbox Code Playgroud)

Joh*_*ing 11

A std::map已排序.没有办法构造一个map没有排序的.

问题不map在于排序的事实.问题是如何设计密钥.

你已经说过你的钥匙是一个约会,但实际上是一个约会string.如何才能map知道数据中的数据string实际上是一个日期,并且它应该先按年份排序,然后是月份,然后是当天?它不能.你必须告诉它这样做.

将密钥更改为以下格式的字符串:

YYYYMMDD

在那里Y,M并且D都是数字.不要试图使用NOV11月 - 11改为使用.

您也可以使用unsigned longs代替键而不是strings.这会使比较更快,但计算值有点棘手.


如果你必须坚持他们的键的原始格式,那么你有一些工作要做.地图根据地图的比较器进行排序,比较器被指定为模板参数之一:

[C++ 03示例]

struct CompareDates 
:
  public std::binary_function <bool, std::string, std::string>
{
  bool operator() (const std::string& lhs, const std::string& rhs)
  {
    // return true if lhs < rhs
    // return false otherwise

    // step 1:  compare years.  if lhs.year < rhs.year, return true.  else, continue
    // step 2: compare months.  if lhs.month < rhs.month, return true.  else, continue.
    //    note:  don't just compare the strings, else "AUG" < "JAN" etc
    // step 3: compare days.  if lhs.day < rhs.day, return true.  else, return false.
  }
};
Run Code Online (Sandbox Code Playgroud)

由于这似乎是家庭作业,我会让你填写上面的遗漏位.:)

使用此比较器比较键,您可以实例化一个自动执行正确排序的映射:

std::map <Key, Value, CompareDates> myMap;
Run Code Online (Sandbox Code Playgroud)


Bil*_*eal 2

如果您想要做的只是按照与当前使用的相反的顺序对地图进行排序,您只需给它一个std::greater比较器而不是默认的std::less

std::map<date, other_type, std::greater<date>> example;
// Otherwise use example
Run Code Online (Sandbox Code Playgroud)

例子:

#include <iostream>
#include <functional>
#include <map>

int main() {
    std::map<int, float, std::greater<int>> example;
    example.emplace(std::make_pair(10, 10.0));
    example.emplace(std::make_pair(12, 12.0));

    for (auto const& entry : example)
    {
        std::cout << "Key: " << entry.first << " " << entry.second << std::endl;
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

http://ideone.com/9Guuil