On Jun 2, 2009, at 11:22 PM, Wilson MacGyver wrote:
> > More newbie questions. :) > > If I have two sequences as follow: > > (2 3 4 5 6 7 8 9 10) > (4 6 8 10) > > what's the best way to subtract the 2nd sequence from the first one? > > The best I can come up with was to do (first) on 2nd sequence and > turn around > and do a (remove) on the first sequence, etc until I exhaust the 2nd > sequence. In Clojure, the set data structure is awesome. I have nothing to add to that. However, I had to do this the other day in Javascript (which lacks a decent set type) and the algorithm I came up with is this: sort both sequences walk down both sequences: if the remove list item is greater than the list item, add it to the result and increment the remove list index if the remove list item is less than the list item, increment the list index if they are equal, increment the remove list index I believe this algorithm to be O(n log n) because the subtraction operation should take O(MAX(n,m)) and that ought to be dominated by the O(n log n) for sorting whichever input list is bigger. The naive method ought to be O(n*m) because for each element of one list you have to do a complete traversal of the other list. If the lists are comparable in size it would start to resemble O(n^2). Pretty off-topic, I know, but the function I came up with is this: // returns the subtraction of two sorted lists function subtract(a1, a2) { var i = 0, j = 0, result = []; // walk down both lists while (i < a1.length && j < a2.length) { // the list item is less than the remove item if (a1[i] < a2[j]) { // stick it on the result and move along the list result.push(a1[i]); i++; } else if (a1[i] > a2[j]) // the list item exceeds the remove item, so we need to move along the // remove items j++; else // the items are equal, so continue testing the list with this item of // the remove list i++; } // glob on the remainder of the list if (i < a1.length) result = result.concat(a1.splice(i)); return result; } I'm sure Clojure's sets do this kind of thing more efficiently but if you have to do it in a language without a decent set data structure you can fall back on that algorithm. Of course, I don't think you'll notice an improvement over the naive method until you hit several thousand elements or have similarly sized input lists. — Daniel Lyons http://www.storytotell.org -- Tell It! --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---