array<string, 7> month31={"January","March","May","July","August","October","December"};
array<string, 4> month30 ={"April","June","September","November"};
array<string, 1> month29 = {"February"};
array<string, 1> month28 = {"February"};
array<string, 4> months= {month31,month30,month29,month28};
I know in python this would work but it keeps crashing. Is there a syntax I am missing?
End goal is to use a for loop to move between the arrays, but if I can't figure that out in time I will have to hard code it all and that will be a pain.
You'll likely be better off using std::vector<std::string> for your (individual) month lists and then a std::array< std::vector<string> > for your composite (note that a std::array of std::array<string, n> would require the element arrays to all be the same length).
Here's a short, illustrative example:
#include <iostream>
#include <string>
#include <array>
#include <vector>
int main()
{
std::vector<std::string> month31 = { "January","March","May","July","August","October","December" };
std::vector<std::string> month30 = { "April","June","September","November" };
std::vector<std::string> month29 = { "February" };
std::vector<std::string> month28 = { "February" };
// The composite list can be a container of the above vector types ...
std::array< std::vector<std::string>, 4 > months = { month31, month30, month29, month28 };
for (auto& vec : months) { // Take REFERENCES (&) to avoid copying.
std::cout << "--- Next List... ---" << std::endl;
for (auto& month : vec) {
std::cout << month << std::endl;
}
}
return 0;
}
Or, you could also use std::vector for the composite; with all other lines in the above code unchanged, just use this for the declaration of months:
std::vector< std::vector<std::string> > months = { month31, month30, month29, month28 };
The (main) difference between vector and array is that, for array, the size, which is fixed at compile time and specified as a template parameter, is also part of the actual type of the object. So, for your 4 components of different lengths, defining each as a std::array would make them types of 4 (or 3, actually) different classes (so they would not be suitable as members of a 'composite' array / vector container).
You declared months as an array of (four) strings, but you want to initialize it with arrays (of strings) - the types don't match. What's more, you want to keep all those arrays in one, while they are all different sizes. Even with auto it wouldn't work.
What you can do is use vector, like:
vector<string> month31 = {"January","March","May","July","August","October","December"};
vector<string> month30 ={"April","June","September","November"};
vector<string> month29 = {"February"};
vector<string> month28 = {"February"};
vector<vector<string>> months= {month31,month30,month29,month28};
#include <iostream>
#include <array>
using namespace std;
int main(){
int a = [];
int b = 10;
std::fill(a);
cout<<a<<endl;
}
I have an array "a" and want to fill it with an integer "b". As I remember in python its simply uses apppend, does someone know solution?
Here one solution how to use your array header.
int b = 10;
std::array<int, 3> a;
std::fill(begin(a), end(a), b);
I have an array "a"
int a = [];
What you have is a syntax error.
As I remember in python its simply uses apppend
A major difference between a C++ array and python list is that the size of C++ array cannot change, and thus nothing can be appended into it.
How to fill array in C++?
There is indeed a standard algorithm for this purpose:
int a[4];
int b = 10;
std::fill_n(a, std::size(a), b);
Decide the size for a, as it is an array not a list. For example:
int a[10];
Then use index values to fill in the array like:
a[0] = 1;
a[1] = 4;
etc.
If you want a dynamic array use std::vector instead
Here is how its done with vectors:
std::vector<int> myvector;
int myint = 3;
myvector.push_back (myint);
Following zohaib's answer:
If your array is of fixed length:
You can use the array's 'fill' member function like this:
a.fill(b);
If your array can change it's size you can use the std's fill function like this:
std::fill(a.begin(), a.end(), b);
There are examples of sorting vectors or dynamically allocated arrays but I couldn't find any help regarding static arrays. Let's say I have an array
int array[10][10];
and a compare function,
bool compare(const int (*a)[10], const int (*b)[10]);
When I call it like this,
std::sort(array, array + 10, compare);
I have compilation errors: error: cannot convert 'int*' to 'const int (*)[10]' in argument passing
I tried many ways, casting array to (void**) in sort function but then I have segmentation fault. My problem is using arrays as function parameters I guess but I couldn't figure out how to use this std::sort. Otherwise, I will have to write my own sort function.
When std::sort is called on a container of elements of type T, the comparison function needs to receive arguments of type T or const T&. In this case, you have a 2-dimensional array, so the type of elements is a 1-dimensional array int[10]. Since 1-dimensional arrays decay to pointers, compare can be:
bool compare(int a[10], int b[10]);
or equivalently:
bool compare(int *a, int *b);
This will fix the error you got, but your code still won't work: std::sort needs the container elements to be assignable (or movable in C++11), but arrays are not assignable.
You can use std::vector<std::vector<int> > instead as people have suggested. Note that your fear of performance problems is misguided: Even if sorting a two-dimensional array was possible, it would involve a lot of copying of one-dimensional arrays which would take a long time. Swapping vectors, on the other hand, is done by simply swapping pointers which is faster. In general, you should not make assumptions about performance if you haven't tested it first.
The comparison function doesn't get an iterator to the element passed but the dereferenced iterator, i.e., the value type. Thus, your comparison function would need to be declared as like the one below:
bool compare(int (&a0)[10], int (&a1)[10]);
You can verify that you can actually call it with array iterators:
compare(*(std::begin(array) + 0), *(std::begin(array) + 1));
However, this won't make it possible to sort you arrays: built-in arrays are not copy-assignable. The easiest way to sort statically sized arrays (where the outer dimension flexible) is to use std::array<T, N>:
std::array<int, 10> array[10];
std::sort(std::begin(array), std::end(array));
I say, if we're gonna use the STL and C++ .. lets write it in a modern style and really use the STL.
My attempt at the problem using modern c++11:
#include <vector>
#include <iostream>
#include <algorithm>
typedef std::vector<int> ArrayInt;
typedef std::vector< std::vector<int> > ArrayData;
bool compare(const ArrayInt& a, const ArrayInt& b) {
std::cout << &(a) << ' ' << &(b) << std::endl;
int sumA = std::accumulate(a.begin(), a.end(), 0);
int sumB = std::accumulate(b.begin(), b.end(), 0);
return sumA < sumB;
}
int main(int argc, char** argv) {
ArrayData array = {
{1,2,4,0,3,7,6,8,3,3},
{13,2,4,0,3,7,6,8,3,3},
{10,2,4,0,3,7,6,8,3,3},
{1,2,4,0,3,7,6,8,3,3},
{16,2,4,0,3,7,6,8,3,3},
{1,2,400,0,3,7,6,8,3,3},
{1,2,4,0,3,7,6,8,3,3},
{120,2,4,0,3,7,6,8,3,3},
{1,2,4,0,3,7,6,8,3,3},
{1,2,4,0,3,7,6,8,3,3}
};
std::sort(array.begin(), array.end(), compare);
for (auto row : array) {
for (int num : row)
std::cout << num << ' ';
std::cout << std::endl;
}
}
It uses accumulate to sum each sub array, and sorts on the sum .. it's super inefficient because it has to sum the same row multiple times .. but it's just there to show off a custom compare function.
As an exercise, I wrote this version that uses async to distribute the summing part over any available cores to do the summing, before the sort. I'm sorry it's getting a bit off topic. I hope it's still useful to some people:
#include <vector>
#include <iostream>
#include <algorithm>
#include <future>
typedef std::vector<int> IntRow;
typedef std::pair<int, IntRow> DataRow;
typedef std::vector<DataRow> DataTable;
int main(int argc, char** argv) {
// Holds the sum of each row, plus the data itself
DataTable array = {
{0, {1,2,4,0,3,7,6,8,3,3}},
{0, {13,2,4,0,3,7,6,8,3,3}},
{0, {10,2,4,0,3,7,6,8,3,3}},
{0, {1,2,4,0,3,7,6,8,3,3}},
{0, {16,2,4,0,3,7,6,8,3,3}},
{0, {1,2,400,0,3,7,6,8,3,3}},
{0, {1,2,4,0,3,7,6,8,3,3}},
{0, {120,2,4,0,3,7,6,8,3,3}},
{0, {1,2,4,0,3,7,6,8,3,3}},
{0, {1,2,4,0,3,7,6,8,3,3}}
};
// Make use of multiple cores if it's efficient enough
// get the sum of each data row
std::vector<std::future<int>> sums(array.size());
auto next = sums.begin();
for (auto& row : array)
*next++ = std::async([](const IntRow& row) { return std::accumulate(row.begin(), row.end(), 0); }, row.second);
// Get the results
auto nextRow = array.begin();
for (auto& sum: sums)
(*nextRow++).first = sum.get();
// Sort it
std::sort(array.begin(), array.end(),
[](const DataRow& a, const DataRow& b) { return a.first < b.first; });
// Print it
for (auto row : array) {
for (int num : row.second)
std::cout << num << ' ';
std::cout << std::endl;
}
}
It needs to be compiled with pthread library or similar:
g++ -O6 sort.cpp --std=c++11 -g -lpthread