按规则对结构的 std::list 进行排序

问题描述

我有一个 tv.setonMouseClicked(e -> { if (e.getClickCount() == 2 && ((TreeItem<String>) tv.getSelectionModel().getSelectedItem()).getValue().contains(".")) { //this method } } codeArea1.textproperty().addListener(new changelistener<String>() { @Override public void changed(ObservableValue<? extends String> observableValue,String s,String s2) { String curr = ""; String currFinal = ""; for (int i = codeArea1.getAnchor(); i > 0; i--) { if (codeArea1.getText().charat(i) == '\n' || codeArea1.getText().charat(i) == ' ') { break; }else { curr += codeArea1.getText().charat(i); } } for (int i = curr.length()-1; i >= 0; i--) { currFinal += curr.charat(i); } if (currFinal != "") { ArrayList<String> fil = new ArrayList<String>(); for (int i = 0; i < keyphrases.length; i++) { if (keyphrases[i].contains(currFinal)) { fil.add(keyphrases[i]); } } if (popup != null) { popup.hide(); } if (fil.size() > 0) { lop = new ListView(); for (int i = 0; i < fil.size(); i++) { lop.getItems().add(fil.get(i)); } popup = new Popup(); lop.setMaxHeight(80); popup.getContent().addAll(lop); //this line is bugging out popup.show(codeArea1,codeArea1.getCaretBounds().get().getMaxX(),codeArea1.getCaretBounds().get().getMaxY()); codeArea1.requestFocus(); } codeArea1.requestFocus(); }else { if (popup != null) { popup.hide(); } } } }); 。我需要根据规则 std::list<struct Data> datadatahead 进行排序。

为此,我使用 rule

下面的实现有效,但效率低下。查找std::list::sort(Compare comp)列表中的元素需要遍历列表,计算距离需要再次遍历列表。

还有什么方法可以对数据进行排序?也许使用向量、unordered_map 和其他?

rule

解决方法

使用 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) 操作。此外,它们可能会减少内存开销并改善引用的局部性,这些在 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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...