Home > Blockchain >  Sorting multidimensional arrays by individual elements in c
Sorting multidimensional arrays by individual elements in c

Time:06-01

I'm just going to come out and ask. I have 500 arrays[127]. I need to sort them all by the value of the very last element in descending order. How would you do this in the most efficient way possible?

EXAMPLE:

float arr1[] = {3,1,4,5};
float arr2[] = {1,2,5,8};
float arr3[] = {102,4,132,2};

OUTPUT:
{arr2,
arr1,
arr3}

CodePudding user response:

Since a raw array is a pointer without size information carried out, your job isn't automatic.

Either you convert all your arrays to std::vector<float> so you can have the last element and then have a std::vector<std::vector<float>> with a custom sort operator to test, or you create a structure that contains the raw array along with size information.

std::vector<float> arr1 = {3,1,4,5}
std::vector<float> arr2 = {1,2,5,8}; 
std::vector<float> arr3 = {102,4,132,2};
std::vector<std::vector<float>> arrays = {arr1,arr2,arr3};

std::sort(arrays.begin(),arrays.end(),[](const std::vector<float>& r1,const std::vector<float>& r2) -> bool
{
   if (r1[r1.size() - 1] < r2[r2.size() - 1]) return true;
   return false;
});


struct ArrAndSize { float* arr; size_t sz; };

ArrAndSize arr1 = {{3,1,4,5},4};
ArrAndSize arr2 = {{1,2,5,8},4}; 
ArrAndSize arr3 = {{102,4,132,2},4};
std::vector<ArrAndSize> arrays = {arr1,arr2,arr3};

std::sort(arrays.begin(),arrays.end(),[](const ArrAndSize& r1,const ArrAndSize& r2) -> bool
{
   if (r1.arr[r1.sz - 1] < r2.arr[r2.sz - 1]) return true;
   return false;
});

In both cases, check if the array has size 0.

CodePudding user response:

Your could create a lightweight wrapper that just stores the begin and end iterators of an array.

#include <iterator>

template<class T>
struct span {
    template<size_t N>
    span(T (&arr)[N]) : m_begin(std::begin(arr)), m_end(std::end(arr)) {}
    
    T* begin() const { return m_begin; }
    T* end() const { return m_end; }

    T& front() const { return *m_begin; }
    T& back() const { return *std::prev(m_end); }

private:
    T* m_begin;
    T* m_end;
};

You could then put these lightweight wrappers in a std::vector<span<int>> and sort that. Note that this will not affect the original arrays in any way and since sorting the vector only moves the spans around and not the actual array data, it should be reasonably fast.

#include <algorithm>
#include <iostream>
#include <vector>

int main() {
    int arr1[] = {3,1,4,5};
    int arr2[] = {1,2,5,8};
    int arr3[] = {102,4,132,2};

    std::vector<span<int>> arrs{
        arr1, arr2, arr3
    };

    // sort on the last element, decending:
    std::sort(arrs.begin(), arrs.end(),[](const auto& lhs, const auto& rhs) {
        return rhs.back() < lhs.back();
    });

    for(auto& arr : arrs) {
        for(auto v : arr) std::cout << v << ' ';
        std::cout << '\n';
    }
}

Output:

1 2 5 8 
3 1 4 5 
102 4 132 2 
  • Related