String Re-ordering
March 27, 2015
Today’s exercise is a fun little interview question:
You are given a string O that specifies the desired ordering of letters in a target string T. For example, given string O = “eloh” the target string T = “hello” would be re-ordered “elloh” and the target string T = “help” would be re-ordered “pelh” (letters not in the order string are moved to the beginning of the output in some unspecified order).
Your task is to write a program that produces the requested string re-ordering. When you are finished, you are welcome to read or run a suggested solution or to post your own solution or discuss the exercise in the comments below.
A solution using PHP >= 5.3: http://3v4l.org/vnoC1
In Python.
Haskell:
In Python the string.find() method returns the index of a character or -1 if a letter is not found in the string.
def reorder(t, o):
return ”.join(sorted(t, key=o.find))
This time with formatting:
An alternative Python solution.
The OrderedCounter counts the number of each character seen in the input, and remembers the order in which they are first seen.
Then each character in the ‘order’ string is moved to the end of the counter.
OrderedCounter.elements() returns each character repeated the number of times it was seen.
Bucket sort a nice idea. Here’s an in-place solution, scan the first string recording which characters are present, then scan the second string, moving uncounted characters to the front, then scan the first again, copying the right number of characters into the second. I’ve ignored problems with using a char to index an array, (don’t do this at work):
With Python list comprehensions, first gather the characters not in the ordering string and then the ones from the ordering string in their order.
def substr(ostr,tstr):
wstr = [x for x in tstr if x not in ostr]
for x in ostr:
wstr += [y for y in tstr if y == x]
return ”.join(wstr)
if __name__ == ‘__main__’:
ostr = “eloh”
tstr = “hello”
print substr(ostr,tstr)
A perl solution:
use Test::More;
is reorder(“hello”, “eloh”), “elloh”;
is reorder(“help”, “eloh”), “pelh”;
sub reorder {
my ($target, $order) = @_;
return join ”, sort { index($order,$a) index($order,$b) } split //, $target;
}
done_testing;
I have ported the given scheme solution using decorate-sort-undecorate algorithm to java:
This is a modified version of the solution posted by Krishnan R.
Bucketsort version:
A not particularly efficient but straightforward C++(11) version:
Java8: