Find a pair in a vector by its first value - c++11

I have a vector which contains several pairs(INT,INT).
I want to search for a particular but I only have one key of that pair.
How should I search for the second key?

You can use the following algorithm (pseudo code):
let vec be the input vector
let key be the value that you are searching
for each pair p in vec
let p_1 be p.first
if p_1 == key
return you have found the key
Here is a functional approach to extract re-usable components:
find_if(beg, end, predicate):
let beg be an iterator to the beginning of a sequence
let end be an iterator to the end of a sequence
let predicate be a function from container element to boolean
for each iterator in beg...end
let element be what the iterator points to
if predicate(element)
return iterator
Now, you can define a custom predicate function:
my_predicate(p):
let p be a pair
let p_1 be p.first
let key be the value that you are searching
return p_1 == key
And use find_if:
let vec be the input vector
found_iterator = find_if(begin(vec), end(vec), my_predicate)
It just so happens that the C++ standard library contains std::find_if with pretty much identical interface to my pseudo code.

Related

Unable to collect a filtered a Vec into itself [duplicate]

This question already has answers here:
is it possible to filter on a vector in-place?
(4 answers)
Closed 3 years ago.
I've started working through the Project Euler problems in Rust and came across #3 where the easiest quick-approach would be to implement a Sieve of Eratosthenes.
In doing so, my algorithm creates an iterator to then filter non-primes out of and assign it back to the original vector, but I'm receiving an error that Vec<u32> can't be built from Iterator<Item=&u32>.
Code:
fn eratosthenes_sieve(limit: u32) -> Vec<u32> {
let mut primes: Vec<u32> = Vec::new();
let mut range: Vec<u32> = (2..=limit).collect();
let mut length = range.len();
loop {
let p = range[0];
primes.push(p);
range = range.iter().filter(|&n| *n % p != 0).collect();
if length == range.len() {
break;
}
length = range.len();
}
primes
}
Error:
error[E0277]: a collection of type `std::vec::Vec<u32>` cannot be built from an iterator over elements of type `&u32`
--> src\main.rs:42:55
|
42 | range = range.iter().filter(|&n| *n % p != 0).collect();
| ^^^^^^^ a collection of type `std::vec::Vec<u32>` cannot be built from `std::iter::Iterator<Item=&u32>`
|
= help: the trait `std::iter::FromIterator<&u32>` is not implemented for `std::vec::Vec<u32>`
Why is the closure wrapping the values in extra borrows?
Explanation
According to the error message, the expression range.iter().filter(|&n| *n % p != 0) is an iterator over items of type &u32: a reference to an u32. You expected an iterator over u32 by value. So let's walk backwards:
The filter(...) part of the iterator chain has actually nothing to do with your problem. When we take a look at Iterator::filter, we see that it returns Filter<Self, P>. This type implements Iterator:
impl<I: Iterator, P> Iterator for Filter<I, P>
where
P: FnMut(&I::Item) -> bool,
{
type Item = I::Item;
// ...
}
The important part here is that type Item = I::Item, meaning that the item type of I (the original iterator) is passed through exactly. No reference is added.
This leaves .iter(): that's the cause of the problem. Vec::iter returns slice::Iter<T> which implements Iterator:
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
// ...
}
And here we see that the item type is a reference to T (the element type of the vector).
Solutions
In general cases, you could call .cloned() on any iterator that iterates over references to get a new iterator that iterates over the items by value (by cloning each item). For types that implement Copy you can (and should) use .copied(). E.g. range.iter().filter(|&n| *n % p != 0).copied().collect().
However, in this case there is a better solution: since you don't need the vector afterwards anymore, you can just call into_iter() instead of iter() in order to directly get an iterator over u32 by value. This consumes the vector, making it inaccessible afterwards. But, as said, that's not a problem here.
range = range.into_iter().filter(|&n| n % p != 0).collect();
Also note that I removed the * in *n, as the dereference is not necessary anymore.
Other hints
Always reallocating a new vector is not very fast. The Sieve of Eratosthenes is classically implemented in a different way: instead of storing the numbers, one only stores Booleans to denote for each number if it's prime or not. The numbers are never stored explicitly, but implicitly by using the indices of the vector/array.
And to make it really fast, one should not use a Vec<bool> but instead a dedicated bitvec. Vec<bool> stores one byte per bool, although only one bit would be necessary. The de-facto crate that offers such a bit vector is bit-vec, which conveniently also shows an example implementation of Sieve of Eratosthenes in its documentation.

Scala: How to create a new list from the weighted difference of two lists added to a third

As part of an implementation of the Differential Evolution algorithm I need to implement the 'mutation' step:
Pick three members from the population at random, they must be distinct from each other as well as from a given member
Calculate a donor member by adding the weighted difference of two of the vectors to the third
This is what I came up with:
// Algorithm types
type Member = List[Double]
type Generation = Vector[Member]
def mutate(index: Int, generation: Generation): Member = {
// Create a random number stream with distinct values
val selector = Stream.continually(Random.nextInt(N)).distinct
// Select 3 mates from the generation
val mates = selector.filter(_ != index).take(3).map(generation(_))
// Calculate the donor member
(mates(0), mates(1), mates(2)).zipped map {
case (e1, e2, e3) => e1 + F * (e2 - e3)
}
}
(I implemented the algorithm as explained here)
Now my question; Is there a better way to implement this step? I have been trying to find a better way to select 3 lists from a vector and zip them together but I couldn't find anything other then putting the selected lists in a tuple manually. The scala compiler gives a warning that instead of mates(0) one should use mates.head, which gives me an indication that this could be implemented in a more elegant way.
Thanks in advance!
You can transpose your mates, and than map over it with a Seq extractor:
mates.transpose map {
case Seq(e1, e2, e3) => e1 + F * (e2 - e3)
}
This will be a Stream[Double], so to get a Member, you'd have to call toList on it, or use mates.toList.transpose ...

Python - Syntax error for taking minimum of tuple by second element

I want to create a list of tuples with first element from a list, and the second element from a function of the element of list, then find the minimum from the output of the function.
The code below best explains what I want:
x,y = min((x,f(x) for x in array), key = lambda(k, v): v[1])
After running the script, I am getting:
SyntaxError: invalid syntax
NOTE: f(x) returns int/float
Update: I wrote my code from another stack overflow question, so I didnt know what exactly I was doing. Can someone explains how key works?
Thanks for the answers :)
You need to add some parenthesis:
x, y = min(((x,f(x)) for x in array), key = lambda t: t[1][1])
I adjusted the lambda expression to work in both Python 2 and 3 (where you cannot use tuple unpacking in the parameter list).
Remember that the key is just a function that is supposed to return the value for which we want to know the minimum. It is called for each element in the input sequence. In this case that's a (x, f(x)) tuple, and you wanted to find the minimum by the second element of the f(x) return value.
I guess you want this:
x,y = min(((x,f(x)) for x in array), key = lambda(k, v): v)
In your list comprehension, the , is not parsed as a tuple expression. You need to wrap it with () to make the parser know.
x,y = min(( (x,f(x)) for x in array), key = lambda(k, v): v[1])
Either add the missing parentheses, or rewrite the code like so:
y, x = min(zip(map(f, array), array))
I've swapped the order of the tuple elements to not have to supply a key function to min().
Here is another version:
x = min(array, key=f)
y = f(x)
It's short and clear, but makes an additional call to f().

Finding list of possible substitutions

Say we have a binary tree as follow:
I'm looking for an algorithm to find all the equivalence of A. I'm given an array that contains elements in this tree. The rule is, if all the children of a node exist in an array, it is equivalent to having the node in the array.
For example, if we have B and C in the array, it is equivalent to having an A. So in the array above, F+G=C, and C+B = A, so [B,F,G] is also equivalent to A. Likewise [D E F G] is also equivalent to A.
I can recursively call something like checkSubstitute(node):
if node in array
return true
else:
for child in nodeChildren
if ((child not in array) && (child == terminalNode))
return false
else
return checkSubstitute(child)
Does this logic make sense? Also how can I store all the equivalent arrays using an algorithm like the one above?
Thanks in advance!!
The method you gave doesn't work properly, since you always return a value during the first iteration of the for loop.
Suppose you have an array [D]. Then checkSubstitute(B) returns True, when it should return False.
Instead of using a for loop, it's easier just to make two explicit calls on both of the children. This assumes every node has either zero or two children. If a node can have one child, some additional null checking is necessary.
#returns true if Node n exists in NodeList seq, or if its equivalent exists in seq.
function exists(n, seq):
if n in seq:
return True
if not n.hasChildren:
return False
return exists(n.leftChild, seq) and exists(n.rightChild, seq)
getting all equivalent arrays just requires a bit of combinatorics.
#gets all possible equivalents for the given node. This includes itself.
#An equivalent is a list of nodes, so this method returns a list of lists of nodes.
function getPossibleEquivalents(node):
ret = new List()
baseCase = new List()
baseCase.append(node)
ret.append(baseCase)
if not node.hasChildren:
return ret
for each leftEquivalent in getPossibleEquivalents(node.leftChild):
for each rightEquivalent in getPossibleEquivalents(node.rightChild):
ret.append(leftEquivalent + rightEquivalent)
return ret
Edit:
You can extend getPossibleEquivalents for trees with exactly 0 or N children, by nesting N for loops:
for each child0Equivalent in getPossibleEquivalents(node.child[0]):
for each child1Equivalent in getPossibleEquivalents(node.child[1]):
for each child2Equivalent in getPossibleEquivalents(node.child[2]):
for each child3Equivalent in getPossibleEquivalents(node.child[3]):
for each child4Equivalent in getPossibleEquivalents(node.child[4]):
ret.append(child0Equivalent + child1Equivalent + child2Equivalent + child3Equivalent + child4Equivalent + child5Equivalent)
If you want to write a single function that can handle trees with any number of children, you need to take the Cartesian Product of each possible equivalent of each child. Some languages implement cartesian product for you already. For example, in python:
from itertools import product
def getPossibleEquivalents(node):
ret = [node]
if len(node.children) == 0: return ret
for equivalentTuple in product(map(getPossibleEquivalents, node.children)):
possibleEquivalent = reduce(lambda x,y: x+y, equivalentTuple)
ret.append(possibleEquivalent)
return ret
This logic will work fine to generate all equivalent representations, but with some repetitions, which you can check and correct if you want to.(I'll follow some python conventions on where to copy things)
suppose you want all possible representations from [B,C]
For each node in this array you can either substitute it for its children or you can leave it intact. So the general idea of the recursion is this:
find_equivalent(representation, node){
// representation is a list which is a valid equivalent representation.
child = list_of_children_of_node;
Temp = representation[:]
for each c in child: Temp.insert(child)
find_equivalent(representation, next(node,representation))
N = next(node,Temp)
Temp.delete(node)
Li.append(Temp)
find_equivalent(Temp, N)
// Here next function takes a list and a node and returns the next element from the list after node.
Above Li is a global array of representations and you need to call the function find_equivalent for each representation as it is added.

Efficient algorithm to remove any map that is contained in another map from a collection of maps

I have set (s) of unique maps (Java HashMaps currently) and wish to remove from it any maps that are completely contained by some other map in the set (i.e. remove m from s if m.entrySet() is a subset of n.entrySet() for some other n in s.)
I have an n^2 algorithm, but it's too slow. Is there a more efficient way to do this?
Edit:
the set of possible keys is small, if that helps.
Here is an inefficient reference implementation:
public void removeSubmaps(Set<Map> s) {
Set<Map> toRemove = new HashSet<Map>();
for (Map a: s) {
for (Map b : s) {
if (a.entrySet().containsAll(b.entrySet()))
toRemove.add(b);
}
}
s.removeAll(toRemove);
}
Not sure I can make this anything other than an n^2 algorithm, but I have a shortcut that might make it faster. Make a list of your maps with the length of the each map and sort it. A proper subset of a map must be shorter or equal to the map you're comparing - there's never any need to compare to a map higher on the list.
Here's another stab at it.
Decompose all your maps into a list of key,value,map number. Sort the list by key and value. Go through the list, and for each group of key/value matches, create a permutation of all the map number pairs - these are all potential subsets. When you have the final list of pairs, sort by map numbers. Go through this second list, and count the number of occurrences of each pair - if the number matches the size of one of the maps, you've found a subset.
Edit: My original interpretation of the problem was incorrect, here is new answer based on my re-read of the question.
You can create a custom hash function for HashMap which returns the product of all hash value of its entries. Sort the list of hash value and start loop from biggest value and find all divisor from smaller hash values, these are possible subsets of this hashmap, use set.containsAll() to confirm before marking them for removal.
This effectively transforms the problem into a mathematical problem of finding possible divisor from a collection. And you can apply all the common divisor-search optimizations.
Complexity is O(n^2), but if many hashmaps are subsets of others, the actual time spent can be a lot better, approaching O(n) in best-case scenario (if all hashmaps are subset of one). But even in worst case scenario, division calculation would be a lot faster than set.containsAll() which itself is O(n^2) where n is number of items in a hashmap.
You might also want to create a simple hash function for hashmap entry objects to return smaller numbers to increase multiply/division performance.
Here's a subquadratic (O(N**2 / log N)) algorithm for finding maximal sets from a set of sets: An Old Sub-Quadratic Algorithm for Finding Extremal Sets.
But if you know your data distribution, you can do much better in average case.
This what I ended up doing. It works well in my situation as there is usually some value that is only shared by a small number of maps. Kudos to Mark Ransom for pushing me in this direction.
In prose: Index the maps by key/value pair, so that each key/value pair is associated with a set of maps. Then, for each map: Find the smallest set associated with one of it's key/value pairs; this set is typically small for my data. Each of the maps in this set is a potential 'supermap'; no other map could be a 'supermap' as it would not contain this key/value pair. Search this set for a supermap. Finally remove all the identified submaps from the original set.
private <K, V> void removeSubmaps(Set<Map<K, V>> maps) {
// index the maps by key/value
List<Map<K, V>> mapList = toList(maps);
Map<K, Map<V, List<Integer>>> values = LazyMap.create(HashMap.class, ArrayList.class);
for (int i = 0, uniqueRowsSize = mapList.size(); i < uniqueRowsSize; i++) {
Map<K, V> row = mapList.get(i);
Integer idx = i;
for (Map.Entry<K, V> entry : row.entrySet())
values.get(entry.getKey()).get(entry.getValue()).add(idx);
}
// find submaps
Set<Map<K, V>> toRemove = Sets.newHashSet();
for (Map<K, V> submap : mapList) {
// find the smallest set of maps with a matching key/value
List<Integer> smallestList = null;
for (Map.Entry<K, V> entry : submap.entrySet()) {
List<Integer> list = values.get(entry.getKey()).get(entry.getValue());
if (smallestList == null || list.size() < smallestList.size())
smallestList = list;
}
// compare with each of the maps in that set
for (int i : smallestList) {
Map<K, V> map = mapList.get(i);
if (isSubmap(submap, map))
toRemove.add(submap);
}
}
maps.removeAll(toRemove);
}
private <K,V> boolean isSubmap(Map<K, V> submap, Map<K,V> map){
if (submap.size() >= map.size())
return false;
for (Map.Entry<K,V> entry : submap.entrySet()) {
V other = map.get(entry.getKey());
if (other == null)
return false;
if (!other.equals(entry.getValue()))
return false;
}
return true;
}

Resources