I want to input data in a map at its depth. It is easy to do the following:
static Map map;
insert(keyList, x) {
if(keyList.length==1) map[0] = x;
if(keyList.length==2) map[keyList[0]][keyList[1]] = x;
...
}
I would, however, like a more intuitive way to do the same (i.e. using a loop over the keyList) which does not rely on hardcoding iterations.
My attempt at implementing the same led to a resource-heavy recursive implementation:
Map insertInMap(Map<String, dynamic> m, List<String> keyList, Object o) {
if (keyList.length == 1) {
m[keyList.first] = o;
} else {
m[keyList.first] = insertInMap(
Map.from(m[keyList.first]),
keyList.sublist(1),
o,
);
}
return m;
}
I understand the above code is making copies of the Map and refitting them in the original map bottom up. I would like a way to edit the map directly, similar to how map[i][j] works, which I believe does not replicate maps and should thus be much more efficient in memory use as an in-place algorithm.
My search led me to this as question;
Accessing nested array at a dynamic depth which resembles my non-optimal recursive solution. Other answers I attempted searching were about iterating over maps using loops, which are a different topic altogether without the mention of their depth.
If it is not possible, assistance by way of confirming it would save me time and mental anguish.
Thanks in advance.
Related
maybe it is a stupid question, but I have this doubt and I cannot find a response...
If I have a map operation on a list of complex objects and to make the code more readable I use intermediate variables inside the map the performance can change?
For example this are two versions of the same code:
profilesGroupedWithIds map {
c =>
val blockId = c._2
val entityIds = c._1._2
val entropy = c._1._1
if (separatorID < 0) BlockDirty(blockId, entityIds.swap, entropy)
else BlockClean(blockId, entityIds, entropy)
}
..
profilesGroupedWithIds map {
c =>
if (separatorID < 0) BlockDirty(c._2, c._1._2.swap, c._1._1)
else BlockClean(c._2, c._1._2, c._1._1)
}
As you can see the first version is more readable than the second one.
But the efficiency is the same? Or the three variables that I have created inside the map have to be removed by the garbage collector and this will reduce the perfomance (suppose that 'profilesGroupedWithIds' is a very big list)?
Thanks
Regards
Luca
The vals are just aliases for the tuple elements. So the generated java bytecode will be identical in both cases, and so will be the performance.
More importantly, the first variant is much better code since it clearly conveys the intent.
Here is a third variant that avoids accessing the tuple elements _1 and _2 entirely:
profilesGroupedWithIds map {
case ((entropy,entityIds),blockId) =>
if (separatorID < 0) BlockDirty(blockId, entityIds.swap, entropy)
else BlockClean(blockId, entityIds, entropy)
}
I have the following pseudo-code:
function X(data, limit, level = 0)
{
result = [];
foreach (Y(data, level) as entity) {
if (level < limit) {
result = result + X(entity, limit, level + 1);
} else {
//trivial recursion case:
result = result + Z(entity);
}
}
return result;
}
which I need to turn into a plain (e.g. without recursive calls). So far I'm out of ideas regarding how to do that elegantly. Following this answer I see that I must construct the entire stack frames which are basically the code repetitions (i.e. I will place same code again and again with different return addresses).
Or I tried stuff like these suggestions - where there is a phrase
Find a recursive call that’s not a tail call.
Identify what work is being done between that call and its return statement.
But I do not understand how can the "work" be identified in the case when it is happening from within internal loop.
So, my problem is that all examples above are providing cases when the "work can be easily identified" because there are no control instructions from within the function. I understand the concept behind recursion on a compilation level, but what I want to avoid is code repetition. So,
My question: how to approach transformation of the pseudo-code above which does not mean code repetitions for simulating stack frames?
It looks like an algorithm to descend a nested data structure (lists of lists) and flatten it out into a single list. It would have been good to have a simple description like that in the question.
To do that, you need to keep track of multiple indices / iterators / cursors, one at each level that you've descended through. A recursive implementation does that by using the call stack. A non-recursive implementation will need a manually-implemented stack data structure where you can push/pop stuff.
Since you don't have to save context (registers) and a return address on the call stack, just the actual iterator (e.g. array index), this can be a lot more space efficient.
When you're looping over the result of Y and need to call X or Z, push the current state onto the stack. Branch back to the beginning of the foreach, and call Y on the new entity. When you get to the end of a loop, pop the old state if there is any, and pick up in the middle of that loop.
I have my function that needs changing to iteration, because of very slow executing of it.
There are two recursive calls, depends which condition is true.
It's something like this:
(I have static array of classes outside function, let's say data)
void func(int a, int b, int c, int d) {
//something
//non-recursive
//here..
for (i=0; i<data.length; i++) {
if (!data[i].x) {
data[i].x = 1;
if (a == data[i].value1)
func(data[i].value2,b,c,d);
else if (a == data[i].value2)
func(data[i].value1,b,c,d);
data[i].x = 0;
}
}
}
!!
EDIT: Here is my algorithm: http://pastebin.com/F7UfzfHv
Function searches for every paths from one point to another in graph, but returns (to an array) only one path in which are only unique vertices.
!!
And I know that good way to manage that is to use stack... But I don't know how. Could someone give me a hint about it?
There is a good possibility that your function might be computing the same thing again and again, which in technical terms is called as overlapping sub-problems(if you are familiar with the dynamic programming then you might know). First try to identify whether that is the case or not. Since you haven't told anything about what function do and I can't tell the exact problem.
Also the thing you are talking about using a stack is not of great use since recursion uses a stack internally. Using external stack instead of internal is more error prone is not of great use.
I have a stl map that's of type:
map<Object*, baseObject*>
where
class baseObject{
int ID;
//other stuff
};
If I wanted to return a list of objects (std::list< Object* >), what's the best way to sort it in order of the baseObject.ID's?
Am I just stuck looking through for every number or something? I'd prefer not to change the map to a boost map, although I wouldn't be necessarily against doing something that's self contained within a return function like
GetObjectList(std::list<Object*> &objects)
{
//sort the map into the list
}
Edit: maybe I should iterate through and copy the obj->baseobj into a map of baseobj.ID->obj ?
What I'd do is first extract the keys (since you only want to return those) into a vector, and then sort that:
std::vector<baseObject*> out;
std::transform(myMap.begin(), myMap.end(), std::back_inserter(out), [](std::pair<Object*, baseObject*> p) { return p.first; });
std::sort(out.begin(), out.end(), [&myMap](baseObject* lhs, baseObject* rhs) { return myMap[lhs].componentID < myMap[rhs].componentID; });
If your compiler doesn't support lambdas, just rewrite them as free functions or function objects. I just used lambdas for conciseness.
For performance, I'd probably reserve enough room in the vector initially, instead of letting it gradually expand.
(Also note that I haven't tested the code, so it might need a little bit of fiddling)
Also, I don't know what this map is supposed to represent, but holding a map where both key and value types are pointers really sets my "bad C++" sense tingling. It smells of manual memory management and muddled (or nonexistent) ownership semantics.
You mentioned getting the output in a list, but a vector is almost certainly a better performing option, so I used that. The only situation where a list is preferable is really when you have no intention of ever iterating over it, and if you need the guarantee that pointers and iterators stay valid after modification of the list.
The first thing is that I would not use a std::list, but rather a std::vector. Now as of the particular problem you need to perform two operations: generate the container, sort it by whatever your criteria is.
// Extract the data:
std::vector<Object*> v;
v.reserve( m.size() );
std::transform( m.begin(), m.end(),
std::back_inserter(v),
[]( const map<Object*, baseObject*>::value_type& v ) {
return v.first;
} );
// Order according to the values in the map
std::sort( v.begin(), v.end(),
[&m]( Object* lhs, Object* rhs ) {
return m[lhs]->id < m[rhs]->id;
} );
Without C++11 you will need to create functors instead of the lambdas, and if you insist in returning a std::list then you should use std::list<>::sort( Comparator ). Note that this is probably inefficient. If performance is an issue (after you get this working and you profile and know that this is actually a bottleneck) you might want to consider using an intermediate map<int,Object*>:
std::map<int,Object*> mm;
for ( auto it = m.begin(); it != m.end(); ++it )
mm[ it->second->id ] = it->first;
}
std::vector<Object*> v;
v.reserve( mm.size() ); // mm might have less elements than m!
std::transform( mm.begin(), mm.end(),
std::back_inserter(v),
[]( const map<int, Object*>::value_type& v ) {
return v.second;
} );
Again, this might be faster or slower than the original version... profile.
I think you'll do fine with:
GetObjectList(std::list<Object*> &objects)
{
std::vector <Object*> vec;
vec.reserve(map.size());
for(auto it = map.begin(), it_end = map.end(); it != it_end; ++it)
vec.push_back(it->second);
std::sort(vec.begin(), vec.end(), [](Object* a, Object* b) { return a->ID < b->ID; });
objects.assign(vec.begin(), vec.end());
}
Here's how to do what you said, "sort it in order of the baseObject.ID's":
typedef std::map<Object*, baseObject*> MapType;
MapType mymap; // don't care how this is populated
// except that it must not contain null baseObject* values.
struct CompareByMappedId {
const MapType ↦
CompareByMappedId(const MapType &map) : map(map) {}
bool operator()(Object *lhs, Object *rhs) {
return map.find(lhs)->second->ID < map.find(rhs)->second->ID;
}
};
void GetObjectList(std::list<Object*> &objects) {
assert(objects.empty()); // pre-condition, or could clear it
// or for that matter return a list by value instead.
// copy keys into list
for (MapType::const_iterator it = mymap.begin(); it != mymap.end(); ++it) {
objects.push_back(it->first);
}
// sort the list
objects.sort(CompareByMappedId(mymap));
}
This isn't desperately efficient: it does more looking up in the map than is strictly necessary, and manipulating list nodes in std::list::sort is likely a little slower than std::sort would be at manipulating a random-access container of pointers. But then, std::list itself isn't very efficient for most purposes, so you expect it to be expensive to set one up.
If you need to optimize, you could create a vector of pairs of (int, Object*), so that you only have to iterate over the map once, no need to look things up. Sort the pairs, then put the second element of each pair into the list. That may be a premature optimization, but it's an effective trick in practice.
I would create a new map that had a sort criterion that used the component id of your objects. Populate the second map from the first map (just iterate through or std::copy in). Then you can read this map in order using the iterators.
This has a slight overhead in terms of insertion over using a vector or list (log(n) time instead of constant time), but it avoids the need to sort after you've created the vector or list which is nice.
Also, you'll be able to add more elements to it later in your program and it will maintain its order without need of a resort.
I'm not sure I completely understand what you're trying to store in your map but perhaps look here
The third template argument of an std::map is a less functor. Perhaps you can utilize this to sort the data stored in the map on insertion. Then it would be a straight forward loop on a map iterator to populate a list
I want to get the following code to work in the Java ME / J2ME environment. Please help:
Hashtable <Activity, Float>scores = new Hashtable<Activity, Float>();
scores.put(act1, 0.3);
scores.put(act2, 0.5);
scores.put(act3, 0.4);
scores.put(act5, 0.3);
Vector v = new Vector(scores.entrySet());
Collections.sort(v); //error is related to this line
Iterator it = v.iterator();
int cnt = 0;
Activity key;
Float value;
while(it.hasNext()){
cnt++;
Map.Entry e=(Map.Entry)it.next();
key = (Activity)e.getKey();
value = (Float)e.getValue();
System.out.println(key+", "+value);
}
It doesn't work, I get the error:
Exception in thread "main" java.lang.ClassCastException: java.util.Hashtable$Entry cannot be cast to java.lang.Comparable
This points to the line that I've indicated with a comment in the code.
Please help, and bear in mind that I'm using j2me!
The code you've got isn't anywhere near valid J2ME, it's full fat (J2SE) java; J2ME doesn't currently have generics, or a Collections class or a Comparable interface - check for JavaDoc for MIDP 2 and CLDC 1.1, the components of J2ME. Your error mentions those, so definitely didn't come from J2ME, which suggests you might be doing something fundamental wrong in your project setup?
If you do want to do this in J2ME you need to write a sort function yourself, because as far as I can tell no such thing exists. Bubblesort will be easiest to write, since the only way you can easily access sequential members of the hashtable is through Enumerations (via scores.keys() and scores.values()). Assuming you want to sort your activities in ascending order based on the scores (floats) they're associated with, you want something like:
boolean fixedPoint = false;
while (!fixedPoint)
{
fixedPoint = true;
Enumeration e = scores.keys();
if (!e.hasMoreElements()) return;
Object previousKey = e.nextElement();
while (e.hasMoreElements()) {
Object currentKey = e.nextElement();
if ((Float) scores.get(currentKey) > (Float) scores.get(previousKey)) {
swap(currentKey, previousKey);
fixedPoint = false;
}
previousKey = currentKey;
}
}
Also, somewhere you'll need to write a swap function that swaps two elements of the hashtable when given their keys. Worth noting this is NOT the quickest possible implementation -- bubble sort will not be good if you expect to have big big lists. On the other hand, it is very easy with the limited tools that J2ME gives you!
The entrySet method doesn't return the values in the hash table, it returns the key-value pairs. If you want the values you should use the values method instead.
If you want the key-value pairs but sort them only on the value, you have to implement a Comparator for the key-value pairs that compares the values of two pairs, and use the overload of the sort method that takes the Comparator along with the list.