Search code examples
c++arrayspopulateiota

Populating an array in descending order c++ NOT sorting


I'm trying to generate an an array in descending order, as in actually fill it from scratch. I am not trying to sort given numbers. I wanted to know if there is a way to do it without a for loop. I was able to generate an array in ascending order of number using std::iota, but I haven't been able to (nor do I think I can) use that for generating a descending array. Is there a one liner out there for generating a array of size in descending order?

EDIT: I was able to create an array in ascending order using:

    void generateAscendingArray(int values[], size_t size){
        std::iota(values, values+size, 1);
    }

So it fills the array with numbers corresponding to the size of the array. I am simply looking for an easy way to generate a descending array without a loop, or with minimal lines and work, similar to ascending. I want it to fill the array in accordance to the size of the array just in descending order.


Solution

  • The easiest solution may be to use std::iota but to fill your array from back to front. Use std::rbegin and std::rend to get reverse iterators that iterate in reverse order :

    #include <array>
    #include <iostream>
    #include <iterator>
    #include <numeric>
    
    int main()
    {
        std::array<int, 10> my_data;
        std::iota(std::rbegin(my_data), std::rend(my_data), 0);
        for (auto value : my_data) {
            std::cout << value << ' ';
        }
        std::cout << std::endl;
        return 0;
    }
    

    The output :

    9 8 7 6 5 4 3 2 1 0

    Edit : It seems you are using a pointer to the first element of an array and a size instead of using a proper container object. In that case, std::rbegin and std::rend cannot deduce the size of the pointed array using the pointer alone. You will need to construct your reverse iterators manually as is done in foo in the following example :

    #include <array>
    #include <iostream>
    #include <iterator>
    #include <numeric>
    
    void foo(int * data, size_t size) {
        std::reverse_iterator<int*> first(data + size);
        std::reverse_iterator<int*> last(data);
        std::iota(first, last, 0);
    }
    
    int main()
    {
        int my_data[10];
    
        foo(my_data, sizeof(my_data) / sizeof(*my_data));
    
        for (auto value : my_data) {
            std::cout << value << ' ';
        }
        std::cout << std::endl;
        return 0;
    }
    

    However, you would be better off ditching arrays as containers in favor of standard containers like std::vector or using iterators to express ranges of elements.