How to obtain the index permutation after the sorting

前端 未结 7 1440
野性不改
野性不改 2020-12-13 06:24

Given an array arr = {5, 16, 4, 7}, we can sort it through sort(arr, arr+sizeof(arr)/sizeof(arr[0])). so now the array arr = {4, 5, 7, 16}

相关标签:
7条回答
  • 2020-12-13 07:03

    Yes, there is one with O(NlogN) time.Since the sorting takes O(NlogN) time anyway, this will not affect overall time complexity.
    Time Complexity: O(NlogN)
    Space Complexity:O(N)
    where N=number of elements in input array

    Algorithm:

    1. Make copy of input array(P) call it Q.
    2. Sort input array P.
    3. For each number in Q, do binary search to find index of that element in P.
    0 讨论(0)
  • 2020-12-13 07:09

    Multimap can come to the rescue

    template<typename TIn, typename TOut>
    sortindex(const TIn &first, const TIn &last, TOut &out) {
        using ValT = typename std::decay<decltype(*first)>::type;
        std::multimap<ValT, size_t> sindex;
    
        for(auto p=first; p != last; p++)
            sindex.emplace(*p, std::distance(first, p));
    
        for(auto &&p: sindex)
            *out++ = p.second;
    }
    

    which can be used like this:

    std::vector<size_t> a{32, 22, 45, 9, 12, 15};
    std::vector<size_t> indexes;
    
    sortindex(a.begin(), a.end(), std::back_inserter(indexes));
    

    If a coupling between the sorted values and the index would be need, then the multimap can be directly returned, rather than writing the indexes to the output iterator.

    template<typename TIn>
    auto
    sortindex(const TIn &first, const TIn &last)
        --> std::multimap<typename std::decay<decltype(*first)>::type, size_t> 
    {  // return value can be commented out in C++14
        using ValT = typename std::decay<decltype(*first)>::type;
        std::multimap<ValT, size_t> sindex;
    
        for(auto p=first; p != last; p++)
            sindex.emplace(*p, std::distance(first, p));
    
        return sindex;
    }
    
    0 讨论(0)
  • 2020-12-13 07:10

    Create an array of indexes, fill it with numbers 0..N-1, and sort it using a custom comparator. The comparator should compare items from the original array at indexes lhs and rhs. Sorting the array of indexes this way reorders them as a permutation:

    vector<int> data = {5, 16, 4, 7};   
    vector<int> index(data.size(), 0);
    for (int i = 0 ; i != index.size() ; i++) {
        index[i] = i;
    }
    sort(index.begin(), index.end(),
        [&](const int& a, const int& b) {
            return (data[a] < data[b]);
        }
    );
    for (int i = 0 ; i != index.size() ; i++) {
        cout << index[i] << endl;
    }
    

    This prints 2, 0, 3, 1

    Here is a demo on ideone.

    Note: you can use index to retrieve the data in sorted order:

    for (int i = 0 ; i != index.size() ; i++) {
        cout << data[index[i]] << endl;
    }
    
    0 讨论(0)
  • 2020-12-13 07:16

    Why not put some satellite data? Instead of sorting the numbers, just sort pairs of numbers and their indices. Since the sorting is first done on the first element of the pair, this shouldn't disrupt a stable sorting algorithm.

    For unstable algorithms, this will change it to a stable one.

    But note that if you try sorting this way it generates the index while sorting, not after.

    Also, since knowing the permutation index would lead to a O(n) sorting algorithm, so you cannot do it faster than O(nlogn).

    0 讨论(0)
  • 2020-12-13 07:17

    Well in c++ we can use pair datatype to do this easily. Sample code below;

    arr = {5, 16, 4, 7};
    vector<pair<int,int> >V;
    for(int i=0;i<4;i++){
        pair<int,int>P=make_pair(arr[i],i);
        V.push_back(P);
    }
    
    sort(V.begin(),V.end());
    

    So V[i].first is the ith value and V[i].second is the ith index. So to print the index in the sorted array.

    for(int i=0;i<4;i++)cout<<V[i].second<<endl;
    

    Note that while sorting an array (or vector) of pair items, array is first sorted based on the first values. If two pair have same first value then they are sorted based on their second value.

    0 讨论(0)
  • 2020-12-13 07:18

    I recently had to solve a similar problem in PHP. You create a local compare function to be used by PHP's UASORT sorting algorithm. Call array_keys() on the sorted array, and that should spit out your permutation array.

    // test array

    $tArray = array('2', '10', '1', '23', '8', '3');

    // sort array; to maintain index association, use uasort; else use usort, etc

    uasort($tArray, 'compareSize');

    // the resulting keys are your permutation indexes (if uasort used in previous step)

    $Keys = array_keys($tArray);

    // local compare function

    function compareSize($a, $b) {

    if($a == $b) { return 0; } else { return ($a < $b) ? -1 : 1; }

    }

    ======================================================================= Results:

    sorted =: Array ( [2] => 1 [0] => 2 [5] => 3 [4] => 8 [1] => 10 [3] => 23 )

    keys =: Array ( [0] => 2 [1] => 0 [2] => 5 [3] => 4 [4] => 1 [5] => 3 )

    0 讨论(0)
提交回复
热议问题