what are all the different ways to initialize a c++ array? - c++

class Solution {
public:
int numSquares(int n) {
int dp[n+1];
for(int i=0;i<=n;i++) dp[i]=0; //initializing all the elements to zero
for(int i=1;i<=n;i++){
int t = INT_MAX;
for(int j=1;j<=(int)sqrt(i);j++){
t = min(t,dp[i-j*j]);
}
dp[i] = t+1;
}
return dp[n];
}
};
The above method works perfectly fine but when I tried to initialize the array like this
int dp[n] = {0} //variable sized array cannot be initialized
I am getting error like variable sized array cannot be initialized .
Is there any why to initialize this array instead of using for loop and please explain me why I am getting this error?.

The problem is that in C++, the size of an array must be a compile time constant. So,
int n = 10;
int arr[n] ; //incorrect
The correct way would be:
const int n = 10;
int arr[n]; //correct
You can solve your problem by using:
const int n = 10;
int arr[n] = {0}; //correct now because n is a constant expression
Some more examples:
void func(int n)
{
int arr[n] = {0}; //incorrect because n is passed as a function argument and is therefore not a compile time constant
}
Another example
int n;
cin >> n;
int arr[n] = {0}; //incorrect
You can use std::vector as it is a dynamic sized container.

what are all the different ways to initialize a c++ array?
They are:
default initialisation (which means "no initialisation" in case of trivial objects)
list initialisation
value initialisation (which is list initialisation with an empty list)
why I am getting this error?.
Your program is ill-formed. The size of an array variable must be compile time constant, but n+1 is not.
You are using a language extension. As the error message implies, the language extension doesn't allow all forms of initialisation to be used. You can use default initialisation i.e. "no" initialisation as you did in the first code example.
but what if you are getting the array size as a parameter in a function in class?
Then create a dynamic array. I recommend using std::vector.

what are all the different ways to initialize a c++ array?
That's described here: Aggregate initialization.
The main problem is that VLA:s (variable length arrays) do not exist in standard C++ so instead of int dp[n+1]; you should use std::vector<int> dp(n+1);
Example:
#include <algorithm>
#include <climits>
#include <cmath>
#include <vector>
class Solution {
public:
int numSquares(int n) {
std::vector<int> dp(n + 1); // instead of `int dp[n+1];`
// for(int i=0;i<=n;i++) dp[i]=0; // no need
for(int i = 1; i <= n; i++) {
int t = INT_MAX;
for(int j = 1, end = (int) std::sqrt(i); j <= end; ++j) {
t = std::min(t, dp[i - j * j]);
}
dp[i] = t + 1;
}
return dp[n];
}
};

Related

Create matrix (2d-array) of size specified by parameter input in C++

I am learning C++ with experiencein mostly Python, R and SQL.
The way arrays (and vectors which differes somehow from 1d-arrays? and matrices which are 2d-arrays?) work in C++ seems quite different as I cannot specify the size of dimension of the array with an argument from the function.
A toy-example of my goal is some thing like this:
Have a function my_2d_array which takes two arguments M and N and returns a matrix or 2d-array of dimension (MxN) with elements indicating the position of that element. E.g. calling my_2d_array(4,3) would return:
[[00, 01, 02],
[10, 11, 12],
[20, 21, 22],
[30, 31, 32]]
The main function should execute my_2d_array and be able to potentially perform calculations with the result or modify it.
This is my attempt (with errors):
int my_2d_array(int N, int M) {
int A[N][M];
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
std::string element = std::to_string(i) + std::to_string(j);
A[i][j] = element;
}
}
return A;
}
void main() {
int N, M;
N = 4;
M = 3;
int A[N][M] = my_2d_array(N, M);
// Print the array A
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
std::cout << A[i][j] << " ";
}
std::cout << "\n";
}
}
One (1) dimensional attempt of #JustLearning's suggestion:
int my_array(int N) {
std::array<int, N> A;
for (int i = 0; i < N; i++) {
A[i] = i;
}
return A;
}
int main() {
int N = 4;
int A[N] = my_array(N);
// Print the array A
for (int i = 0; i < N; i++) {
std::cout << A[i] << " ";
}
}
You can use a 2d vector like this
vector<vector int> A;
It works the same way as a 2d array
Welcome to C++! Your function my_2d_array has a couple of issues:
the return type is int, however you are attempting to return an array of ints.
the identifier of an array in C++ is actually a pointer to the first element of that array. Therefore, when you return A, you must be aware of how it should be passed to a new variable in the main part of the code. In particular, your code is passing a reference to a temporary variable A, which is not permitted or safe.
In addition, in C++, unless you know what you're doing, main should always return an int:
int main() { ... }
What is not clear from your question is whether you are attempting to implement your own "array" class, or simply want to use arrays already established in the standard. For the latter, std::array is a good place to start. The advantage is that you can return std::arrays from functions like you return ints or doubles.
std::arrays are good if you plan to work with arrays of fixed size, as the size becomes part of the type: std::array<int, 3> my_array;. Then you can fill it in manually or with member functions of the class (see dox linked above).
If for some reason you prefer to work with arrays of dynamical size (sizes that will change during running your program), std::vector is the way to go.
Finally, if you are actually learning C++ by attempting to implement a container MyArray, you should specify that in your question and be a bit more specific in what help you need.
Here's a working example in 1d:
#include <iostream>
#include <array>
template <int N>
std::array<int, N> my_array() {
std::array<int, N> A;
for (int i = 0; i < N; i++) {
A[i] = i;
}
return A;
}
int main() {
const int N = 4;
std::array<int, N> arr = my_array<N>();
// Print the array A
for (int i = 0; i < N; i++) {
std::cout << arr[i] << " ";
}
}
Since the size of a std::array is included it its type, you need to create a function template, which is basically a function that works for different types. (In C++, std::array<int, 3> and std::array<int, 4> are considered different types.)
In order to use this in main, the index is promoted to a const int, as plain ints can vary during run time, and therefore are not suitable for defining types. (In C++ jargon, look up constant expressions).
Finally, note that both the return type and the type of the variable that receives the value returned by the function must be std::array, not int as you tried in your 1d code.
Following your comment, I can see why you are confused in your attempts to use a matrix in code.
There are many types of containers in C++. Many of them you can find in the standard library (std::vector, std::list, std::set, ...), others you can create yourself or use other libraries. Plain arrays (like int a[5]) are a somewhat unique case because they come from C and are part of the language itself.
A plain array lives on the stack (not very important but you might want to read up on stack vs heap allocations), and refers to a contiguous region of memory.
If you declare some array a like int a[5], you get a region of 5 integers one after the other, and you can point to the first one by just writing a. You can access each of them using a[i] or, equivalently, *(a+i).
If you declare a like int a[5][3], you now get a region of 15 integers, but you can access them slightly differently, like a[i][j], which is equivalent to *(a+i*3+j).
The important thing to you here is that the sizes (5 and 3) must be compile-time constants, and you cannot change them at runtime.
The same is true for std::array: you could declare a like std::array<std::array<int, 3, 5> a and get a similar region of 15 integers, that you can access the same way, but with some convenience (for example you can return that type, whereas you cannot return a plain array type, only a pointer, losing the size information in the process).
My advice is not to think of these arrays as having dimensionality, but as simple containers that give you some memory to work with however you choose. You can very well declare a like std::array<int, 15> a and access elements in a 2D way by indexing like this: a[i*3+j]. Memory-wise, it's the same.
Now, if you want the ability to set the sizes at runtime, you can use std::vector in a similar way. Either you declare a like std::vector<std::vector<int>> a(5, std::vector<int>(3)) and deal with the nested vectors (that initialization creates 5 std::vector<int> of size 3 each), or you declare a as a single vector like std::vector<int> a(15) and index it like a[i*3+j]. You can even make your own class that wraps a vector and helps with the indexing.
Either way, it's rare in C++ to need a plain array, and you should generally use some kind of container, with std::vector being a good choice for a lot of things.
Here is an example of how your code would look like using vectors:
#include <vector>
#include <string>
#include <iostream>
std::vector<std::string> my_2d_array(int N, int M) {
std::vector<std::string> A(N*M);
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
std::string element = std::to_string(i) + std::to_string(j);
A[i*M+j] = element;
}
}
return A;
}
int main() {
int N, M;
N = 4;
M = 3;
std::vector<std::string> A = my_2d_array(N, M);
// Print the array A
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
std::cout << A[i*M+j] << " ";
}
std::cout << "\n";
}
}
And here is a very crude example of a Matrix class used to wrap the vectors:
#include <vector>
#include <string>
#include <iostream>
template<typename T>
class Matrix {
public:
Matrix(int rowCount, int columnCount) : v(rowCount*columnCount), columnCount(columnCount) {}
T& operator()(int row, int column) {
return v[row*columnCount + column];
}
private:
std::vector<T> v;
int columnCount;
};
Matrix<std::string> my_2d_array(int N, int M) {
Matrix<std::string> A(N, M);
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
std::string element = std::to_string(i) + std::to_string(j);
A(i, j) = element;
}
}
return A;
}
int main() {
int N, M;
N = 4;
M = 3;
Matrix<std::string> A = my_2d_array(N, M);
// Print the array A
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
std::cout << A(i, j) << " ";
}
std::cout << "\n";
}
}

Reverse an Array but i'm getting a segmentation error

What am I doing wrong ???
It is giving me an error of segmentation fault .
I don't know what memory i'm accessing ??
#include <iostream>
using namespace std;
int main() {
int t;
int n;
int arr[n];
cin>>t;
cin>>n;
// taking array elements from user
for(int i=0; i<n;i++)
{
cin>>arr[i];
}
// reverse of the array
for(int i=n-1; i>=0;i--)
{
cout<<arr[i];
}
//code
return 0;
}
int n;
You've default initialised this variable. Thus, the value is indeterminate.
int arr[n];
Here, you use that indeterminate value. Thus, the behaviour of the program is undefined.
There are "data flow" languages where using a variable will stop execution waiting for you to initialise it later and continue. C++ isn't such language. You must initialise everything before using the value.
Besides that, n isn't a compile time constant expression. Because the size of the array variable isn't compile time conastant, the progarm is ill-formed in C++.
If you want an array to have a dynamic size, you can use dynamic storage. Simplest way to create a dynamic array is to use std::vector.
For starters you are trying to declare a variable length array
int n;
int arr[n];
Variable length arrays is not a standard C++ feature. Moreover you are using an uninitialized variable n as the size of the array.
Either declare the array with an expected maximum size or use standard container std::vector<int>. At least you should write provided that the compiler supports variable length arrays
int t;
int n = 1;
cin>>t;
cin>>n;
if ( n < 1 ) n = 1;
int arr[n];
//...
Also you are not reversing an array. You are trying to output an array in the reverse order.
To reverse an array you could use standard algorithm std::reverse or you can write an appropriate loop yourself as for example
for ( int i = 0; i < n / 2; i++ )
{
// or use std::swap( arr[i], arr[n-i-1] );
int tmp = arr[i];
arr[i] = arr[n-i-1];
arr[n-i-1] = tmp;
}
and then you can output the reversed array.
You are not allowed to define array with Unknown size in C++ so int arr[n]; is Wrong! and if you have to use arrays and not know the size of it , you should use dynamic array with Pointers like this : int* a = new int[n] and also Deallocate Heap memory with Delete []array_name at end of your program and if it is possible for you not use arrays It's better for you use vectors because the size of it is dynamic.
look at this with vectors :
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//by : Salar Ashgi
int main()
{
int k;
cout<<"Enter number of elements ?\n";
cin>>k;
vector<int> v;
cout<<"--------------------\n";
int x;
for(int i=0;i<k;i++)
{
cout<<"Enter num "<<i+1<<" : ";
cin>>x;
v.push_back(x);
}
reverse(v.begin(),v.end());//algorithm.h
cout<<"Reverse : \n";
for(int i=0;i<k;i++)
{
cout<<v[i]<<" ";
}
}

Invoking function with paremeters, one of which is an array of structures in C++?

I have a program where I have a function that sorts elements of an array of structures by their key field. However, when I invoke the function Insertion(a[],7) - I pass the array and its size, the compiler gives an error expected primary expression before ']' token. I would like to ask what am I doing wrong?
#include <iostream>
using namespace std;
struct CElem
{
int key;
};
CElem a[7];
void Insertion(CElem m[],int n)
{
CElem x;
int i;
int j;
for (i = 0; i < n; i++)
{
x = m[i];
j = i-1;
while (j >= 0 && x.key < m[j].key)
m[j+1] = m[j--];
m[j+1] = x;
}
}
int main()
{
a[0].key=32;
a[1].key=45;
a[2].key=128;
a[3].key=4;
a[4].key=-9;
a[5].key=77;
a[6].key=-7;
Insertion(a[],7);
return 0;
}
you only need to pass the pointer to the start of the array:
Insertion(a, 7);
Your parameter m of the method Insertion is of type CElem*. The variable a is of type CElem* too so you are supposed to give the method just a, like Insertion(a,7);.

Pointers; Simple Allocation of An Array

I get an error under "int dArray[size]" saying that size needs to be a constant. Can someone explain what that means exactly?
I want it to be an array of size 4 and output 1, 3, 5, and 7.
#include <iostream>
using namespace std;
int *AllocateArray(int size, int value){
int dArray[size];
for (int i = 0; i <= size; i++){
dArray[i] = value;
value + 2;
}
}
int main(){
AllocateArray(4, 1);
}
Solved:
Here is the code that ended up working.
#include <iostream>
using namespace std;
int *AllocateArray(int size, int value){
int * Array = new int[size];
for (int i = 0; i < size; i++){
Array[i] = value;
value = value + 2;
}
for (int i = 0; i < size; i++){
cout << Array[i] << endl;
}
return Array;
}
int main(){
int *dArray = AllocateArray(4, 1);
}
In int dArray[size] size is not a constant value. Because of that you are getting that error. What you probably wanted to do was make a new array using a pointer and new like:
int * dArray = new int[size];
C++ requires that the size of arrays are determined at compile-time. As size is determined at runtime, the compiler complains.
If you are interested in having array-like behaviour with a size unknown at compile-time, then consider using std::vector.
The size of array should be a known constant in compile time, so that compiler can allocate correct memory for that array on the stack. Remember that such a declare is for stack variable. If you do want dynamic array, try std::vector.
You have to declare the size of an array using numbers, #define or const unsigned int. Otherwise they are considered variable length arrays.
Example:
const unsigned int MAX_ARRAY_SIZE = 14;
double my_array[MAX_ARRAY_SIZE];

How to initialize a zero array in c++

int M=7;
int N=6;
int i=0;
int x=N*M;
int val3[x] = {};
for(int i=0;i<x;i++)
{
//some calculations
if (my condition)
{
//if this condition ok, change value of val[i]
}
cout << i << " " << val[i] << endl;
}
I want to initialize a zero array(val), I used above codes, but I got an error which says variable size object may not be initialized. is it not possible to initialize zero array? need your help....thanks
C++ does not include variable-length arrays; int val3[ x ] with x non-constant is a feature of C99. Not all C99 features are part of C++. Try using std::vector.
#include <vector>
// contains an array of length x, automatically filled with zeroes
std::vector< int > val3( x );
int val3[x] = {};
C++ doesn't allow arrays to be initialized with a variable that isn't a compile-time constant. Use a const int for all the variables (except i).
Btw, you don't use that first int i (outside the loop).
Alternatively to the std::vector suggested above, you could also do:
int M=7;
int N=6;
int x=N*M;
int* val3 = new int[x];
memset(val3, 0, x * sizeof (int));
for (int i = 0; i < x; i++)
{
// ...
}
// ...
delete [] val3;