c++ 用find查詢vector中的某個元素位置和用迴圈遍歷查詢哪個更好?
99.99%
的情況下都是使用stl的algorithm更優,那
0.01
%也是由於stl個別演算法要在泛用性和效率(空間、時間)之間做出權衡可能在極小機率不是你使用場景的最優解。
迴歸到題目所說的std::find,不存在上述問題啊。
template< class ExecutionPolicy, class ForwardIt, class T >
ForwardIt find( ExecutionPolicy&& policy, ForwardIt first, ForwardIt last, const T& value );
其中的一個過載,ExecutionPolicy提供了並行化的潛在能力它不香麼?
No Raw Loops帶來語義上更高的抽象層次它不香麼?
用find
因為寫起來簡單,
因為程式碼讀起來簡單,
如果用for迴圈,你或者別人還可能在迴圈裡面加點料。
用find_if 還可以 配合lambda表示式能輕鬆寫你的查詢邏輯
或許理解find如何實現能幫助你解開糾結。
STL原始碼剖析 - 候捷
不同編譯器實現不一樣。
補充:find原理上就是封裝好的迴圈遍歷,找到想要的value時退出迴圈。具體實現上,有的編譯器中會做迴圈最佳化。迴圈最佳化原理其實就是
儘可能的展開迴圈
,
減少條件的比較次數
。如
int
N
=
10
;
for
(
int
i
=
0
;
i
<
N
;
++
i
)
{
// 迴圈過程中 i yourTask ( i ); } for ( int i = 0 ; i < N ;) { // 迴圈過程中 i yourTask ( i ); ++ i ; yourTask ( i ); ++ i ; } 需要注意的點是:① 迴圈比較小時,做不做迴圈最佳化差別其實非常不明顯。② debug模式下 有可能 做迴圈最佳化反而效率會變低。 原因是debug模式下,為了除錯過程中程式設計師看到變數中的值,編譯器會copy變數到指定的暫存器中。這一點可以看編譯出來的組合語言,同樣的程式碼,對比編譯結果可能會發現debug下會多出許多指令。如果是inline的,debug進不去,可能就不會有這個問題。所以在比較效率時,要在release下進行比較。 find更好一些。就算不管效能,從程式碼的可讀性和可維護性來看,也應該優先選find。 std::vector // 用find,如果以後不需要修改,可以定義為const,防止烏龍 const bool found = end(v) != std::find(begin(v), end(v), 4); // 用迴圈 bool found = false; // 要先定義一個變數,就算這個變數別處不能使用了,也不能定義為const for(auto it = begin(v); it != end(v); ++it) { if(*it == 4) { found = true; break; } } 除非按行領工資,否則實在找不出不用find的理由。 再說find只是STL中眾多查詢演算法中的一個,而且是實現最簡單的一個,自己實現這個不難。還有些查詢比較繁瑣如果自己用迴圈實現未必能一次正確且次次正確。STL都為程式設計師準備好了。用來實現各種各樣的查詢的演算法至少還有這些: std::find_if_not/std::/adjacent_find/std::find_if/std::mismatch/std::find_end/std::find_first_of/std::search/std::search_n 去看看文件,說不定能讓自己程式碼中的手寫迴圈減少很多。
先看下自己用迴圈寫一個遍歷查詢元素的程式碼
#include
#include
using namespace std;
int main()
{
vector
int findNum = 4;
bool find = false;
for(auto item : vecInt)
{
if (item == findNum)
{
find = true;
break;
}
}
cout<<“num: ” << findNum << “ ” << find;
return 0;
}
再來看一下用 SLT 裡面 find 的寫法
#include
#include
#include
using namespace std;
int main()
{
vector
int findNum = 5;
auto it = find(vecInt。begin(), vecInt。end(), findNum);
if (it != vecInt。end())
{
cout << “find num: ” << *it;
}
return 0;
}
看下 STL 中 find 的原始碼
template
_LIBCPP_NODISCARD_EXT inline
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
_InputIterator
find(_InputIterator __first, _InputIterator __last, const _Tp& __value_)
{
for (; __first != __last; ++__first)
if (*__first == __value_)
break;
return __first;
}
其實也就是一個迴圈,遍歷一下容器,發現相等的值返回當前的迭代器,沒有找到就返回 end()
其他的先不管,直接用 STL 的 find 程式碼可讀性是不是很好,有人呢說上面也可以將迴圈封裝成一個函式 find,直接呼叫,兩個是不是也就一樣了。
但是人家 STL 都幫我們把這方法都實現了,為啥還要重新寫一遍呢,重複造輪子(如果是學習程式碼另說,在工作中還是不要這樣),另外 STL 演算法裡面還提供了很多演算法,排序、查詢一系列的都可以提高我們的開發效率。