2015-03-31 63 views
0

(不确定这是否是正确的任务) 我正在写一个与经典排序相关的stl风格的算法。 原型为:如何使用end()迭代器扩展范围

template<typename RAIter> 
    void Algo(RAIter first, RAIter last) { 
    .... 
    size_t size = std::distance(first, last); 
    RAIter midIter =first; 
    std::advance(midIter, size/2 - 1); 

    Algo(first, midIter); 
    Algo(midIter + 1, last); 
    .... 
} 

,但它不正确的我,因为,最初 它得到的范围内工作一样: 矢量V; Algo(v.begin(),v.end());然而,在内部,在递归调用中,子范围不包含end()元素。

这种情况下的典型技术是什么?

+0

你是算法内部不一致。你在被排除的末尾调用它,但是你可以递归地调用它,并且结尾被包含和排除。 – chris 2015-03-31 17:31:28

+0

实际上问题是 - 如何为内部呼叫添加end()元素 – amigo421 2015-03-31 17:36:09

+1

如果内部呼叫的合约比用户呼叫的合约不同,则需要不同的功能。 – chris 2015-03-31 17:40:29

回答

0

我会提出两个选择。

  1. (首选)使算法在内部不需要包含last。你的情况是可以做到这样的:

    template<typename RAIter> 
    void Algo(RAIter first, RAIter last) { 
        .... 
        size_t size = std::distance(first, last); 
        if (size <= 1) { 
         // special processing of single-item or empty range 
         return; 
        } 
    
        RAIter midIter =first; 
    
        std::advance(midIter, size/2); 
    
        Algo(first, midIter); // midIter not included 
        Algo(midIter, last); // it's included here instead 
    } 
    
  2. 让包括一个独立的功能,期待与last范围:

    template<typename RAIter> 
    void AlgoImpl(RAIter first, RAIter last) { 
        .... 
        // looks like this is more correct: 
        // size_t size = std::distance(first, last) + 1; 
        size_t size = std::distance(first, last); 
        RAIter midIter =first; 
        std::advance(midIter, size/2 - 1); // and here "- 1" seems wrong 
    
        AlgoImpl(first, midIter); 
        AlgoImpl(midIter + 1, last); 
        .... 
    } 
    
    template<typename RAIter> 
    void Algo(RAIter first, RAIter last) { 
        if (first == last) { 
         return; 
        } 
        AlgoImpl(first, last - 1); 
    } 
    
+0

E.g.容器有6个元素。使用end()进行初始调用时,距离返回6,但在下一步中,返回2而不是预期的3,这很明显,因为初始调用包含带有结束的7个元素,但下一次调用仅获得3个元素而没有结束。 – amigo421 2015-03-31 18:13:25

+0

@ amigo421注意'std :: advance(midIter,size/2);'not'size/2 - 1'。顺便说一下'size/2 - 1'在两种情况下都是错误的,我只是没有编辑第二个。 – 2015-03-31 18:16:23

+0

@ amigo421但可能你不会将范围划分成相等的部分,谁知道 – 2015-03-31 18:19:54