非标准条件排序算法STL c ++

时间:2015-03-29 09:28:49

标签: c++ algorithm sorting stl

我正在学习STL,并从斯坦福大学找到了this非常有趣的PDF作品。其中一项任务是对歌曲列表进行排序,但标签为“我的歌曲”的歌曲始终位于列表的第一位。

所以,如果我们有:

vector <string> song{ "Viva", "Pompeii", "My song", "We remain", "My song", "It is time" };

输出应为:

My song, My song ... (in ascending or descending order);

我使用iter_swap

解决了这个问题

这是我的代码:

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


    void print(vector <string> song) {
        for (vector <string> ::iterator it = song.begin(), end = song.end(); it != end; ++it) {
            cout << *it << " ";
        }
    }

    int main() {
        vector <string> song{ "Viva", "Pompeii", "My song", "We remain", "My song", "It is time" };
        vector <string> ::iterator start = song.begin();

        for (vector <string> ::iterator begin = song.begin(), end = song.end(); begin != end; ++begin){
            if (*begin == "My song") {
                iter_swap(start, begin);
                ++start;
            }
        }
        sort(start, song.end());
        print(song);
        cin.get();
        }

但在此之前,我一直在努力通过仅使用sort算法来解决问题。不幸的是,我没有提出解决方案。你能说是否有可能编写一个可以解决任务的排序函数compare?我不确定是否可能,因为sort只是简单的排序。我是对的吗?

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

bool compare(string x, string y) {
    // What to write here?
}

void print(vector <string> song) {
    for (vector <string> ::iterator it = song.begin(), end = song.end(); it != end; ++it) {
        cout << *it << " ";
    }
}

int main() {
    vector <string> song{ "Viva", "Pompeii", "My song", "We remain", "My song", "It is time" };

    sort(start, song.end(), compare);
    print(song);
    cin.get();
    }

1 个答案:

答案 0 :(得分:7)

是的,这是可能的。您只需要确保字符串"My song"比其他任何字符串都要小。

bool compare(std::string const& x, std::string const& y)
{
    // if y == "My Song", then x can't come before it
    if (y == "My song") return false;

    // we already know y != "My Song", so if x does, then we know it should come before y
    if (x == "My song") return true;

    // neither x nor y == "My Song", so just fall back to a normal comparison.
    return x < y;    
}

顺便说一下,你原来的想法很好。但你所做的是一个分区。标准库中也有一个算法。

auto start = std::partition(song.begin(), song.end(),
    [](std::string const& s) { return s == "My song"; });
std::sort(start, song.end());