関数の戻り値が最も小さくなる配列の要素は何番目か
- 2015/06/13
- #C++
関数foo()
と何らかの値の入った配列nyan
があって,
double foo(double arg) {
return std::acos(arg);
}
double nyan[] = {.0, -.1, .3, -.5, .7};
foo(nyan[n])
が最小になるn取得するって感じのコードを某所で見つけた.
こんな感じ.
int result;
double prev = INFINITY;
for (int i = 0; i < 5; i++) {
if (foo(nyan[i]) < prev) {
prev = foo(nyan[i]);
result = i;
}
}
std::cout << result << std::endl; // = 4
別に問題ないんだけれども, とにかくCoolじゃなくて個人的にもにょる…
ってことでこんな感じなのを思いついた. もっとよさ気な書き方があったら教えてくださいー.
動作確認はclang++ -Wall -Wextra -std=c++14 prog.cc
でしました.
std::min_element
これくらい標準ライブラリの何かでパパッとやって終わりそうだなとと思って<algorithm>ヘッダで定義されてる関数一覧を眺めていたら, 面白そうなのを見つけた.
std::min_element
template< class ForwardIt, class Compare > ForwardIt min_element( ForwardIt first, ForwardIt last, Compare comp );
Parameters
first, last - forward iterators defining the range to examine
cmp - comparison function object (i.e. an object that satisfies the requirements of Compare) which returns true if a is less than b.
これを使ってみることにした.
const auto result_itr = std::min_element(std::cbegin(nyan), std::cend(nyan),
[](const auto& a, const auto& b) {
return foo(a) < foo(b);
});
int result = result_itr - std::cbegin(nyan);
std::cout << result << std::endl;
const
とかcbegin()
, cend()
を使わなければもう少し短くなるけれど, 気分的に.
正直Coolになったかは微妙なんだけど, std::min_element
に関しては複雑な比較もできそうで面白いなと思った.
番外編
minがあれば当然maxもある.
std::minmax_element - cppreference.com
そして, 同じく3番目の引数に関数オブジェクトを渡して動作をカスタムできる.
あれ…? もしかして…
#include <algorithm>
#include <array>
#include <iostream>
auto main() -> int {
std::array<int, 5> a{{2, 6, 1, 9, 4}};
auto min = std::min_element(a.cbegin(), a.cend(), [](const auto& a, const auto& b) {
return a > b;
});
auto max = std::max_element(a.cbegin(), a.cend(), [](const auto& a, const auto& b) {
return a > b;
});
std::cout << "std::min_element() : " << *min << std::endl;
std::cout << "std::max_element() : " << *max << std::endl;
}
逆転できちゃったよ()