【问题标题】:Sort unique values from a map<string, vector<string>>对 map<string, vector<string>> 中的唯一值进行排序
【发布时间】:2020-02-26 19:12:30
【问题描述】:

我的头文件中有一个自定义地图

class Tramway
{
private:
    using stations = std::vector <std::string>;
    using Tramlines = std::map <std::string, stations>;
...../

我正在尝试对唯一值进行排序,但到目前为止,我的方法是给我编译错误。 这是我的代码。

void Tramway::print_stations(const Tramway::Tramlines &tramlines)
{

    for(auto map_iter = tramlines.cbegin(); map_iter != tramlines.cend(); ++map_iter)
    {
        std::unique(map_iter->second.cbegin(), map_iter->second.cend());

        std::sort(map_iter->second.begin(), map_iter->second.end());

       for( auto vec_iter = map_iter->second.cbegin() ; vec_iter != map_iter->second.cend() ; ++vec_iter )
           std::cout << *vec_iter << std::endl;
    }

}

有没有办法同时获取唯一值并对其进行排序?我试过std::sort(std::unique(..,..))std::sort() 需要两个参数才能工作。

以下是我不断遇到的错误

    x86_64-w64-mingw32\7.3.0\include\c++\bits\stl_algobase.h:148: error: no matching function for call to 'swap(const std::__cxx11::basic_string<char>&, const std::__cxx11::basic_string<char>&)'
           swap(*__a, *__b);
           ~~~~^~~~~~~~~~~~

x86_64-w64-mingw32\7.3.0\include\c++\bits\stl_algo.h:975: error: passing 'const std::__cxx11::basic_string<char>' as 'this' argument discards qualifiers [-fpermissive]
    *++__dest = _GLIBCXX_MOVE(*__first);
              ^

x86_64-w64-mingw32\7.3.0\include\c++\bits\stl_algo.h:1852: error: passing 'const std::__cxx11::basic_string<char>' as 'this' argument discards qualifiers [-fpermissive]
        *__first = _GLIBCXX_MOVE(__val);
                 ^

x86_64-w64-mingw32\7.3.0\include\c++\bits\stl_heap.h:252: error: passing 'const std::__cxx11::basic_string<char>' as 'this' argument discards qualifiers [-fpermissive]
       *__result = _GLIBCXX_MOVE(*__first);
                 ^

x86_64-w64-mingw32\7.3.0\include\c++\bits\move.h:187: error: no type named 'type' in 'struct std::enable_if<false, void>'

86_64-w64-mingw32\7.3.0\include\c++\bits\stl_heap.h:225: error: passing 'const std::__cxx11::basic_string<char>' as 'this' argument discards qualifiers [-fpermissive]
    *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __secondChild));
                             ^

86_64-w64-mingw32\7.3.0\include\c++\bits\stl_heap.h:231: error: passing 'const std::__cxx11::basic_string<char>' as 'this' argument discards qualifiers [-fpermissive]
    *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first
                             ^
x86_64-w64-mingw32\7.3.0\include\c++\bits\stl_algobase.h:548: error: passing 'const std::__cxx11::basic_string<char>' as 'this' argument discards qualifiers [-fpermissive]
      *--__result = std::move(*--__last);
      ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~

【问题讨论】:

  • 你应该在调用 std::unique (see this page) 之后调用erase。还有but so far my approach is giving me compile errors你忘了包括编译器错误。
  • std::unique 只删除连续的重复项,使容器尾部处于未确定状态
  • @Borgleader 我添加了编译器错误。
  • std::set 是一个有序的、唯一的集合。将数据结构从 std::vector 更改为这样会避免首先重新排列吗?

标签: c++ dictionary c++11 vector


【解决方案1】:

三个问题:

  1. std::unique 需要可修改的迭代器。您不应将cbegin/cend 传递给他们。该函数还应该采用可修改的引用。

  2. 首先是std::sort,然后是std::uniquestd::unique 只删除相邻的等效元素。

  3. std::unique 无权更改向量的大小。它只是将结果序列放在向量的开头。使用remove-erase idiom 消除移除的元素。

固定代码:

void Tramway::print_stations(Tramway::Tramlines& tramlines)
{
    for (auto map_iter = tramlines.cbegin(); map_iter != tramlines.cend(); ++map_iter)
    {
        std::sort(map_iter->second.begin(), map_iter->second.end());
        map_iter->second.erase(std::unique(map_iter->second.begin(), map_iter->second.end()), map_iter->second.end());

       for (auto vec_iter = map_iter->second.cbegin(); vec_iter != map_iter->second.cend(); ++vec_iter)
           std::cout << *vec_iter << '\n';
    }    
}

另外,考虑使用基于范围的 for 循环和引用来简化代码:

void Tramway::print_stations(Tramway::Tramlines& tramlines)
{
    for (auto& tramline : tramlines) {
        auto& station = tramline.second;
        std::sort(station.begin(), station.end());
        station.erase(std::unique(station.begin(), station.end()), station.end());

        std::copy(station.begin(), station.end(),
                  std::ostream_iterator<stations>{std::cout, '\n'});
    }    
}

【讨论】:

  • 啊,我明白了,现在说得通了。我试过你的代码,但“map_iter->second.erase”给出了一个错误,“没有匹配的”成员函数来调用擦除
  • @cyberbemon 它还说了什么?错误消息应该比这更长。
  • 这里是完整的错误tramway.cpp:78:26: error: no matching member function for call to 'erase' stl_vector.h:1206:7: note: candidate function not viable: 'this' argument has type 'const std::vector&lt;std::__cxx11::basic_string&lt;char&gt;, std::allocator&lt;std::__cxx11::basic_string&lt;char&gt; &gt; &gt;', but method is not marked const stl_vector.h:1179:7: note: candidate function not viable: requires single argument '__position', but 2 arguments were provided
  • @cyberbemon 函数参数(tramline)也必须是 const。
猜你喜欢
  • 2015-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-29
  • 2021-03-26
相关资源
最近更新 更多