I have a List of CustomObjects that I need to sort. First the objects should be sorted after their property dateTime and if that is the same, it should be sorted after another property, the compare-property.
I searched for multisort and found this:
medcimentNotificationListData.sort((med1, med2) {
var r = med1.datetime.compareTo(med2.datetime);
if (r != 0) return r;
return med1.mealTimeDescription.compareValue
.compareTo(med2.mealTimeDescription.compareValue);
});
But when printing the list right after it, the list is not sorted..
medcimentNotificationListData.forEach((medicamentNotificationData) {
print(
'${medicamentNotificationData.title}, order: ${medicamentNotificationData.mealTimeDescription.compareValue}');
});
What am I missing here? Is there an easy way to multisort?
Let me know if you need any more info!
when you are calling the sort() method the function calls (a, b) { // your function} which should return either -1 , 0 or 1 . this function is called on the existing order.
at first your element a is your first element and element b is second element of the list as the existing order of the list
if your function returns -1 it means your element a should be placed before the element b therefore it places a before the b and call the function again by replacing older element b as new element a and new element b will be the element after the old b element.
if your function returns 0 it means elements a and b are both same. therefore it places a before the b and call the function again by replacing older element b as new element a.
but when your function returns the 1 it means your element a is coming after the element b. therefore the function is called again by replacing element a with the element before the old element a.
Following code shows how this is works
final List<int> list = [1, 0, 3, 4, 2 , 6, 8, 2 , 5];
list.sort((a,b) {
print("a : $a, b : $b");
int result = a.compareTo(b);
print('result : $result \n');
return result;
});
output
a : 1, b : 0
result : 1
a : 1, b : 3
result : -1
a : 3, b : 4
result : -1
a : 4, b : 2
result : 1
a : 3, b : 2
result : 1
a : 1, b : 2
result : -1
a : 4, b : 6
result : -1
a : 6, b : 8
result : -1
a : 8, b : 2
result : 1
a : 6, b : 2
result : 1
a : 4, b : 2
result : 1
a : 3, b : 2
result : 1
a : 2, b : 2
result : 0
a : 8, b : 5
result : 1
a : 6, b : 5
result : 1
a : 4, b : 5
result : -1
I have the following code, originally programmed using C++11's regular expressions library (#include <regex>) but now using Boost in an attempt to troubleshoot:
boost::regex reg(R"(.*?((?:[a-z][a-z]+)).*?((?:[a-z][a-z]+)).*?((?:[a-z][a-z]*[0-9]+[a-z0-9]*)).*?((?:[a-z][a-z]+)).*?((?:[a-z][a-z0-9_]*)).*?((?:[a-z][a-z0-9_]*)).*?(\d+).*?((?:[a-z][a-z0-9_]*)).*?((?:[a-z][a-z0-9_]*)).*?((?:[a-z][a-z0-9_]*)).*?(\d+).*?((?:[a-z][a-z0-9_]*)).*?(\d+).*?((?:[a-z][a-z0-9_]*)).*?((?:[a-z][a-z0-9_]*)).*?((?:[a-z][a-z0-9_]*)).*?(\d+).*?((?:[a-z][a-z0-9_]*)).*?(\d+).*?((?:[a-z][a-z]+)).*?(\d+).*?((?:[a-z][a-z]+)))", boost::regex::icase);
boost::cmatch matches;
if (boost::regex_match(request, reg) && matches.size() > 1)
{
printf("Match found");
}
else
{
printf("No match.");
}
When executed, this code seems to "freeze" on boost::regex_match(request, reg), as if it's taking a long time to process. I waited five minutes for it to process (in case this is a processing issue) but the program state was the same.
I tested the STL's regex library version of the above code online on cpp.sh and onlinegdb, and it works flawlessly there. I then copied this code into a VC++ project, and the code freezes again:
#include <iostream>
#include <string>
#include <regex>
int main()
{
std::string request = "\\login\\\\challenge\\jRJkdflp3gvTzrwiQ3tyKSqnyppmaZog\\uniquenick\\Lament\\partnerid\\0\\response\\4767846ef255a88da9b10f7c923a1e6e\\port\\-14798\\productid\\11489\\gamename\\crysiswars\\namespaceid\\56\\sdkrevision\\3\\id\\1\\final\\";
std::regex reg(R"(.*?((?:[a-z][a-z]+)).*?((?:[a-z][a-z]+)).*?((?:[a-z][a-z]*[0-9]+[a-z0-9]*)).*?((?:[a-z][a-z]+)).*?((?:[a-z][a-z0-9_]*)).*?((?:[a-z][a-z0-9_]*)).*?(\d+).*?((?:[a-z][a-z0-9_]*)).*?((?:[a-z][a-z0-9_]*)).*?((?:[a-z][a-z0-9_]*)).*?(\d+).*?((?:[a-z][a-z0-9_]*)).*?(\d+).*?((?:[a-z][a-z0-9_]*)).*?((?:[a-z][a-z0-9_]*)).*?((?:[a-z][a-z0-9_]*)).*?(\d+).*?((?:[a-z][a-z0-9_]*)).*?(\d+).*?((?:[a-z][a-z]+)).*?(\d+).*?((?:[a-z][a-z]+)))", std::regex::icase);
std::smatch matches;
if (std::regex_search(request, matches, reg) && matches.size() > 1)
{
printf("Match found");
}
else
{
printf("No match.");
}
}
The string concerned is the following:
\login\challenge\jRJwdflp3gvTrrwiQ3tyKSqnyppmaZog\uniquenick\User\partnerid\0\response\4767846ef255a83da9b10f7f923a1e6e\port-14798\productid\11489\gamename\crysiswars\namespaceid\56\sdkrevision\3\id\1\final\
I tested the same code on a Visual Studio 2017 installation on another computer (brand new project) and get the exact same result... which seems to indicate that something that the compiler is doing is causing the code to freeze/take a long time processing. I am unable to test on another compiler locally at present.
The regular expression string checks out on regex101, so functionally the expression is OK.
This is with Visual Studio 2017 Professional targeting v141.
Why is this happening, and how can I fix it?
Your problem is one of backtracking.
In the boost sample, you use regex_match which forces a match on the
whole string.
You will get the same result if using regex_search and adding ^..$.
However, your string can never match because you have forced it to end
on a letter, but the string really ends with a backslash .
This forces the engine to retry all those .*? positions.
The fix is to put a final .*? at the end of your regex which will let
the regex fulfill it's mission of matching the entire string.
Other things may help, you could clean up your regex a bit and/or add some
atomic groups and/or add some slashes in place of those .*?
Anyway, use this :
^.*?((?:[a-z][a-z]+)).*?((?:[a-z][a-z]+)).*?((?:[a-z][a-z]*[0-9]+[a-z0-9]*)).*?((?:[a-z][a-z]+)).*?((?:[a-z][a-z0-9_]*)).*?((?:[a-z][a-z0-9_]*)).*?(\d+).*?((?:[a-z][a-z0-9_]*)).*?((?:[a-z][a-z0-9_]*)).*?((?:[a-z][a-z0-9_]*)).*?(\d+).*?((?:[a-z][a-z0-9_]*)).*?(\d+).*?((?:[a-z][a-z0-9_]*)).*?((?:[a-z][a-z0-9_]*)).*?((?:[a-z][a-z0-9_]*)).*?(\d+).*?((?:[a-z][a-z0-9_]*)).*?(\d+).*?((?:[a-z][a-z]+)).*?(\d+).*?((?:[a-z][a-z]+)).*?$
Output
** Grp 0 - ( pos 0 : len 207 )
\login\challenge\jRJwdflp3gvTrrwiQ3tyKSqnyppmaZog\uniquenick\User\partnerid\0\response\4767846ef255a83da9b10f7f923a1e6e\port-14798\productid\11489\gamename\crysiswars\namespaceid\56\sdkrevision\3\id\1\final\
** Grp 1 - ( pos 1 : len 5 )
login
** Grp 2 - ( pos 7 : len 9 )
challenge
** Grp 3 - ( pos 17 : len 32 )
jRJwdflp3gvTrrwiQ3tyKSqnyppmaZog
** Grp 4 - ( pos 50 : len 10 )
uniquenick
** Grp 5 - ( pos 61 : len 4 )
User
** Grp 6 - ( pos 66 : len 9 )
partnerid
** Grp 7 - ( pos 76 : len 1 )
0
** Grp 8 - ( pos 78 : len 8 )
response
** Grp 9 - ( pos 94 : len 25 )
ef255a83da9b10f7f923a1e6e
** Grp 10 - ( pos 120 : len 4 )
port
** Grp 11 - ( pos 125 : len 5 )
14798
** Grp 12 - ( pos 131 : len 9 )
productid
** Grp 13 - ( pos 141 : len 5 )
11489
** Grp 14 - ( pos 147 : len 8 )
gamename
** Grp 15 - ( pos 156 : len 10 )
crysiswars
** Grp 16 - ( pos 167 : len 11 )
namespaceid
** Grp 17 - ( pos 179 : len 2 )
56
** Grp 18 - ( pos 182 : len 11 )
sdkrevision
** Grp 19 - ( pos 194 : len 1 )
3
** Grp 20 - ( pos 196 : len 2 )
id
** Grp 21 - ( pos 199 : len 1 )
1
** Grp 22 - ( pos 201 : len 5 )
final
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.
}
I'm trying to find out the coverage of my source code by GCOV. And follow is a part of the result:
328 : 8 : char* GetNumber() {
329 [ + - ][ + - ]: 8 : Log(__FILE__, __LINE__, CLASS_NAME, "Enter GetAccountNumber", "");
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
330 [ + - ][ + - ]: 8 : Log(__FILE__, __LINE__, CLASS_NAME, "Leave GetAccountNumber", "");
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
331 [ + - ]: 8 : return this->Number.c_str();
332 : : }
I did'n use the option -coverage, and as default, coverage option is enable.
I wonder why branch data looks so wierd. The GCOV document said:
’ + ’: Branch was taken at least once
’ - ’: Branch was not taken
’ # ’: The basic block containing the branch was never executed
so why there 4 +/- in every line, and even in the line there are no "line".
I want to know programmatic way to get the memory consumed by my user defined class.
Following is the declaration of the class
struct TrieNode {
typedef std::map<char, TrieNode *> ChildType;
std::string m_word;
bool m_visited;
}
I have inserted around 264061 words into this Trie. After this when i do sizeof(trieobject) it just show me 32. How do i know how much exact memory is used by such data structures.
I use
valgrind --tool=massif ./myprogram -opt arg1 arg2
ms_print massif.* | less -SR
for that. Sample output from this page
19.63^ ###
| #
| # ::
| # : :::
| :::::::::# : : ::
| : # : : : ::
| : # : : : : :::
| : # : : : : : ::
| ::::::::::: # : : : : : : :::
| : : # : : : : : : : ::
| ::::: : # : : : : : : : : ::
| ###: : : # : : : : : : : : : #
| ::# : : : # : : : : : : : : : #
| :::: # : : : # : : : : : : : : : #
| ::: : # : : : # : : : : : : : : : #
| ::: : : # : : : # : : : : : : : : : #
| :::: : : : # : : : # : : : : : : : : : #
| ::: : : : : # : : : # : : : : : : : : : #
| :::: : : : : : # : : : # : : : : : : : : : #
| ::: : : : : : : # : : : # : : : : : : : : : #
0 +----------------------------------------------------------------------->KB 0 29.48
Number of snapshots: 25
Detailed snapshots: [9, 14 (peak), 24]
The remainder of the log details the highest percentiles of memory allocations, you can specifically see what type of class takes what % of heap memory (and where the allocations originate in terms of call stack), e.g.:
--------------------------------------------------------------------------------
n time(B) total(B) useful-heap(B) extra-heap(B) stacks(B)
--------------------------------------------------------------------------------
10 10,080 10,080 10,000 80 0
11 12,088 12,088 12,000 88 0
12 16,096 16,096 16,000 96 0
13 20,104 20,104 20,000 104 0
14 20,104 20,104 20,000 104 0
99.48% (20,000B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
->49.74% (10,000B) 0x804841A: main (example.c:20)
|
->39.79% (8,000B) 0x80483C2: g (example.c:5)
| ->19.90% (4,000B) 0x80483E2: f (example.c:11)
| | ->19.90% (4,000B) 0x8048431: main (example.c:23)
| |
| ->19.90% (4,000B) 0x8048436: main (example.c:25)
|
->09.95% (2,000B) 0x80483DA: f (example.c:10)
->09.95% (2,000B) 0x8048431: main (example.c:23)
Well, this is not so easy to do. First of all m_word is a string with variable size right? Internally the std::string holds an array of chars among other things. The same stands for std::map. I guess you could get a rough estimation based on the size of the map * TrieNode but this will be just a rough estimate.
I think some code profiling with an external tool would be of more help. Hell you can even use the task manager if you are out of any tools left :).
Your "object size" is sizeof(std::string) + sizeof(bool) + m_word.capacity() + padding bytes or sizeof(trieobject) + m_word.capacity()
Here's a piece of code for GCC that I came up with that you can use in a test program where you only instantiate one object of your class and do some typical work with it. The code replaces the global operator new() and operator delete(); so it will only track allocations through ::new expressions and the standard allocator, provided that the standard allocator itself uses ::operator new() (this is the case for GCC).
Since we need to track the pointers and their allocations, we need a separate map for that, which of course cannot use the standard allocator itself; GCC's malloc-allocator comes to the rescue.
We use a statically initialized global to make the memory tracker print its data after main returns.
#include <unordered_map>
#include <string>
#include <iostream>
#include <ext/malloc_allocator.h>
struct Memtrack
{
typedef std::unordered_map<void*, std::size_t, std::hash<void*>,
std::equal_to<void*>, __gnu_cxx::malloc_allocator<void*>> AllocMap;
static int memtrack;
static int memmax;
static AllocMap allocs;
Memtrack() { std::cout << "starting tracker: cur = " << memtrack << ", max = " << memmax << ".\n"; }
~Memtrack() { std::cout << "ending tracker: cur = " << memtrack << ", max = " << memmax << ".\n"; }
static void track_new(std::size_t n, void * p)
{
memtrack += n;
if (memmax < memtrack) memmax = memtrack;
allocs[p] = n;
std::cout << "... allocating " << n << " bytes...\n";
}
static void track_delete(void * p)
{
const int n = int(allocs[p]);
memtrack -= n;
std::cout << "... freeing " << n << " bytes...\n";
}
} m;
int Memtrack::memtrack = 0;
int Memtrack::memmax = 0;
Memtrack::AllocMap Memtrack::allocs;
void * operator new(std::size_t n) throw(std::bad_alloc)
{
void * const p = std::malloc(n);
Memtrack::track_new(n, p);
return p;
}
void operator delete(void * p) throw()
{
Memtrack::track_delete(p);
std::free(p);
}
int main()
{
std::cout << "Beginning of main.\n";
std::unordered_map<std::string, int> m; // this piece of code
m["hello"] = 4; // is a typical test for working
m["world"] = 7; // with dynamic allocations
std::cout << "End of main.\n";
}
Some typical output:
starting tracker: cur = 0, max = 0.
Beginning of main.
... allocating 48 bytes...
... allocating 12 bytes...
... allocating 12 bytes...
End of main.
... freeing 12 bytes...
... freeing 12 bytes...
... freeing 48 bytes...
ending tracker: cur = 0, max = 72.
Trivial. If you have some time (which might be the case, if you are only interested in the size for debugging/optimising purposes). This approach might be unsuited for production code!
#include <malloc.h>
template <typename T> int objSize(T const* obj) {
// instead of uordblks, you may be interested in 'arena', you decide!
int oldSize = mallinfo().uordblks;
T* dummy = new T(*obj);
int newSize = mallinfo().uordblks;
delete dummy;
return newSize - oldSize;
}