Mencoba mencari elemen minimal vektor 2D dengan lambda
Saat ini saya mencoba menemukan elemen minimum vektor 2D. Saya mencoba berlatih menggunakan fungsi lambda C ++ 11 dan saya pikir ini mungkin praktik yang baik, tetapi sepertinya tidak bisa membuatnya dikompilasi.
Saya sadar bahwa saya dapat melakukan hal berikut:
vector<vector<int>> matrix = {
{1, 2, 3, 4, 5 },
{6, 7, 8, 9, 10 },
{5, 6, 8, 1, 12 },
{1, 7, 2, 4, 18 },
};
int result = std::numeric_limits<int>::max();
for(const auto& row : matrix)
{
int minElemInRow = *std::min_element(row.begin(), row.end());
result = std::min(result , minElemInRow);
}
return result;
tetapi bertanya-tanya apakah hal yang sama bisa dilakukan dengan fungsi lambda. Saat ini, ini upaya terbaik saya:
vector<vector<int>> matrix = {
{1, 2, 3, 4, 5 },
{6, 7, 8, 9, 10 },
{5, 6, 8, 1, 12 },
{1, 7, 2, 4, 18 },
};
return *std::min_element(matrix.begin(), matrix.end(),
[](const auto& row)
{
return *std::min_element(row.begin(), row.end());
});
Saya mendapatkan kesalahan: kesalahan C2672 : 'operator __surrogate_func': tidak ada fungsi kelebihan beban yang cocok ditemukan
Bagaimana saya merasa itu harus berfungsi adalah bahwa min_element luar akan melewati baris pada satu waktu (yang hanya referensi ke vektor), dari mana saya dapat mengembalikan yang terkecil, yang kemudian akan dibandingkan dengan baris lain.
Saya pikir masalahnya mungkin bahwa lambda akan menerima iterator ke vektor ints daripada referensi ke vektor ints, tetapi dereferencing tampaknya tidak membantu.
Adakah cara yang lebih baik untuk melakukan apa yang saya coba lakukan?
@assembly_wizard menunjukkan bahwa min_element menginginkan predikat yang dapat membandingkan dua item yang melewatinya. Itu dua baris. Ini mengarah ke kode berikut:
vector<vector<int>> matrix = {
{1, 2, 3, 4, 5 },
{6, 7, 8, 9, 10 },
{5, 6, 8, 1, 12 },
{1, 7, 2, 4, 18 },
};
auto i = std::min_element(matrix.begin(), matrix.end(),
[](const auto& lhs, const auto& rhs)
{
return *std::min_element(lhs.begin(), lhs.end()) <
*std::min_element(rhs.begin(), rhs.end());
});
Ini akan menemukan baris dengan elemen terkecil. Meskipun saya bisa membuatnya bekerja dengan membungkusnya di std :: min_element lain, itu menjadi jauh lebih kompleks daripada membantu dari jarak jauh. Jika ada yang punya saran yang lebih baik, saya akan senang mendengarnya!
Jawaban
Saya telah menyusun versi kerja yang melakukan apa yang saya sebutkan di komentar:
#include <vector>
#include <algorithm>
#include <iostream>
int main() {
std::vector<std::vector<int>> matrix = {
{1, 2, 3, 4, 5 },
{6, 7, 8, 9, 10 },
{5, 6, 8, 1, 12 },
{1, 7, 2, 4, 18 },
};
std::vector<int> row_minimums(matrix.size());
std::transform(matrix.begin(), matrix.end(), row_minimums.begin(), [](const auto& row) {
return *std::min_element(row.begin(), row.end());
});
auto i = *std::min_element(row_minimums.begin(), row_minimums.end());
std::cout << "Minimum element is: " << i << std::endl;
}
Lihat aksinya di atas gerendel
Ini akan mengambil minimum dari setiap baris secara terpisah, jadi kita dapatkan row_minimums
yang merupakan vektor int, dan kemudian dibutuhkan minimum ini untuk mendapatkan hasil akhir di antara semua baris.
Satu-satunya hal yang membuat kode ini lebih buruk daripada for
versi loop, adalah ia menyimpan semua row_minimums
di memori sekaligus, sebelum menjalankannya min_element
. Sayangnya saya tidak tahu cara untuk melakukan ini secara bersamaan, tapi saya bukan STL terhebat yang diharapkan, jadi mungkin ada jalan.
Opsi lain yang mungkin Anda pertimbangkan adalah pertama-tama menggabungkan matriks 2D menjadi vektor 1D dan kemudian menggunakannya min_element
, atau opsi yang Anda sertakan dalam pengeditan di mana Anda memanggil min_element
3 kali.
Juga, jawaban SO ini tampaknya memiliki info menarik tentang solusi menggunakan boost
pustaka yang mungkin lebih baik, tetapi saya tidak yakin persis apa itu.
Sedikit lebih sederhana: Dengan std :: for_each Anda melakukan iterasi pada setiap vektor dalam matriks, dan mendapatkan elemen minimumnya. Seperti min
yang ditangkap oleh referensi, Anda mendapatkan min dari semuanya.
#include <vector>
#include <algorithm>
#include <iostream>
int main() {
std::vector<std::vector<int>> matrix = {
{1, 2, 3, 4, 5 },
{6, 7, 8, 9, 10 },
{5, 6, 8, 1, 12 },
{1, 7, 2, 4, 18 },
};
int min = std::numeric_limits<int>::max();
std::for_each(matrix.begin(), matrix.end(),
[&min](const auto& v)
{
min = std::min(*min_element(v.begin(), v.end()), min);
}
);
std::cout << "Minimum element is: " << min << std::endl;
}