[英]Sorting the std::list of structures by rule
我有一個std::list<struct Data> data
。 我需要根據規則rule
按head
對data
進行排序。
為此,我使用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::vector
和std_unordered_map
了程序。
改變了std::list::sort
和std::sort
函數的速度:
沒有標志-O3
:
帶有標志-O3
:
兩個問題:
一切都正確嗎?
排序時如何應用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;
}
這個問題可以很容易地通過使用提供隨機訪問的容器來解決,比如vector
、 deque
或array
。 對於這些,計算兩個迭代器之間的距離是 O(1) 操作,而不是 O(n) 操作。 此外,它們可能會減少 memory 開銷並改善 Big O 表示法未涵蓋但仍會影響性能的引用局部性。
不過要查看的另一部分是find()
調用,因為這仍然需要遍歷 O(n) 中的序列。 如果您使用某種字典,例如map
或unordered_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.