주어진 조건을 만족하는 nth
요소에 액세스하기위한 두 개의 std::algorithm/lambda function
이 있습니까? std::find_if
이 첫 번째 것을 액세스하므로 nth
을 찾을 수있는 등가물이 있습니까?조건을 만족하는 n 번째 요소를 찾으시겠습니까?
답변
예상 개수에 도달하면 인스턴스 수를 계산하고 완료 할 상태 저장 술어를 만들어야합니다. 이제 문제는 알고리즘을 평가하는 동안 술어가 복사되는 횟수에 대한 보장이 없다는 것입니다. 따라서 술어 그 자체를 외부에서 유지해야하기 때문에 추악합니다.하지만 그렇게 할 수는 있습니다. :이 자주오고, 성능에 대해 우려하지 않는 경우
iterator which;
{ // block to limit the scope of the otherwise unneeded count variable
int count = 0;
which = std::find_if(c.begin(), c.end(), [&count](T const & x) {
return (condition(x) && ++count == 6)
});
};
, 당신은 내부적으로 카운트에있는 shared_ptr을 생성하고 업데이트 술어 어댑터를 작성할 수 있습니다. 동일한 어댑터의 여러 복사본은 동일한 실제 개수 개체를 공유합니다.
또 다른 대안으로는 find_nth_if
을 구현하는 것이 더 간단 할 수 있습니다.
#include <iterator>
#include <algorithm>
template<typename Iterator, typename Pred, typename Counter>
Iterator find_if_nth(Iterator first, Iterator last, Pred closure, Counter n) {
typedef typename std::iterator_traits<Iterator>::reference Tref;
return std::find_if(first, last, [&](Tref x) {
return closure(x) && !(--n);
});
}
그대로 다윗의 대답은 괜찮습니다. 술어는 Boost.Iterator 라이브러리, 특히 boost::filter_iterator
어댑터를 사용하여 반복기로 추상화 될 수 있다는 점을 지적합니다.이 알고리즘은 더 많은 알고리즘 (예 : 계산)에도 사용할 수 있다는 이점이 있습니다.
#include <iostream>
#include <vector>
#include <algorithm>
#include <boost/iterator/filter_iterator.hpp>
template<class ForwardIt, class Predicate, class Size>
ForwardIt find_if_nth(ForwardIt first, ForwardIt last, Predicate pred, Size n)
{
auto vb = boost::make_filter_iterator(pred, first, last);
auto const ve = boost::make_filter_iterator(pred, last, last);
while (vb != ve && --n)
++vb;
return vb.base();
}
int main()
{
auto const v = std::vector<int>{ 0, 0, 3, 0, 2, 4, 5, 0, 7 };
auto const n = 2;
auto const pred = [](int i){ return i > 0; };
auto const nth_match = find_if_nth(v.begin(), v.end(), pred, n);
if (nth_match != v.end())
std::cout << *nth_match << '\n';
else
std::cout << "less than n elements in v matched predicate\n";
}
Live example. 이 인쇄됩니다 2 (2 요소> 0, 1부터 시작 계산이 find_if
일치 n==1
와 find_if_nth
. 술어가 i > 10
로 변경 또는 n 번째 요소가 n = 6
로 변경하는 경우, 그것은 끝 반복자를 반환됩니다.
template<class InputIterator, class NthOccurence class UnaryPredicate>
InputIterator find_nth_if(InputIterator first, InputIterator last, NthOccurence Nth, UnaryPredicate pred)
{
if (Nth > 0)
while (first != last) {
if (pred(*first))
if (!--Nth)
return first;
++first;
}
return last;
}
그리고 당신은 절대적으로 std::find_if
을 사용하려는 경우, 당신은 같은 것을 할 수 : :
[정의되지 않은 동작] (http://coliru.stacked-crooked.com/view?id=02ff2c799552600fb174b17d9eacd458-25783dc5e0579471d3e326cae35dc982) - [find_if_nth]와 일치 시키려면 더 신중하게 진행해야합니다 (http : //coliru.stacked- crooked.com/view?id=2d3e9b6357b3445aa30b374d6a149847-25783dc5e0579471d3e326cae35dc982).n 번째 요소가 존재하지 않는 경우 더 안전한 방법을 알고 계십니까? – Yakk
경계 조건을 지적하기위한 @Yakk tnx. 정말로 그것에 대해 생각하지 않았다면 고칠 것입니다. – TemplateRex
@Yakk 필자는 평소의'find_if'처럼 행동해야하는'find_if_nth'를 작성했고, 일치하는 n 번째 항목이 없을 때 end 반복자를 반환했습니다. 술어가'for' 루프에서 끌어 올려 졌기 때문에 여전히이 솔루션을 좋아합니다. – TemplateRex
STL과 같은 기능 템플릿이 될 것
template<class InputIterator, class NthOccurence class UnaryPredicate>
InputIterator find_nth_if(InputIterator first, InputIterator last, NthOccurence Nth, UnaryPredicate pred)
{
if (Nth > 0) {
do
first = std::find_if(first, last, pred);
while (!--Nth && ++first != last);
return first;
}
else
return last;
}
eehm, 답변은 아직 사용자가 대답으로 표시되어 있습니다 ... – Manu343726
@ Manu343726 : 나는 좋은 대답을 쓸 시간이 너무 많았습니다 :/게다가, 제 대답이 _ 대답보다 우수 할 수도 있습니다. .)) –
나는 보통 너무 많은 시간을 들여 답을 썼다. 그리고 Im은 오랫동안 풀 설명 된 대답을 쓰고 있지만 수천 개의 두 줄의 답이 나옵니다. 나는 너를 이해한다 :) – Manu343726
- 1. 제약 조건을 만족하는 모든 조합을 찾으시겠습니까?
- 2. scala 조건을 만족하는 ListBuffer의 모든 요소를 제거합니다.
- 3. 조건을 만족하는 std :: vector의 마지막 요소를 찾으십시오.
- 4. 조건을 만족하는 첫 번째 열 찾기
- 5. 조건을 만족하는 범위의 첫 번째 셀만 선택하기
- 6. 조건을 만족하는 요소 선택
- 7. 주어진 조건을 만족하는 쿼리
- 8. 특정 제약 조건을 만족하는 n 개의 제품으로 이익 극대화
- 9. 조건을 만족하는 요소를 포함하지 않는 노드에 대한 XPath 쿼리
- 10. 최소 N 개의 조건을 만족하는 M 선택 가능
- 11. 조건을 만족하는 여러 열 선택
- 12. 특정 조건을 만족하는 목록의 요소를 그룹화하는 함수의 일반 버전 만들기
- 13. n 번째 요소를 배열마다 복사합니다.
- 14. 목록에서 n 번째 요소를 버리십시오.
- 15. OCaml에서리스트의 n 번째 요소를 반환합니까?
- 16. R : 조건을 만족하는 행을 찾으십시오.
- 17. 조건을 만족하는 응답을 확인하는 방법
- 18. 일부 조건을 만족하는 색인 얻기
- 19. 조건을 부분적으로 만족하는 MongoDB 결과
- 20. Ruby에서 배열의 조건을 만족하는 모든 요소를 제거하는 방법은 무엇입니까?
- 21. 특정 조건을 만족하는 scipy.sparse 행을 0으로 설정하십시오.
- 22. 조건을 만족하는 맵에서 첫 번째 요소의 인덱스를 반환하는 함수
- 23. 조건을 만족하는 첫 번째 행만 선택하는 방법은 무엇입니까?
- 24. 중첩 목록에서 n 번째 요소의 n 번째 요소를 업데이트하십시오.
- 25. 파이썬에서 조건을 만족하는 모든 것을 계산하십시오.
- 26. 특정 조건을 만족하는 배열에서 행 제거 MATLAB
- 27. 조건을 만족하는 컴퓨터 만 내 보냅니다.
- 28. 조건을 만족하는 모든 열을 삭제하려면 VBA를 조정하십시오.
- 29. 조건을 만족하는 행 번호를 얻는 방법
- 30. 일부 조건을 만족하는 문서에서 필드 삭제
을 가치에 사로 잡힌 '가변적 인'람다도 마찬가지로 효과가 있습니까? – Yakk
@Yakk : 아니요. 알고리즘의 구현은 술어를 복사 할 수있게되어 람다의 다른 인스턴스에서 카운트가 업데이트되고 결과적으로 알고리즘의 결과가 잘못 될 수 있습니다 (M -th, 여기서'M> N' 인스턴스) –
@ DavidRodríguez-dribeas +1하지만 부스트 :: filter_iterator를 사용하면 좀 더 쉽게 접근 할 수 있습니다. 내 대답을 참조하십시오. – TemplateRex