簡體   English   中英

按規則對結構的 std::list 進行排序

[英]Sorting the std::list of structures by rule

我有一個std::list<struct Data> data 我需要根據規則ruleheaddata進行排序。

為此,我使用std::list::sort(Compare comp)

下面的實現有效,但是效率低下。 rule列表中查找元素需要遍歷列表,計算距離需要再次遍歷列表。

數據還能如何排序? 也許使用向量、unordered_map 和其他?

#include <iostream>
#include <list>
#include <algorithm>

struct Data {
    std::string code;
    std::string text;
    std::string head;
};

int main() {
    struct Data data1{"0010", "it is text1", "head3"};
    struct Data data2{"0025", "it is text2", "head1"};
    struct Data data3{"0065", "it is text3", "head2"};
    struct Data data4{"0011", "it is text4", "head2"};
    
    std::list<struct Data> data = {data1, data2, data3, data4};
    
    std::list<std::string> rule = {"head1", "head2", "head3", "head4"};
    

    data.sort([&rule](const Data& first, const Data& second) {
        auto index_a = std::distance(rule.begin(), std::find(rule.begin(),rule.end(),first.head));
        auto index_b = std::distance(rule.begin(), std::find(rule.begin(),rule.end(),second.head));
        return index_a < index_b;
    });
    
    for (auto &it : data)
        std::cout << it.code << "\t" << it.text << "\t" << it.head << "\n";
    
    return 0;
}

使用std::vectorstd_unordered_map了程序。

改變了std::list::sortstd::sort函數的速度:

沒有標志-O3

  • 第一個選項:0.000030 秒
  • 第二個選項:0.000017 秒

帶有標志-O3

  • 第一個選項:0.000009 秒
  • 第二個選項:0.000009 秒

兩個問題:

  1. 一切都正確嗎?

  2. 排序時如何應用set::less<std::string>

     std::vector<struct Data> data = {data1, data2, data3, data4}; std::unordered_map<std::string, unsigned> rule = { {"head1", 0}, {"head2", 1}, {"head3", 2}, {"head4", 3} }; std::sort(data.begin(), data.end(), [&rule](const Data& first, const Data& second) { int index_f = rule[first.head], index_s = rule[second.head]; return index_f < index_s; }); for (auto &it: data) std::cout << it.code << "\t" << it.text << "\t" << it.head << "\n"; return 0;

    }

這個問題可以很容易地通過使用提供隨機訪問的容器來解決,比如vectordequearray 對於這些,計算兩個迭代器之間的距離是 O(1) 操作,而不是 O(n) 操作。 此外,它們可能會減少 memory 開銷並改善 Big O 表示法未涵蓋但仍會影響性能的引用局部性。

不過要查看的另一部分是find()調用,因為這仍然需要遍歷 O(n) 中的序列。 如果您使用某種字典,例如mapunordered_map ,您甚至可以將其減少到 O(log n) 或 O(1)。

最后,如果您希望訂單為“head1”...“head4”不僅僅是巧合,您可以簡單地委托給less<string>而不是實現您自己的。

但是:除非您有實際數字證明此代碼是性能關鍵型應用程序的瓶頸,否則您正在做過早的優化。 此外,所有 Big-O 聲明都以“有一個n_0 ,因此對於所有n > n_0 ...”開始,您甚至可能無法達到n_0

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM