[英]How to check if a `std::vector<bool>` is true at multiple indexes simultaneously?
我有一個大小為 N 的std::vector<bool>
和一個可變大小的std::vector<std::size_t>
,其中包含[0, N)
中的索引。 檢查第一個向量在第二個向量給出的所有索引處是否為真的慣用方法是什么?
我可能天真的解決方案是:
auto all_true(
std::vector<bool> const& bools, std::vector<std::size_t> const& indexes)
-> bool {
auto res = true;
for (auto index : indexes) {
res = res and bools[index];
}
return res;
}
An idiomatic (though not necessarily efficient ) way to do this would be to use the std::all_of
STL function , using a predicate that simply returns the value of the Boolean vector at the index specified by each value in the size_t
vector.
這是一個大綱/演示:
#include <iostream>
#include <vector>
#include <algorithm>
#include <random>
bool all_true(const std::vector<bool>& data, const std::vector<size_t>& test)
{
return std::all_of(test.begin(), test.end(), [&data](size_t n) { return data[n]; });
}
int main()
{
std::vector<bool> bools{ true, true, true, true, false, false, true, false, true, false };
std::vector<size_t> test1{ 0, 1, 2, 3, 6, 8 }; // all true
std::vector<size_t> test2{ 0, 1, 2, 4, 7, 9 }; // some false
std::cout << "Test1: " << all_true(bools, test1) << "\n";
std::cout << "Test2: " << all_true(bools, test2) << "\n\n";
// Just to show that the order doesn't matter ...
std::cout << "After shuffling ...\n";
std::random_device rdev;
std::mt19937 rgen(rdev());
std::shuffle(test1.begin(), test1.end(), rgen);
std::shuffle(test2.begin(), test2.end(), rgen);
std::cout << "Test1: " << all_true(bools, test1) << "\n";
std::cout << "Test2: " << all_true(bools, test2) << "\n";
return 0;
}
不要認為你的代碼不是慣用的。
基於for()
的范圍可以處理這種情況。 特別是如果您正在編寫一個名為 function 來封裝它。
auto allTrue(std::vector<bool> const& data, std::vector<std::size_t> const& indexs) -> bool
{
for (auto index: indexs) {
if (!data[index]) {
return false;
}
}
return true;
}
基於預范圍的迭代器我會說使用使用迭代器的標准 function。
auto allTrue(std::vector<bool> const& data, std::vector<std::size_t> const& indexs) -> bool
{
return std::all_of(std::begin(indexs), std::end(indexs),
[&data](std::size_t i){return data[i];}
);
}
也許:如果您不打算將其包裝在 function 中,那么在代碼中直接使用此std::all_of()
function 使其更易於閱讀,然后使用它。 但是,如果您正在編寫 function 無論如何都要使用基於的范圍。
或者如果你有 C++20
auto allTrue(std::vector<bool> const& data, std::vector<std::size_t> const& indexs) -> bool
{
return std::ranges::all_of(indexs, [&data](std::size_t i){return data[i];});
}
另一種選擇是std::accumulate
。 如果結果類型和輸入std::vector
元素類型相同,則可以改用(更有效的) std::reduce
。 但是,在這種情況下,您需要(某種程度上)將size_t
s(指向bool
s 的std::vector
的索引)累積到bool
結果中:
#include <iostream>
#include <numeric>
#include <vector>
int main() {
const std::vector<bool> bools{true, true, false, true, true};
const std::vector<size_t> i1{1, 4, 3, 0}; // true && true && true && true
const std::vector<size_t> i2{0, 2, 4, 3}; // true && false && true && true
const auto and_by_idx{
[&bools](bool acc, size_t idx) { return acc && bools[idx]; }};
std::cout << std::boolalpha
<< std::accumulate(i1.begin(), i1.end(), true, and_by_idx) << '\n'
<< std::accumulate(i2.begin(), i2.end(), true, and_by_idx) << '\n';
}
不過,我不會將任何 C++ 解決方案稱為慣用的。 其他一些語言有更短更優雅的表達方式,比如 Python 及其all()
。
bools = (True, True, False, True, True)
i1 = (1, 4, 3, 0) # True && True && True && True
i2 = (0, 2, 4, 3) # True && False && True && True
print(all(bools[i] for i in i1))
print(all(bools[i] for i in i2))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.