Radek Simko
Radek Simko

Reputation: 16126

Fill in the int array from zero to defined number

i need to fill in the int[] array in C++ from zero to number defined by variable, but ISO C++ forbids variable length array... How to easily fill in the array? Do i need to allocate/free the memory?

int possibilities[SIZE];
unsigned int i = 0;
for (i = 0; i < SIZE; i++) {
    possibilities[i] = i;
}

btw. if you would ask - Yes, i need exactly standard int[] arrays, no vectors, no maps etc.

Upvotes: 8

Views: 41974

Answers (11)

Unmitigated
Unmitigated

Reputation: 89224

Since C++ 23, ranges::iota can be used to initialize an array or other container with increasing values.

#include <numeric>

// only used for output:
#include <algorithm>
#include <iterator>
#include <iostream>

int main() {
    int arr[5]; // also works the same for std::array<int, 5>, std::vector<int>, etc
    std::ranges::iota(arr, 0); // fills arr with increasing integers starting from 0
    std::ranges::copy(arr, std::ostream_iterator<int>(std::cout, " ")); // 0 1 2 3 4 
}

Alternatively, since C++ 11, std::begin and std::end can be used to get iterators to plain arrays to pass to std::iota.

#include <numeric> // for iota
#include <iterator> // for begin and end
#include <iostream> // output
int main() {
    int arr[5];
    std::iota(std::begin(arr), std::end(arr), 0);
    for (int x : arr) std::cout << x << ' ';
    std::cout << '\n';
}

Upvotes: 0

user12002570
user12002570

Reputation: 1

Assuming SIZE is a constant expression and you're allowed to use std::array, you can create a function template that will allow you to do this at compile time. Note from C++17, std::array<T, N>::begin is constexpr so that you can do all this at compile time.

C++17 Version

template<std::size_t N> std::array<int, N> constexpr make_array()
{
    std::array<int, N> tempArray{};
    int count = 0;
    for(int &elem:tempArray)
    {
        elem = ++count;
    }
    return tempArray;
}
int main()
{
    const int SIZE = 8;
    //-------------------------------V-------->number of elements  
    constexpr auto arr  = make_array<SIZE>();
   

    
    //lets confirm if all objects have the expected value 
    for(const auto &elem: arr)
    {
        std::cout << elem << std::endl; //prints 1 2 3 4 5 6 7 8 with newline in between
    }
    
}

C++17 demo


C++11 Version

But prior to C++17, std::array<T, N>::begin was not constexpr, we will need to modify the above example slightly for C++11 as shown below:

template<std::size_t N> std::array<int, N> make_array()
{
    std::array<int, N> tempArray{};
    int count = 0;
    for(int &elem:tempArray)
    {
        elem = ++count;
    }
    return tempArray;
}
int main()
{
    const int SIZE = 8;
    //---------------------VVVV---->number of elements  
    auto arr  = make_array<SIZE>();
   

    
    //lets confirm if all objects have the expected value 
    for(const auto &elem: arr)
    {
        std::cout << elem << std::endl; //prints 1 2 3 4 5 6 7 8 with newline in between
    }
    
}

C++11 demo

Upvotes: 0

claytonjwong
claytonjwong

Reputation: 844

std::generate() can be used with a mutable lambda function to be more concise. The following C++ snippet will place the values 0..9 inclusive in a vector A of size 10 and print these values on a single line of output:

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

using namespace std;

int main() {
    size_t N = 10;
    vector<int> A(N);
    generate(A.begin(), A.end(), [i = 0]() mutable { return i++; });
    copy(A.begin(), A.end(), ostream_iterator<int>(cout, " "));
    cout << endl;
    return 0;
}

Upvotes: 0

bpavlov
bpavlov

Reputation: 1090

Simply use a dynamic arrays?

type * pointer;
pointer = new type[number_of_elements];

void main() 
{
int limit = 0; // Your lucky number
int * pointer = NULL; 
cout << "Please, enter limit number: ";           
cin >> n;
pointer = new int[limit+1]; // Just to be sure.
    for (int i = 0; i < n; i++) 
    {
         pointer[i] = i; // Another way is: *(pointer+i) = i (correct me if I'm wrong)   
    }
delete [] pointer; // Free some memory
pointer = NULL; // If you are "pedant"
}

I don't pretend this is the best solution. I hope it helps.

Upvotes: -1

jarno
jarno

Reputation: 341

In c++11 you can use std::iota and std::array. Example below fills array sized 10 with values from 1 to 10.

std::array<int, 10> a;
std::iota(a.begin(), a.end(), 1);

Edit Naturally std::iota works with vectors as well.

Upvotes: 34

kalaxy
kalaxy

Reputation: 1658

If you have access to boost then you already have access to an incrementing iterator.

#include <vector>
#include <boost/iterator/counting_iterator.hpp>

std::vector<int> possibilities(
    boost::counting_iterator<int>(0),
    boost::counting_iterator<int>(SIZE));

The counting iterator essentially wraps incrementing a value. So you can automatically tell it the begin and end values and vector will populate itself properly.

As mentioned elsewhere, the resulting vector can be used directly with std::next_permutation.

std::next_permutation(possibilities.begin(),possibilities.end());

Upvotes: 3

xtofl
xtofl

Reputation: 41509

You can use the std::generate_n function:

std::generate_n( myarray, SIZE, increment() );

Where increment is an object that generates numbers:

struct increment {
 int value;
 int operator() () { return ++value; }
 increment():value(0){}
};

Upvotes: 1

UmmaGumma
UmmaGumma

Reputation: 5693

std::vector<int> possibilities;
unsigned int i = 0;
for (i = 0; i < SIZE; i++) {
    possibilities.push_back(i);
}

Use std::vector(you need to include <vector>)

If you want pass vector to std::next_permutation you need to write:

std::next_permutation(possibilities.begin(),possibilities.end());

also you can use vector as C style arrays. &vec[0] returns pointer to C style array.

Upvotes: 2

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272467

As you've found, you cannot create a variable-length array on the stack. So your choices are either to allocate it on the heap (introduces memory-management issues), or to use a std::vector instead of a C-style array:

std::vector<int> possibilities(SIZE);
for (int i = 0; i < SIZE; i++)
{
    possibilities[i] = i;
}

If you want to get even more flashy, you can use STL to generate this sequence for you:

// This is a "functor", a class object that acts like a function with state
class IncrementingSequence
{
public:
    // Constructor, just set counter to 0
    IncrementingSequence() : i_(0) {}
    // Return an incrementing number
    int operator() () { return i_++; }
private:
    int i_;
}

std::vector<int> possibilities(SIZE);
// This calls IncrementingSequence::operator() for each element in the vector,
// and assigns the result to the element
std::generate(possibilities.begin(), possibilities.end(), IncrementingSequence);

Upvotes: 17

Amir
Amir

Reputation: 1979

it should be help u man

int* a = NULL;   // Pointer to int, initialize to nothing.
int n;           // Size needed for array
cin >> n;        // Read in the size
a = new int[n];  // Allocate n ints and save ptr in a.
for (int i=0; i<n; i++) {
    a[i] = 0;    // Initialize all elements to zero.
}
. . .  // Use a as a normal array
delete [] a;  // When done, free memory pointed to by a.
a = NULL;     // Clear a to prevent using invalid memory reference

Upvotes: -2

Skurmedel
Skurmedel

Reputation: 22149

If you make SIZE a constant (macro or const), you can use it to specify the size of your static array. If it is not possible to use a constant, for example you are reading the intended size from outside the program, then yes you will need to allocate the memory.

In short, if you don't know the size at compile time you probably need to allocate the memory at runtime.

Upvotes: 0

Related Questions