I'm using std::array<array<float, 4,3> = . . . to in
I'm having trouble understand how to format the following code so I don't get the following error:
g++ array2d_colors.cpp -o array2dcolors.o
array2d_colors.cpp: In function ‘void arrayStart()’:
array2d_colors.cpp:36:7: error: too many initializers for
‘std::array<std::array<float, 4ul>, 3ul>’ };
^
using namespace;
array<array<float,4>,3> color = {
{ 0.0 , 0.1686 , 0.2117 },
{ 0.0274 , 0.2117 , 0.2588},
{ 0.3450 , 0.4313 , 0.4588},
{ 0.3960 , 0.4823, 0.5137}
};
This code worked in another study:
using namespace;
array<array<float, 2>, 2> a1 = {{{5,6},{7,8}}};
That is a lot of "{'s" . What if a want to create a 16x3?
I'd appreciate some help.
When you're doing
array<array<float,4>,3> color
you're saying that the inner array has 4 elements and the outer one has 3. So it becomes a 4*3 matrix while you're defining a 3*4 matrix.
Try doing :
array<array<float,3>,4> color = {{
{ 0.0 , 0.1686 , 0.2117 },
{ 0.0274 , 0.2117 , 0.2588},
{ 0.3450 , 0.4313 , 0.4588},
{ 0.3960 , 0.4823, 0.5137}
}};
and remember to add {{ - two braces before defining the array of inner arrays and you'll be good to go!
You have the initializer arrays transposed to a 4 x 3 array. Hence, it does not match the declaration of color.
You can use:
array<array<float, 3>, 4> color =
{
{ 0.0 , 0.1686 , 0.2117 }, // 1st of four of the outer array
{ 0.0274 , 0.2117 , 0.2588},
{ 0.3450 , 0.4313 , 0.4588},
{ 0.3960 , 0.4823, 0.5137} // 4th of four of the outer array
};
If you need to have a 3 x 4 array, you have to change the initializer array.
Ex:
array<array<float, 4>, 3> color =
{
{ 0.0 , 0.1686 , 0.2117, 1 }, // 1st of three of the outer array
{ 0.0274 , 0.2117 , 0.2588, 2},
{ 0.3960 , 0.4823, 0.5137, 3} // 3rd of three of the outer array
};
Issue 1: Dimensions are swtitched
array<array<float,3>,4> color = {
// ^ ^
Issue 2: Explicitly mention the type of array in initializer. Compiler can't deduce it.
array<float,3>{ 0.0 , 0.1686 , 0.2117 },
// ^^^^^^^^^^^^
{ 0.0274 , 0.2117 , 0.2588},
{ 0.3450 , 0.4313 , 0.4588},
{ 0.3960 , 0.4823, 0.5137}
Related
I am developing an app in flutter. For which I am using lists of map but there something that I am unable to undertand. Consider the following cases:
SCENARIO 1
void main() {
List<Map<String,String>> _reminders = [];
Map<String , String> _tempMap = {};
for (int i = 0; i < 5; i++) {
_tempMap.clear();
_tempMap.putIfAbsent('M' , () => 'm ' + i.toString());
_tempMap.putIfAbsent('D' , () => 'd : ' + i.toString());
_reminders.add(_tempMap);
// or _reminders.insert(i, _tempMap);
}
print(_reminders.toString());
return;
}
to which the result is as follows
[{M: m 4, D: d : 4}, {M: m 4, D: d : 4}, {M: m 4, D: d : 4}, {M: m 4, D: d : 4}, {M: m 4, D: d : 4}]
SCENARIO 2
void main() {
List<Map<String,String>> _reminders = [];
for (int i = 0; i < 5; i++) {
Map<String , String> _tempMap = {};
_tempMap.putIfAbsent('M' , () => 'm ' + i.toString());
_tempMap.putIfAbsent('D' , () => 'd : ' + i.toString());
_reminders.add(_tempMap);;
}
print(_reminders.toString());
return;
}
to which the result is as follows
[{M: m 0, D: d : 0}, {M: m 1, D: d : 1}, {M: m 2, D: d : 2}, {M: m 3, D: d : 3}, {M: m 4, D: d : 4}]
As far as I understand, these scenarios should give similar results. Also in my use case scenario 2 is the correct way as it gives me the result that I want. Please note the above examples have been changed to similify the question. The usage in my original code is much more complex.
Dart, like many other programming languages including java, stores objects as reference, and not contiguous memory blocks. In the first case, in all the iterations of the loop, you have added the same Map using the _reminders.add(_tempMap). Your intuition that "Everytime I add the Map, a copy is created of the current state of Map and that copy is appended to the list" is incorrect.
From my understanding, both are different
The problem is with _tempMap.clear(); in the SCENARIO 1. You have used the global variable for map object and when you apply clear inside the for loop all the previously added entries will be cleared and map becomes empty.
when i = 0 => {} => clear() => all entries will be cleared => New item inserted.
when i = 1 => {"Item inserted in 0th iteration"} => clear() => all entries will be cleared => New item inserted.
So for every iteration map is cleared and holds only last iterated value. After for loop is completed it contains only the last iterated value(i=4) since we are clearing the global map variable every time when a new iteration starts.
EDIT :
You can print the map values inside the for loop and can check yourself.
for (int i = 0; i < 5; i++) {
print('\n $i => ${_tempMap} \n');
I am trying to a initialise an array of structs in a std::array. I know that the following is a way of initialising an std::array with integers.
std::array<int, 5> arr { {1, 2, 3, 4, 5} };
Scenario:
But, say I have an array of structs like this
struct MyStruct {
const char *char_val_1;
const char *char_val_2;
int int_val_1;
double d_val_1;
} my_struct_obj[] = {
{ "a1b1" , "a2b1" , 1 , 1.1 },
{ "a1b2" , "a3b1" , 2 , 1.2 },
{ "a1b3" , "a4b1" , 3 , 1.3 },
{ "a1b4" , "a5b1" , 4 , 1.4 },
{ "a1b5" , "a6b1" , 5 , 1.5 },
{ "a1b6" , "a7b1" , 6 , 1.6 },
{ "a1b7" , "a8b1" , 7 , 1.7 },
{ "a1b8" , "a9b1" , 8 , 1.8 },
{ "a1b9" , "a10b1" , 9 , 1.9 },
};
Question:
How can I create an std::array of MyStructs each initialised with different set of values?
Just like for integers, provide initializers for each value:
std::array<MyStruct, 9> my_struct_arr = {{
{ "a1b1" , "a2b1" , 1 , 1.1 },
{ "a1b2" , "a3b1" , 2 , 1.2 },
{ "a1b3" , "a4b1" , 3 , 1.3 },
{ "a1b4" , "a5b1" , 4 , 1.4 },
{ "a1b5" , "a6b1" , 5 , 1.5 },
{ "a1b6" , "a7b1" , 6 , 1.6 },
{ "a1b7" , "a8b1" , 7 , 1.7 },
{ "a1b8" , "a9b1" , 8 , 1.8 },
{ "a1b9" , "a10b1" , 9 , 1.9 },
}};
I'm trying to sort coordinates in a vector based on whether they are enveloped or dominated by other coordinates. For example the coordinate [1 , 2 , 1 , 1] is enveloped or dominated by [4, 2 , 1 , 2] even though the 2nd and 3rd values of both coordinates are equal.
Highlight of program. (Complete program online at rextester.com)
int input[18][4] = { { 4 , 3 , 3 , 3 } , { 1 , 5 , 4 , 1 } , { 2 , 4 , 5 , 4 } ,
{ 3 , 1 , 2 , 5 } , { 4 , 2 , 1 , 2 } , { 1 , 3 , 3 , 1 } ,
{ 2 , 3 , 3 , 3 } , { 3 , 1 , 2 , 3 } , { 5 , 2 , 1 , 2 } ,
{ 1 , 4 , 4 , 1 } , { 1 , 1 , 2 , 1 } , { 1 , 2 , 1 , 1 } ,
{ 2 , 1 , 2 , 4 } , { 2 , 2 , 1 , 2 } , { 3 , 1 , 1 , 2 } ,
{ 2 , 1 , 2 , 3 } , { 1 , 1 , 1 , 1 } , { 2 , 1 , 1 , 2 } };
struct Coordinate
{
Coordinate(){}
Coordinate( int (&val)[4] );
bool operator<( const Coordinate& otherCoord ) const;
void print() const;
int value[4];
};
void print( const std::vector<Coordinate>& coord );
int main()
{
std::vector<Coordinate> coord;
coord.assign( input , input + 18 );
print( coord );
std::sort( coord.begin() , coord.end() );
print( coord );
}
Program output is however not what I expected,
[ 1 , 1 , 1 , 1 ]
[ 1 , 4 , 4 , 1 ]
[ 2 , 1 , 1 , 2 ]
[ 2 , 1 , 2 , 3 ]
[ 3 , 1 , 1 , 2 ]
[ 1 , 3 , 3 , 1 ]
[ 2 , 2 , 1 , 2 ]
[ 2 , 1 , 2 , 4 ]
[ 1 , 2 , 1 , 1 ]
[ 1 , 1 , 2 , 1 ]
[ 4 , 3 , 3 , 3 ]
[ 5 , 2 , 1 , 2 ] // <-- ???
[ 3 , 1 , 2 , 3 ]
[ 2 , 3 , 3 , 3 ]
[ 4 , 2 , 1 , 2 ] // <-- ???
[ 3 , 1 , 2 , 5 ]
[ 2 , 4 , 5 , 4 ]
[ 1 , 5 , 4 , 1 ]
For example [ 5 , 2 , 1 , 2 ] envelopes or dominates [ 4 , 2 , 1 , 2 ] yet appears before it as shown in the program output.
What you are asking for is lexicographical ordering that basically amounts to saying the comparison (x1, y1) < (x2, y2) is equivalent to saying if (x1 < x2 || (x1 == x2 && y1 < y2))
The body of your Coordinate::operator< can be modified as follows:
for( int i = 0; i < 4; ++i ) {
if( value[i] > otherCoord.value[i] )
return false;
if (value[i] < otherCoord.value[i] )
return true;
}
return false;
We return false at the end because we are performing strict less-than comparison. When we've reached that line we know that all the elements of both coordinates are identical, so if we return true then we've satisfied <= instead.
However, I would propose that you update this code to use more modern C++. Namely vectors and arrays. This is nice especially because the default operator< for a std::array will perform lexicographical ordering for you. (Additionally you don't have to worry about pointer math because you get to use iterators).
Here is your new class:
template<size_t N>
struct Coordinate
{
Coordinate(){}
Coordinate( std::array<int, N> _val);
bool operator<( const Coordinate& otherCoord ) const;
void print() const;
std::array<int, N> value;
};
And here's how you'd implement operator<:
template<size_t N>
bool Coordinate<N>::operator<( const Coordinate<N>& otherCoord ) const
{
return value < otherCoord.value;
}
And finally main:
int main()
{
std::vector<Coordinate<4>> coords;
coords.assign( input.begin(), input.end() );
print(coords);
std::sort(coords.begin(), coords.end());
print( coords );
}
Prefer the templates for Coordinate so that you can make coordinates of arbitrary dimensionality at compile-time. Right now there is a lot of magic numbering going on to make it all work.
Here's a live demo
I've found the answer and I'm posting here for posterity's sake.
The sorting criterion must define strict weak ordering, which is defined by the following four properties
Accordingly I've re-implemented operator< as follows.
Note: implementation intentionally suboptimal for sake of clarity. (Comparisons should ideally be done once and cached.)
bool Coordinate::operator<( const Coordinate& otherCoord ) const
{
int ltCount = 0;
int gtCount = 0;
for( int i = 0; i < 4; ++i )
{
if( value[i] < otherCoord.value[i] ) ++ltCount;
if( value[i] > otherCoord.value[i] ) ++gtCount;
}
if( ltCount == 4 ) return true; // Strictly less
if( gtCount == 4 ) return false; // Strictly greater
// Neither stritcly greater or less. Create ordering (based on magnitute of first coordinate)
for( int i = 0; i < 4; ++i )
{
if( value[i] == otherCoord.value[i] ) continue;
return( value[i] < otherCoord.value[i] );
}
return false; // this should NEVER happen if coords are NOT equal.
}
This question already has answers here:
Ruby multidimensional array
(10 answers)
Closed 7 years ago.
I had previously created a struct and an array of the same in C++ , now i want to implement the same in Ruby.
/ Number of Elements (Which can be increased) :D
#define ELM_NO 110
struct elem
{
char name[18];
char elm_symbol[5];
double atm_weight;
int elm_melting;
int elm_boiling;
int elm_yearofdis;
int elm_group;
double elm_ionis_e;
};
elem element[ELM_NO] = { {" Hydrogen" ,"H" ,1.0079 ,-259 ,-253 ,1776 ,1 ,13.5984 },
{" Hydrogen" ,"H" ,1.0079 ,-259 ,-253 ,1776 ,1 ,13.5984 } ,
{" Helium" ,"He" ,4.0026 ,-272 ,-269 ,1895 ,18 ,24.5874 } ,
{" Lithium" ,"Li" ,6.941 ,180 ,1347 ,1817 ,1 ,5.3917 } ,
{" Beryllium" ,"Be" ,9.0122 ,1278 ,2970 ,1797 ,2 ,9.3227 } ,
{" Boron" ,"B" ,10.811 ,2300 ,2550 ,1808 ,13 ,8.298 } ,
{" Carbon" ,"C" ,12.0107 ,3500 ,4827 ,0 ,14 ,11.2603 } ,
{" Nitrogen" ,"N" ,14.0067 ,-210 ,-196 ,1772 ,15 ,14.5341 } ,
{" Oxygen" ,"O" ,15.9994 ,-218 ,-183 ,1774 ,16 ,13.6181 } ,
{" Fluorine" ,"F" ,18.9984 ,-220 ,188 ,1886 ,17 ,17.4228 } ,
{" Neon" ,"Ne" ,20.1797 ,-249 ,-246 ,1898 ,18 ,21.5645 } ,
{" Sodium" ,"Na" ,22.9897 ,98 ,883 ,1807 ,1 ,5.1391 } ,
{" Magnesium" ,"Mg" ,24.305 ,639 ,1090 ,1755 ,2 ,7.6462 } ,
{" Aluminum" ,"Al" ,26.9815 ,660 ,2467 ,1825 ,13 ,5.9858 } };
Omitted some parts.
Now , I want to implement in Ruby . The problem is I don't know how to implement 2D arrays from which we can access an Individual Element from the Inner Array.
I have checked on previous Questions , and found that the answers were not either clear or were concerned with Narrays.
Can anybody show me how it's done ?
Here is an samplest example that gives you an idea
anarray = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
puts anarray[1][1]
--output:--
5
I have a collection of lists with each containing around 6 to 7 values. Like,
list1 = 2,4,7,4,9,5
list2 = 4,3,7.3,9,8,1.2
list3 = 2,2.4,7,9,8,5
list4 = 9,1.6,4,3,4,1
list5 = 2,5,7,9,1,4
list6 = 6,8,7,2,1,5
list7 = 4,2,5,2,1,3
Now I want to sort these with index1 as primary and index3 as secondary and index2 as tertiary and so on. That is, the output should be like:
2,2.4,7,9,8,5
2,4,7,4,9,5
2,5,7,9,1,4
4,2,5,2,1,3
6,8,7,2,1,5
9,1.6,4,3,4,1
I want the list order to be sorted for index1 first and if the values are same for index1 than sorting is done on index3 and if further same than on index2. Here the number of lists are less which can increase to 20 and the indexes can grow up to 20 as well.
The algorithm I want to know is the same as that of iTunes song sorting, in which songs with the same album are sorted first and then by artist and then by rank and then by name. That's the album's if album names are the same then sorting is done on the artist if same, then by rank and so on. The code can be in C/C++/tcl/shell.
sort -n -t ',' -k 1 -k 3 -k 2
Feed the lists as individual lines into it.
To do this in Tcl, assuming there's not huge amounts of data (a few MB wouldn't be “huge”) the easiest way would be:
# Read the values in from stdin, break into lists of lists
foreach line [split [read stdin] "\n"] {
lappend records [split $line ","]
}
# Sort twice, first by secondary key then by primary (lsort is _stable_)
set records [lsort -index 1 -real $records]
set records [lsort -index 0 -real $records]
# Write the values back out to stdout
foreach record $records {
puts [join $record ","]
}
If you're using anything more complex than simple numbers, consider using the csv package in Tcllib for parsing and formatting, as it will deal with many syntactic issues that crop up in Real Data. If you're dealing with a lot of data (where “lot” depends on how much memory you deploy with) then consider using a more stream-oriented method for handling the data (and there are a few other optimizations in the memory handling) and you might also want to use the -command option to lsort to supply a custom comparator so you can sort only once; the performance hit of a custom comparator is quite high, alas, but for many records the reduced number of comparisons will win out. Or shove the data into a database like SQLite or Postgres.
You can use STL's sort, and then all you have to do is to write a comparison function that does what you want (the example in the link should be good enough).
Since you asked for a Tcl solution:
set lol {
{2 4 7 4 9 5}
{4 3 7.3 9 8 1.2}
{2 2.4 7 9 8 5}
{9 1.6 4 3 4 1}
{2 5 7 9 1 4}
{6 8 7 2 1 5}
{4 2 5 2 1 3}
}
set ::EPS 10e-6
proc compareLists {ixo e1 e2} {
foreach ix $ixo {
set d [expr {[lindex $e1 $ix] - [lindex $e2 $ix]}]
if {abs($d) > $::EPS} {
return [expr {($d>0)-($d<0)}]
}
}
return 0
}
foreach li [lsort -command [list compareLists {0 2 1}] $lol] {
puts $li
}
Hope that helps.
Here is a C++ solution:
#include <iostream>
#include <vector>
#include <algorithm>
template <typename Array, typename CompareOrderIndex>
struct arrayCompare
{
private:
size_t
size ;
CompareOrderIndex
index ;
public:
arrayCompare( CompareOrderIndex idx ) : size( idx.size() ), index(idx) { }
bool helper( const Array &a1, const Array &a2, unsigned int num ) const
{
if( a1[ index[size-num] ] > a2[ index[size-num] ] )
{
return false ;
}
if( !(a1[ index[size-num] ] < a2[ index[size-num] ]) )
{
if( 1 != num )
{
return helper( a1, a2, num-1 ) ;
}
}
return true ;
}
bool operator()( const Array &a1, const Array &a2 ) const
{
return helper( a1, a2, size ) ;
}
} ;
int main()
{
std::vector< std::vector<float> > lists = { { 2, 4, 7, 4, 9, 5},
{ 4, 3, 7.3, 9, 8, 1.2 },
{ 2, 2.4, 7, 9, 8, 5 },
{ 4, 2, 5, 2, 1, 3 },
{ 9, 1.6, 4, 3, 4, 1 },
{ 2, 5, 7, 9, 1, 4 },
{ 6, 8, 7, 2, 1, 5 },
{ 4, 2, 5, 2, 1, 1 },
};
//
// Specify the column indexes to compare and the order to compare.
// In this case it will first compare column 1 then 3 and finally 2.
//
//std::vector<int> indexOrder = { 0, 2, 1, 3, 4 ,5 } ;
std::vector<int> indexOrder = { 0, 2, 1 } ;
arrayCompare< std::vector<float>, std::vector<int>> compV( indexOrder ) ;
std::sort( lists.begin(), lists.end(), arrayCompare< std::vector<float>, std::vector<int>>( indexOrder ) ) ;
for(auto p: lists)
{
for( unsigned int i = 0; i < p.size(); ++i )
{
unsigned int idx = ( i > (indexOrder.size() -1) ? i : indexOrder[i] ) ;
std::cout << p[idx] << ", " ;
}
std::cout << std::endl ;
}
}