2017-03-08 15 views
0

나는 범위 (이 경우 "범위"라는 용어의 모호함으로 인해 "선"이라고 부름)의 범위에서 중복을 제거하는 알고리즘을 작성하고 있습니다. , 감안할 때 세 줄 (0,3), (1,2)와 (5,1)이 내가 얻을 것으로 예상 (0 :range-v3을 사용하여 범위를 쌍으로 변환하는 방법은 무엇입니까?

struct line { 
    int begin, width; 
    int end() const { return begin + width; } 
}; 

예 :

이것은 line이 같은 모습입니다 3), (3,2) 및 (5,1)에 의해 정의된다.

Overlap Removal

이 문제에 대한 하나 개의 가능한 솔루션은 다음과 같습니다 : 다음은이 문제의 그래픽 표현입니다

auto removeOverlap(std::pair<line, line> input) 
{ 
    // keeps first line untouched and shifts the second line to the end of the first one, if necessary 
    return std::pair<line, line>{std::get<0>(input), {std::max(std::get<0>(input).end(), std::get<1>(input).begin), std::get<1>(input).width}}; 
} 

int main(int argc, char *argv[]) 
{ 

    std::array<line, 3> lines{{{0,3},{1,2},{5,1}}}; 
    for(int i = 0; i < lines.size()-1; ++i) 
    { 
     std::tie(lines[i], lines[i+1]) = removeOverlap(std::make_pair(lines[i], lines[i+1])); 
    } 
    assert(lines[0].begin == 0); 
    assert(lines[1].begin == 3); 
    assert(lines[2].begin == 5); 

내 질문 : 어떻게이 사용 범위-V3을 할 수 있습니까?

증가 된 크기가 1 (N 대신) 인 수정 된 view::chunk(N)을 사용하려고합니다. 그러나 나는이 시점에서 어떻게 진행해야 할지를 정말로 모른다.

답변

3

당신은 할 수 있습니다 : 원래 범위의 변환보기로, 다음 순서로 변환 된보기를 반복하는 것이

auto pair_view = 
    ranges::view::zip(lines | ranges::view::take(lines.size() - 1), 
         lines | ranges::view::drop(1)); 

for (auto&& p : pair_view) 
{ 
    p = removeOverlap(p); 
} 

Demo

+1

도사 (... 백 자체에 배열에서 변환하기위한 쉬운 방법을 이해할 수 없었다). 'for' 루프를 여분의 승리를 위해서'ranges :: transform' 알고리즘 호출로 대체하십시오. –

1
auto push_highwater = [](int& highwater){ 
    return [&](line l) { 
    l.begin = (std::max)(highwater, l.begin); 
    highwater = l.end(); 
    return l; 
    }; 
}; 

피드.

min int의 하이 워터로 시작하십시오. Int가 충분히 오래 살도록하십시오.

Live example

+0

또한 올바른 경우보기는 한 번만 반복 가능합니다. – Jarod42

+0

@ Jarod42 두 번째로 이전 요소 세트가 겹쳐지지 않는다고 가정합니다. ;) – Yakk