我知道這個線程是舊的,但我覺得它非常有用在C++中實現強大的argmax函數。
但是,據我所見,上面給出的所有示例都依賴於std :: max_element,它在元素之間進行比較(使用函子或通過調用運算符<)。如果每個元素的計算都很昂貴,這可能會很慢。它適用於排序數字和處理簡單的類,但如果函子更復雜呢?也許計算一個國際象棋位置的啓發式值或其他產生巨大樹木的東西等。
作爲線程啓動程序提到的真正的argmax只會計算一次argmax,然後將其保存爲與其他值進行比較。
編輯:好吧,我惱火,並有太多的空閒時間,所以我創建了一個< C++ 11和一個C++ 11版本的R值的引用,第一個C++ 11版:
#include <iostream>
#include <algorithm>
#include <iterator>
#include <vector>
template<typename IteratorT, typename HeuristicFunctorT>
IteratorT argmax(IteratorT && it, const IteratorT & end, const HeuristicFunctorT & functor) {
IteratorT best(it++);
typename HeuristicFunctorT::result_type best_value(functor(*best));
for(; it != end; ++it) {
typename HeuristicFunctorT::result_type value(functor(*it));
if (value > best_value) {
best_value = value;
best = it;
}
}
return best;
}
template<typename IteratorT, typename HeuristicFunctorT>
inline IteratorT argmax(const IteratorT & begin, const IteratorT & end, const HeuristicFunctorT & functor) {
return argmax(IteratorT(begin), end, functor);
}
class IntPairFunctor : public std::unary_function< std::pair<int, int>, int > {
public:
int operator() (const std::pair<int, int> & v) const {
return v.first + v.second;
}
};
std::pair<int, int> rand_pair() {
return std::make_pair(rand(), rand());
}
int main(int argc, const char **argv) {
srand(time(NULL));
std::vector< std::pair<int, int> > ints;
std::generate_n(std::back_insert_iterator< std::vector< std::pair<int, int> > >(ints), 1000, rand_pair);
std::vector< std::pair<int, int> >::iterator m (argmax(ints.begin(), ints.end(), IntPairFunctor()));
std::cout << std::endl << "argmax: " << *m << std::endl;
}
非C++ 11的版本要簡單得多,只有模板:
template<typename IteratorT, typename HeuristicFunctorT>
IteratorT argmax(IteratorT it, const IteratorT & end, const HeuristicFunctorT & functor) {
IteratorT best(it++);
typename HeuristicFunctorT::result_type best_value(functor(*best));
for(; it != end; ++it) {
typename HeuristicFunctorT::result_type value(functor(*it));
if (value > best_value) {
best_value = value;
best = it;
}
}
return best;
}
注意,無論是版本需要任何模板參數,唯一的要求是啓發式實現unary_function類
矢量的名稱完全沒有區別。你甚至關心它,表明你需要閱讀[一本好的C++書]中的正式和實際參數(http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and -list)。 – 2011-02-23 02:37:51
謝謝你這麼快判斷我。我只包括了這個,因爲我不希望有人提出一些預處理器黑客。 – karpathy 2011-02-23 06:09:45
我刪除了這段話,因爲無論如何,似乎沒人提出這些想法。 – karpathy 2011-02-23 06:12:18