Reverse Words
March 8, 2011
After we solved the reverse-words problem in an exercise a few weeks ago, a reader complained that the suggested solution was too simple because it used library functions to split the words and later to rejoin them; he also thought the exercise should include a restriction that the string had to be reversed in-place. I’m not sure about either of the objections, but we’ll take the opportunity to revisit a classic interview question. We’ll also eliminate the letters-only and single-space-between-words restrictions of the original exercise from Google. Thus, here are some sample inputs and their associated outputs; note especially the placements of leading and trailing spaces:
"" => ""
" " => " "
" " => " "
"hello" => "hello"
"hello " => " hello"
" hello" => "hello "
"the quick brown fox" => "fox brown quick the"
"the quick brown fox" => "fox brown quick the"
"the quick brown 42 fox!" => "fox! 42 brown quick the"
Your task is to write a reverse-words function given the definition and restrictions stated above. 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.
My Haskell solution (see http://bonsaicode.wordpress.com/2011/03/08/programming-praxis-reverse-words/ for a version with comments):
[…] today’s Programming Praxis exercise, we’re revisiting the well-known interviewing problem of […]
My 2 cents in python:
arf my bad, I used builtin functions….sorry
Python strings are immutable, so we can’t change them in place. I came up with
two options, neither of which are terribly satisfactory:
1. build a new string with the slice reversed (
reverse_slice()
) or2. turn our string into a list and work on that (
rev_slice_list()
like Remco’s solution with arrays), but that still creates a new object
and requires converting back to a string.
I decided to emulate the official solution’s sample tests somewhat closely.
I actually wrote that a couple of days ago and tried submitting it to the other exercise, but for some reason WordPress didn’t like it (it never appeared in the list of comments, and I got a “comment already submitted” error when I tried to re-submit it). [ Sorry. It went to the spam folder for some reason, along with three other comments on that post. All have now been retrieved. Phil ]
Anyway, in C, first reversing the letters word by word, then reversing the whole string (please excuse the puerile bit of fun with macros). It doesn’t quite do what’s asked here, as it will treat punctuation the same as whitespace, but it’s close enough:
#define is_word_char(A) \
(((A) >= ‘a’ && (A) <= ‘z’) || \
((A) >= ‘A’ && (A) <= ‘Z’) || \
((A) >= ‘0’ && (A) <= ‘9’))
/* —————————–
* Questionable macro implementation of swap,
* careful when reusing,
* definitely not threadsafe */
#define swapchar(A,B) \
do { \
tmp_swap_char = *(A); \
*(A) = *(B); \
*(B) = tmp_swap_char; \
} while (0)
char tmp_swap_char;
/* —————————– */
void reverse_from_to(char *from, char *to)
{
// Reverses part of a string, between *from and *to
int i;
for (i = 0; i < (to – from + 1) / 2; i++){
swapchar(from + i, to – i);
}
}
char* reverse_words_in_string(char *str)
{
char *cp; //points to character within a word
char *wp = str; //points to start of a word
/* We’ll first reverse the letters in each word within the string str */
while (*wp != ‘\0’) {
if (is_word_char(*wp)) {
cp = wp;
while (is_word_char(*(cp + 1)))
cp++;
reverse_from_to(wp, cp);
wp = cp;
}
wp++;
}
/* Now simply reverse the whole string again to finish the job */
reverse_from_to(str, str + strlen(str) – 1);
return str;
}
As Graham pointed out above, strings are immutable in Python. So, I just eliminated the built-in functions that made the earlier exercise too easy.
Basic strategy is to start at the end and scan the string backwards to identify runs of similar (space or non-space) characters.
First solution uses built in ‘len’ and ‘isspace’, because most languages have equivalents. Second version omits even those built-ins.
If you don’t like (s[b-1] in ‘ \t’) replace it with (s[b-1]==’ ‘ or s[b-1]==’\t’).
If I asked a job applicant to solve this problem, I would expect them to use the features of their chosen programming language.
For Python I would expect something like this:
Mike: As I said in the first paragraph of the exercise, I wasn’t sure about either of the reader’s objections. But as an interview question, sometimes you just have to go with what the interviewer wants; think of today’s exercise as the follow-up question from the interviewer after you have given the straight forward answer. And it does make for a good exercise. I got it wrong the first time I wrote it, an off-by-one error in resetting lo and hi for the next step. Maybe the next time I go on a job interview, and get this question, I’ll get it right.
Haven’t used C seriously in at least 15 years, so I was a bit rusty. But after a few trys I came up with the following routine. It doesn’t use any library functions.
reverseWord = (concat.reverse.(groupBy noChar))
where
noChar ‘ ‘ ‘ ‘ = True
noChar x y = (not.isSpace) x && (not.isSpace) y
My try in REXX
with self-made reverse()
give a answer using looping simply
i cn die 4 learning alll the languages of computer …i want to become a sofware developer wana make everything related to programming ….m a engineering student plz help me sir how can i improve my programming skills
My solution in Python: