2017-03-01 10 views
6

범위 컨테이너를 값 범위 컨테이너를 범위 범위로 분할하여 이웃 범위가 경계 요소를 공유하도록 시도했습니다. 엘리먼트가 제로 범위를 중복 범위 범위로 분할

  • 의 값을 갖는다

    1. 여부 : 영역이 두 기준 fullfills 여부

      using namespace ranges; 
      
      std::vector<int> v = { 1, 2, 3, 0, 4, 0, 5, 0, 6, 7, 8, 0, 0, 9 }; 
      auto myRanges = v | /* something like adjacent split */ 
      for_each(myRanges, [](auto&& range){ std::cout << range << std::endl;}); 
      

      내가 기초 겹치는 하위 범위로 영역 분할하고자 :

      은 다음을 고려 또는 0 값을 갖는 하나 이상의 요소에 인접 함

    원하는 출력 :

    [1,2,3] 
    [3,0,4,0,5,0,6] 
    [6,7,8] 
    [8,0,0,9] 
    

    내 시도 :

    auto degenerate = 
        [](auto&& arg){ 
        return distance(arg) < 2; 
        }; 
    
    auto myRanges = v | view::split(0) | view::remove_if(degenerate); 
    for_each(myRanges, [](auto&& range){ std::cout << range << std::endl;}); 
    

    출력 :

    [1,2,3] 
    [6,7,8] 
    

    내가

    1. "삽입"하는 방법에 손실 해요 3에서 6까지의 범위
    2. 8에서 내가 제대로 귀하의 요구 사항을 이해한다면, 당신은 adjacent_find의 측면에서 발전기를 구현할 수 9
  • +0

    왜 이동 참조를 전달합니까? 그것은 당신의 데이터를 손상시킬 것입니다. – Sugar

    +3

    @Sugar 저는'auto && '의 사용과'&&'가 rvalue reference를 암시한다고 생각한다고 가정합니다. 이 경우 sigil은 rvalue reference를 의미하는 것이 아니라 Scott Meyer가 보편적으로 참조하는 것을 의미합니다. 더보기 (여기) [https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers] – apmccartney

    +1

    [여기] (https://isocpp.org/blog/2012/11)/universal-references-in-c11-scott-meyers)는 apmccartney의 링크의 작동 버전입니다. –

    답변

    2

    의 범위를 "가 추가"

    template<typename IterT> 
    struct seg_generator_ { 
        IterT it_, end_; 
        bool fz_ = true; 
    
        ranges::iterator_range<IterT> operator()() { 
         if (it_ == end_) { 
          return {it_, end_}; 
         } 
    
         auto n = ranges::adjacent_find(
          it_, end_, 
          [fz = std::exchange(fz_, !fz_)](auto const a, auto const b) { 
           return a && !b == fz; 
          } 
         ); 
         return { 
          std::exchange(it_, n), 
          n != end_ ? ranges::next(std::move(n)) : std::move(n) 
         }; 
        } 
    }; 
    
    template<typename RngT> 
    auto seg_generator(RngT&& rng) -> seg_generator_<decltype(ranges::begin(rng))> { 
        return {ranges::begin(rng), ranges::end(rng)}; 
    } 
    
    int main() { 
        std::vector<int> const v{1, 2, 3, 0, 4, 0, 5, 0, 6, 7, 8, 0, 0, 9}; 
        auto myRanges = 
         ranges::view::generate(seg_generator(v)) 
         | ranges::view::take_while([](auto const& r) { return !r.empty(); }); 
        ranges::copy(myRanges, ranges::ostream_iterator<>{std::cout, "\n"}); 
    } 
    

    Online Demo

    희망 사항만큼 간결하지는 않습니다. - [