稳定的排序向量交替大小值

时间:2015-02-21 17:41:17

标签: c++11 stl

给定一对int和string的向量,类似于vector<pair<int,string>>。我需要以不同的方式对它们进行排序。

我希望第一个元素是最大的。第二个元素是最小的等等。此外,如果值相同,则必须按照它们出现在原始列表中的顺序显示值。

就像说我们有类似的东西:N = 5,这里有5对:

10 bcd
2  abc
30 def
2  xyz
50 mn

然后输出数组应为:[mn,abc,def,xyz,bcd]

说明:首先50是最大的,所以第一个元素是“mn”,然后2是最小的,但是当“abc”高于“xyz”时,首先取“abc”。然后最大值为30,因此“def”,然后最小值为2,“xyz”,然后在结束时保持“bcd”。

如何使用C ++ 11 STL完成此操作?我知道它不是那么困难

1 个答案:

答案 0 :(得分:0)

这是一个想法:

  • 根据整数
  • 稳定排序元素向量
  • 为每个唯一值创建多个存储桶
    • 每个存储桶对原始向量中的值进行稳定排序
  • 打印出来自最大值桶和最小值桶的交替元素的桶
  • 在移动到下一个存储桶之前打印存储桶的全部内容。

所以使用原始列表:

  

10 bcd
  2 abc
  30 def
  2 xyz
  50 mn

稳定分拣后:

  

2 abc
  2 xyz
  10 bcd
  30 def
  50 mn

创建存储桶:

  

2:(2,abc),(2,xyz)
  10:(10,bcd)
  30:(30,def)
  50:(50,mn)

打印存储桶50的第一个元素:

  

50,mn

打印存储桶2的第一个元素:

  

2,abc

打印铲斗50的下一个元素...不存在,移动到下一个最小的铲斗,30。 打印桶30的下一个元素:

  

30,def

打印存储桶2的下一个元素:

  

2,xyz

桶30中没有更多元素,因此转到桶10:

  

10,bcd

铲斗2中没有更多元素,因此转移到铲斗10.我们已经从另一侧到达了铲斗10,所以请停在这里。

我的实施使用std::stable_sortstd::map,并没有完全遵循这一逻辑,但即使在所有元素都相同的情况下也能正常运行:

Live Demo

代码:

#include <iostream>
#include <algorithm>
#include <vector>
#include <utility>
#include <string>
#include <map>
using namespace std;


void PrintPair(const std::pair<int, std::string>& thePair)
{
    std::cout << thePair.first << ", " << thePair.second << std::endl;
}

int main() {
    // create our vector
    std::vector<std::pair<int, std::string>> myVector{
        std::make_pair(10,"bcd"),
        std::make_pair(2, "abc"),
        std::make_pair(30, "def"),
        std::make_pair(2, "xyz"),
        std::make_pair(50, "mn")
    };


    // print vector before sorting
    std::cout << "vector before sorting:\n";
    for (auto&& nextPair : myVector)
    {
        std::cout << nextPair.first << ", " << nextPair.second << std::endl;
    }

    // sort it on the ints in the pairs
    std::stable_sort(std::begin(myVector),std::end(myVector), [](const std::pair<int,std::string>& lhs, const std::pair<int,std::string>& rhs){return lhs.first < rhs.first;});

    // print vector after sorting
    std::cout << "\nvector after sorting\n";
    for (auto&& nextPair : myVector)
    {
        std::cout << nextPair.first << ", " << nextPair.second << std::endl;
    }

    std::map<int, decltype(myVector)> myBuckets;
    for (auto&& nextElement : myVector)
    {
        if (myBuckets.find(nextElement.first) == myBuckets.end())
            myBuckets[nextElement.first] = decltype(myVector){nextElement};
        else
            myBuckets[nextElement.first].emplace_back(nextElement);
    }

    //needs at least a 2 element vector to work
    cout << "\nFinal output:\n";
    // create buckets for each value, internally each bucket is stable sorted
    // the buckets are sorted on map value
    // print out each element in a bucket before moving onto the next bucket
    auto bucketsBegin = myBuckets.begin();
    auto bucketsEnd = myBuckets.end();
    --bucketsEnd;
    auto nextEndElement = bucketsEnd->second.begin();
    auto nextBeginElement = bucketsBegin->second.begin();
    while(bucketsBegin != myBuckets.end() && bucketsBegin != bucketsEnd)
    {
        if (bucketsEnd != bucketsBegin)
        {
            PrintPair(*nextEndElement);
            ++nextEndElement;
            if (nextEndElement == bucketsEnd->second.end())
            {
                bucketsEnd--;
                nextEndElement = bucketsEnd->second.begin();
            }
        }
        PrintPair(*nextBeginElement);
        ++nextBeginElement;
        if (nextBeginElement == bucketsBegin->second.end())
        {
            bucketsBegin++;
            if (bucketsBegin != myBuckets.end())
                nextBeginElement = bucketsBegin->second.begin();
        }
    }
     //print remainder
     while(nextBeginElement != bucketsBegin->second.end())
     {
        PrintPair(*nextBeginElement);
        ++nextBeginElement;
     }



    return 0;
}

输出:

排序前的矢量:
10,bcd
2,abc
30,def
2,xyz
50,mn

分拣后的矢量
2,abc
2,xyz
10,bcd
30,def
50,mn

最终输出:
50,mn
2,abc
30,def
2,xyz
10,bcd

当几乎所有向量中的元素具有相同的值时:

排序前的矢量:
1,bcd
1,abc
1,def
1,xyz
2,mn

分拣后的矢量
1,bcd
1,abc
1,def
1,xyz
2,mn

最终输出:
2,mn
1,bcd
1,abc
1,def
1,xyz