2011-06-28 9 views
19

Cho một vùng chứa giá trị boolean (Ví dụ là std::vector<bool>), có hàm chuẩn trả về true nếu tất cả các giá trị là true ("và") hoặc true nếu ít nhất một giá trị là true ("hoặc"), đánh giá ngắn mạch?Có điều gì giống như "std :: và" hoặc "std :: hay" không?

Tôi đã đào máng www.cplusplus.com sáng nay nhưng không thể tìm thấy bất kỳ thứ gì gần gũi.

+0

Bạn có thể dễ dàng thực hiện của riêng bạn ... – Dani

+8

@Dani: Thật vậy. Nhưng ngay cả khi mã là tầm thường, nếu có bất cứ điều gì đã tồn tại, tại sao tôi sẽ viết lại nó? – ereOn

+0

@ereOn, những thứ dễ thực hiện không đi vào C++. nếu bạn muốn thử C# hoặc thậm chí một số thông dịch viên. – Dani

Trả lời

37

Bạn có thể thực hiện bằng cách:

VÀ:

std::find(vector.begin(), vector.end(), false) == vector.end() // all the values are true 

OR:

std::find(vector.begin(), vector.end(), true) != vector.end() //at least one value is true 
+1

Vâng, đôi khi tôi đoán tôi đang tìm kiếm quá khó ... Và tôi thậm chí có thể sử dụng 'find_if' với một đối tượng hàm nếu tôi cần thực hiện một kiểm tra phức tạp hơn về các giá trị. Cảm ơn nhiều ! – ereOn

+3

+1 Đó là thông minh! – fredoverflow

+0

Tôi chấp nhận câu trả lời của FredOverflow bởi vì giải pháp của ông là đơn giản hơn. Upvoted này một cho sự công bằng và bởi vì nó thực sự là thông minh. – ereOn

10

Bạn có thể sử dụng chức năng đối tượng logical_andlogical_or kết hợp với việc giảm tới thực hiện điều đó.

accumulate tính toán mức giảm. Do đó:

bool any = std::accumulate(foo.begin(), foo.end(), false, std::logical_or); 
bool all = std::accumulate(foo.begin(), foo.end(), true, std::logical_and); 

Nên biết trước: đây là không sử dụng đoản mạch (các accumulate chức năng không biết gì về ngắn mạch mặc dù functors làm), trong khi giải pháp thông minh Igor là.

+1

Làm thế nào về 'std :: accumulate' để giảm? – ltjax

+1

@ltjax Duh […] (http://example.com) –

+0

+1. Tôi không biết các chức năng này. Cảm ơn. – ereOn

43

là có một chức năng tiêu chuẩn mà trả về true nếu tất cả các giá trị là đúng ("và")

std::all_of(vec.begin(), vec.end(), [](bool x) { return x; }) 

hoặc đúng nếu ít nhất một giá trị đúng ("hay")

std::any_of(vec.begin(), vec.end(), [](bool x) { return x; }) 

với evalutation ngắn mạch?

Tôi vừa chèn câu lệnh in vào lambda và có, cả hai chức năng đều thực hiện đoản mạch.

+0

+1. Tôi biết điều này sẽ được thêm vào một ngày nào đó. Rất tiếc, tôi không thể sử dụng C++ 0x ngay bây giờ trong dự án của mình, nhưng điều đó rất hữu ích. Cảm ơn bạn. – ereOn

+1

@ereOn: tôi cũng không thể (tại nơi làm việc), vì vậy tôi đã tiếp tục và tạo ra chúng (không phải trong không gian tên, tất nhiên) để giúp di chuyển trong tương lai :) –

+0

như @Morwenn cho biết có thiếu Unary Predicate –

1

Nếu bạn không cần một thuật toán chung cho các loại container khác nhau ...

Khi bạn đang tìm kiếm đánh giá ngắn mạch, bạn có thể cung cấp cho std :: valarray một cơ hội. Đối với and, hãy sử dụng valarray::min() == true cho or bạn có thể sử dụng std::find như đã đề cập bởi Igor.

Trong trường hợp bạn biết số phần tử để lưu trữ tại thời gian biên dịch, bạn thậm chí có thể sử dụng một std :: bitset:

bitset<100> container(); 

//... fill bitset 

bool or = container.any(); 
bool and = container.count() == container.size();