2010-11-19 16 views
15

Có một thuật toán STL/boost nào sẽ kiểm tra nếu tất cả các phần tử giữa hai trình vòng lặp khớp với một giá trị đã cho không? Hoặc cách khác là một biến vị ngữ trả về true cho tất cả chúng?Có thuật toán STL/boost để kiểm tra tất cả các phần tử trong vùng chứa có khớp với giá trị không?

ví dụ: một cái gì đó giống như

template<class InputIterator, class T> 
InputIterator all_match (InputIterator first, InputIterator last, const T& value) 
{ 
    bool allMatch = true; 
    while(allMatch && first!=last) 
     allMatch = (value == *first++); 
    return allMatch; 
} 

Hoặc

template <class InputIterator, class Predicate> 
bool all_true (InputIterator first, InputIterator last, Predicate pred) 
{ 
    bool allTrue = true; 
    while (allTrue && first != last) 
     allTrue = pred(*first++); 
    return allTrue; 
} 

Trả lời

22

Nếu bạn có thể phủ nhận biến vị ngữ bạn có thể sử dụng lệnh std :: find/std :: find_if và xem nó có trả về phần tử cuối của chuỗi không. Nếu không thì nó trả về kết quả phù hợp.

Bạn có thể điều chỉnh hàm bằng std :: not1 hoặc std :: not_equal_to như vậy bằng cách kết hợp với std :: find_if bạn thực sự có thể làm như vậy bằng cách sử dụng STL mà không cần viết vòng lặp.

bool allMatch = seq.end() == std::find_if(seq.begin(), seq.end(), 
    std::not_equal_to(val)); 
bool allPass = seq.end() == std::find_if(seq.begin(), seq.end(), 
    std::not1(pred)); 
+0

Điều đó sẽ hoạt động tốt. Cảm ơn. – GrahamS

+4

thực sự tôi không nghĩ rằng cú pháp 'not_equal_to()' là hoàn toàn đúng. Tôi có thể làm điều gì đó sai, nhưng tôi đã phải sử dụng 'bind2nd' với nó như thế này:' std :: find_if (seq.begin(), seq.end(), std :: bind2nd (std :: not_equal_to () , val)) ' – GrahamS

2

Bạn có thể sử dụng std: tìm ord std :: find_if để làm điều này.

template <class T> 
struct pred { 
    T t_; 

    pred(const T& value) : t_(value) {} 

    bool operator()(const T &t) 
    { 
     return t != t_; 
    } 
}; 

if (e.cend() == std::find_if(c.cbegin(), c.cend(), pred<T>(value))) 
    print("all match value"); 
+0

Như tôi đã hiểu, hãy tìm và find_if chỉ xác định vị trí khớp đầu tiên trong vùng chứa. Tôi muốn kiểm tra rằng phần tử MỌI giữa các trình vòng lặp là một giá trị đã cho. – GrahamS

+0

Bản chỉnh sửa của tôi có hiển thị cách chỉnh sửa không? – frast

+0

Xin lỗi, vị ngữ của tôi đã quá lo lắng. Tôi đã sửa nó ngay bây giờ. – frast

2

Bạn có thể sử dụng std::equal với biến vị ngữ. Một cái gì đó như:

using namespace std; 
using namespace boost::lambda; 

int main() 
{ 
    vector<int> a; 
    a.push_back(1); 
    a.push_back(1); 
    a.push_back(2); 
    a.push_back(2); 
    a.push_back(3); 
    bool allMatch = equal(a.begin(), a.begin() + 2, a.begin(), _1 == 1); 
    return 0; 
} 
18

C++ 0x giới thiệu std::all_of.

+0

@avakar: Phần 25.1 [thuật toán.general] Nó cũng giới thiệu' std :: any_of' và 'std :: none_of' (và nổi tiếng' std :: copy_if'). –

+0

@avakar: chúng tôi không sử dụng C++ 0x nhưng đó là hữu ích để biết anyway, cảm ơn. – GrahamS

+0

Điều này thật thú vị. Nó cho thấy C++ 0x đặt ra một sự thay đổi hướng tới một giao diện nhân đạo hơn. – wilhelmtell

1

Thông thường bạn chỉ có thể đếm chúng:

template<class FwdIterator, class T> 
InputIterator all_match (FwdIterator first, FwdIterator last, const T& value) 
{ 
    return std::count(first, last, value) == std::distance(first, last); 
} 

không hiệu quả khi iterator là không ngẫu nhiên, hoặc khi nó trả về false. Không hoạt động cho các trình lặp đầu vào.

+0

Cũng không dừng lại ngay sau khi nó không phù hợp, điều này khiến nó ít lý tưởng hơn cho các thùng chứa rất lớn. – GrahamS

Các vấn đề liên quan