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 开发者_如何学Pythonwould ask - Yes, i need exactly standard int[] arrays, no vectors, no maps etc.
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.
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);
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());
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.
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){}
};
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.
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;
}
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
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.
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
精彩评论