问题描述
我有一个 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> data
按 data
对 head
进行排序。
为此,我使用 rule
。
下面的实现有效,但效率低下。查找std::list::sort(Compare comp)
列表中的元素需要遍历列表,计算距离需要再次遍历列表。
还有什么方法可以对数据进行排序?也许使用向量、unordered_map 和其他?
rule
解决方法
使用 std::vector
和 std_unordered_map
重写程序。
更改函数 std::list::sort
和 std::sort
的速度:
没有标志-O3
:
- 第一个选项:0.000030 秒
- 第二个选项:0.000017 秒
带有标志 -O3
:
- 第一个选项:0.000009 秒
- 第二个选项:0.000009 秒
两个问题:
-
一切都正确吗?
-
排序时如何应用
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) 操作。此外,它们可能会减少内存开销并改善引用的局部性,这些在 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
。