First define the lambda object, then pass it to the template's type using decltype and also pass it directly to the constructor.
auto comp = []( adjist a, adjlist b ) { return a.second > b.second; };
priority_queue< adjlist_edge , vector<adjlist_edge>, decltype( comp ) >
adjlist_pq( comp );
Answer from Potatoswatter on Stack OverflowFirst define the lambda object, then pass it to the template's type using decltype and also pass it directly to the constructor.
auto comp = []( adjist a, adjlist b ) { return a.second > b.second; };
priority_queue< adjlist_edge , vector<adjlist_edge>, decltype( comp ) >
adjlist_pq( comp );
priority_queue takes the comparator as a template argument. Lambda functions are objects, and thus can't be used as template arguments (only very few types can be, among them integral types).
You can try using decltype there:
priority_queue< adjlist_edge , vector<adjlist_edge>,
decltype( [](adjlist_edge a, adjlist_edge b) -> bool {
if(a.second > b.second){ return true; } else { return false; }
})>
adjlist_pq( [](adjlist_edge a, adjlist_edge b) -> bool {
if(a.second > b.second){ return true; } else { return false; }
} );
Failing that (and it will), you can use function<>:
priority_queue< adjlist_edge , vector<adjlist_edge>,
function<bool(adjlist_edge,adjlist_edge)> >
adjlist_pq( [](adjlist_edge a, adjlist_edge b) -> bool {
if(a.second > b.second){ return true; } else { return false; }
} );
Videos
It's unlikely that the compiler will be able to inline a std::function call, whereas any compiler that supports lambdas would almost certainly inline the functor version, including if that functor is a lambda not hidden by a std::function.
You could use decltype to get the lambda's comparator type:
#include <set>
#include <iostream>
#include <iterator>
#include <algorithm>
int main()
{
auto comp = [](int x, int y){ return x < y; };
auto set = std::set<int,decltype(comp)>( comp );
set.insert(1);
set.insert(10);
set.insert(1); // Dupe!
set.insert(2);
std::copy( set.begin(), set.end(), std::ostream_iterator<int>(std::cout, "\n") );
}
Which prints:
1
2
10
See it run live on Coliru.
Yes, a std::function introduces nearly unavoidable indirection to your set. While the compiler can always, in theory, figure out that all use of your set's std::function involves calling it on a lambda that is always the exact same lambda, that is both hard and extremely fragile.
Fragile, because before the compiler can prove to itself that all calls to that std::function are actually calls to your lambda, it must prove that no access to your std::set ever sets the std::function to anything but your lambda. Which means it has to track down all possible routes to reach your std::set in all compilation units and prove none of them do it.
This might be possible in some cases, but relatively innocuous changes could break it even if your compiler managed to prove it.
On the other hand, a functor with a stateless operator() has easy to prove behavior, and optimizations involving that are everyday things.
So yes, in practice I'd suspect std::function could be slower. On the other hand, std::function solution is easier to maintain than the make_set one, and exchanging programmer time for program performance is pretty fungible.
make_set has the serious disadvantage that any such set's type must be inferred from the call to make_set. Often a set stores persistent state, and not something you create on the stack then let fall out of scope.
If you created a static or global stateless lambda auto MyComp = [](A const&, A const&)->bool { ... }, you can use the std::set<A, decltype(MyComp)> syntax to create a set that can persist, yet is easy for the compiler to optimize (because all instances of decltype(MyComp) are stateless functors) and inline. I point this out, because you are sticking the set in a struct. (Or does your compiler support
struct Foo {
auto mySet = make_set<int>([](int l, int r){ return l<r; });
};
which I would find surprising!)
Finally, if you are worried about performance, consider that std::unordered_set is much faster (at the cost of being unable to iterate over the contents in order, and having to write/find a good hash), and that a sorted std::vector is better if you have a 2-phase "insert everything" then "query contents repeatedly". Simply stuff it into the vector first, then sort unique erase, then use the free equal_range algorithm.
public static int longestStrChain(String[] words) {
Arrays.sort(words, (a, b) -> a.length() - b.length());
HashMap<String, Integer> dp = new HashMap<>();
int max_chain = 0;
for (String word : words) {
dp.put(word, 1);
for (int i = 0; i < word.length(); i++) {
String prev_word = word.substring(0, i) + word.substring(i + 1);
if (dp.containsKey(prev_word)) {
dp.put(word, Math.max(dp.get(word), dp.get(prev_word) + 1));
}
}
max_chain = Math.max(max_chain, dp.get(word));
}
return max_chain;
}Can someone help me understand how doesArrays.sort(words, (a, b) -> a.length() - b.length()); actually work? they said that it's for sorting String array, descending order. I don't even know how this
does work i use the debugging tool and seems like it's looping through the array, i was fine with the for-each-loop sorting until this came in.
for(int i = 0; i<words.length;i++) {
for (int j = i; j < words.length; j++) {
if (words[j].length()<words[i].length()){
swap(j,i,words);
}could someone please explain this to me? the Array.sort is looping too so maybe it's the same?
Comparator#compareTo returns an int; while getTime is obviously long.
It would be nicer written like this:
.sort(Comparator.comparingLong(Message::getTime))
Lambda
The lambda can be seen as the shorthand of somewhat cumbersome anonymous class:
Java8 version:
Collections.sort(list, (o1, o2) -> o1.getTime() - o2.getTime());
Pre-Java8 version:
Collections.sort(list, new Comparator<Message>() {
@Override
public int compare(Message o1, Message o2) {
return o1.getTime() - o2.getTime();
}
});
So, every time you are confused how to write a right lambda, you may try to write a pre-lambda version, and see how it is wrong.
Application
In your specific problem, you can see the compare returns int, where your getTime returns long, which is the source of error.
You may use either method as other answer method, like:
Long.compare(o1.getTime(),o2.getTime())
Notice
- You should avoid using
-inComparator, which may causes overflow, in some cases, and crash your program.
rustic distinct meeting price sand sense rain many alleged instinctive
This post was mass deleted and anonymized with Redact