两个排序数组实现中的第k个元素

时间:2014-05-12 17:15:18

标签: c++ iterator

我尝试将两个排序数组算法的着名第k个元素的this c++实现调整到我的应用程序(其中第二个数组按增加订购)。现在,我可以看到两个解决方案:

  1. 通过reverse_iterator将迭代器替换为B(第二个数组)的元素,
  2. 尝试手动执行,例如通过减量将增量替换为B的指针。
  3. 现在,我开始尝试2)不是因为喜欢而是因为我使用reverse_iterator不太好。然而,"解决方案"我没有工作。我想知道如何更改J.F. Sebastian的代码以便为第二个数组使用反向迭代器?

    #include <cmath>
    #include <ctime>
    #include <functional>
    #include <fstream>
    #include <iostream>
    #include <iterator>
    #include <limits>
    #include <vector>
    #include <random>
    #include <inttypes.h>
    #include <math.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <numeric>
    
    #define SIZE(a) (sizeof(a)/sizeof(*a))
    #define NDEBUG 
    
    using namespace std;
    template<class RandomAccessIterator, class Compare>
    typename std::iterator_traits<RandomAccessIterator>::value_type
    nsmallest_iter(RandomAccessIterator firsta,RandomAccessIterator lasta,RandomAccessIterator firstb,RandomAccessIterator lastb,size_t n,Compare less){//https://stackoverflow.com/questions/4607945/how-to-find-the-kth-smallest-element-in-the-union-of-two-sorted-arrays/11698659#11698659 
        assert(std::is_sorted(firsta,lasta,less) && std::is_sorted(firstb,lastb,less));
        const float x_0=*firsta,x_1=*lastb;
        std::cout << x_0 << std::endl; 
        std::cout << x_1 << std::endl;
        for(;;){
            assert(n<static_cast<size_t>((lasta-firsta)+(lastb-firstb)));
            if(firsta==lasta) return *(firstb+n);
            if(firstb==lastb) return *(firsta+n);
            size_t mida=(lasta-firsta)/2;
            size_t midb=(lastb-firstb)/2;
            if((mida+midb)<n){
                if(less(*(firstb+midb),*(firsta+mida))){
                    firstb+=(midb+1);
                    n-=(midb+1);
                } else {
                    firsta+=(mida+1);
                    n-=(mida+1);
                }
            } else {
                if(less(*(firstb+midb),*(firsta+mida))){
                    lasta=(firsta+mida);
                } else {
                    lastb=(firstb+midb);
                }
            }
        }
    }
    

    主要相关部分:

    const int n=*nr,m=*mr,k=*kr-1;
    int i;
    float x[n];
    srand (time(NULL));
    for(i=0;i<n;i++)   x[i]=rand();
    std::sort(x,x+m,std::greater<float>());
    std::sort(x+m,x+n);
    *vr=nsmallest_iter(x,x+m,x+m+1,x+n-1,n-2-k,std::greater<float>());
    

1 个答案:

答案 0 :(得分:1)

使用反向迭代器,您只需对您提供的link中显示的代码进行一些调整:

template<class RandomAccessIterator1, typename RandomAccessIterator2, class Compare>
typename std::iterator_traits<RandomAccessIterator1>::value_type
nsmallest_iter(RandomAccessIterator1 firsta, RandomAccessIterator1 lasta,
               RandomAccessIterator2 firstb, RandomAccessIterator2 lastb,
               size_t n,
               Compare less) {
   ...
}

int v = nsmallest_iter(
      a, a + SIZE(a),
      std::reverse_iterator<int*>(b + SIZE(b)), std::reverse_iterator<int*>(b),
      SIZE(a)+SIZE(b)-1-i,
      std::greater<int>());