[Challenge] Reverse Words

Here’s the code(in C++) for the first hard reverser(not the one with punctuation):
It’s iterating through the string and when it founds a space it prints the word that starts from that position, and ends at the last printed position-1

https://repl.it/He9G/1

Here’s my take on the hard version

https://repl.it/Hebp/0

https://repl.it/HeSr/0

That was fun
Cut the string in words, spaces and punctuation symbols. then only reverse the words
swapping starting from the outer to inside ones, skipping the spaces and symbols positions.
then re-join the string.
sol in repl.it ruby <-

https://repl.it/embed/HegT/0.js

Comments in the code:

https://repl.it/Hegz/4

1 Like
import java.io.; import java.util.;
public class Solution {
public static void main(String[] args) {

    Scanner sc=new Scanner(System.in);
    String A=sc.next();
    StringBuffer sb = new StringBuffer();

    sb.append(A);
 System.out.println(sb.reverse().toString());
    

}
}

##Intermediate Problem

My code has inline comments to explain the strategy I am using and why am using it. Overall, I am trying to record the location of punctuation so that I can reverse the order of the words and space-blocks and then insert the punctuation back into the correct position.

As you can see from running the code, this can handle multiple punctuation as well as multiple spaces in a row, keeping them in their original position while the words reverse in order.

import re
import string
import itertools

x = 'may, the, fourth:    ,be with! !you'

def problem_solver_spaces(ex_str):
    ## this will split the string on either spaces or punctuation marks. Since we have included both split delimiters within a capture group, they will
    ## be included in the ouput list
    splitter = re.split(r'((?:\s{1,})|[%s])' % string.punctuation, ex_str)
    ## this will filter out any empty spaces within the list
    splitter = filter(lambda a: a != '', splitter)
    ## here will will create a dictionary and add any puncation marks to it and the position of it within the initial string
    ## this is so we can place them back in their original spot
    new_dict = {}
    for index, item in enumerate(splitter):
        if item in string.punctuation:
            new_dict[index] = item
    ## this will take all the words and spaces (NOT punctuation marks) and reverse their order so we have everything backwards
    new_str = [i for i in reversed(re.findall('(\w+|\s{1,})', ex_str))]

    ## this will go through our created dictionary and place the punctuation marks back in their original position within the new reversed list. The sort
    ## helps to not alter the indices as we go through and re-enter characters into the list
    for key in sorted(new_dict):
        new_str.insert(key, new_dict[key]) 

    ## this joins all the elements back together. The .strip gets rid of the initial space in the beginning of the string
    new_str = ''.join(new_str).strip()
    ## printing just so it shows up in repl.it
    print new_str

    return new_str
    
problem_solver_spaces(x)

I am also embedding my repl.it page here for people to view.

https://repl.it/HeTw/6

Intermediate challenge accepted!

This solution seems to work. I created:

  1. an initial array to hold the test string,
  2. a punctuation-holding array that is set to the same length as the initial array (so we can merge them later),
  3. a final string that will take the merged arrays and should display the requested text.

First I loop over the “staging array” which has been split up by word, in order to get to the punctuation. On each item/word in this array, I do a regex search to see if there are any punctuation characters. If there are, I return that character (using String.charAt) to the punctuation array at the index position corresponding to where it was in the staging array (so if the second word index has a comma in the string, it puts that string in the second index of the punctuation array. Again, so we can merge it later). Then I replace the character in the staging array with an empty character using the newWord variable.

When that’s all done, I reverse the staging array, and put it in a new array revMaster. Finally I loop over that array and where the index position of the punctuation array is NOT undefined (ie, it got a punctuation character from the last loop), I merge the character at that index position with the revMaster index position.

See below. Codepen link here:

var str = "May the force, be with you.";
var stagingArray = str.split(' ');
var punctArray = new Array(stagingArray.length); 
var finalStr = [];
var i = 0;

stagingArray.forEach(function(word){
    regExSearch = word.search(/[,!.;]/);
        if (regExSearch !== -1) {
            newWord = word.replace(word.charAt(regExSearch),'');
            punctArray[i] = word.charAt(regExSearch);
            stagingArray[i]= newWord;
            i++;
        } else {
            i++;
        };
    
});

var revMaster = stagingArray.reverse();

for(var z= 0; z< revMaster.length; z++) {
    if (punctArray[z] === undefined) {
        finalStr += revMaster[z] + " ";
    } else {
        finalStr += revMaster[z] + punctArray[z] + " ";
    }
};

console.log(finalStr);

Intermediate difficulty:

https://repl.it/Hesy/0

Intermediate, javascript.

I interpreted it as a function that should receive one sentence, reverse the order of words, and keep any punctuation at the end in place.

https://repl.it/HepD/2

So punctuation within the sentence will also be reversed , so “May… the Fourth be with you.” becomes “you with be Fourth the May…” (and the same will happen with multiple spaces) so the only punctuation that will stay untouched is the last one.

https://repl.it/Heop/1

I encapsulated it in a function so its reusable.
I used regexes to define words as all word+digit chars, and punctuation as all non word+digit chars and the immediately following space. I then reversed the words, mapped over the word list concatenating the un-reversed punctuation list, then recombined them.

https://repl.it/Herp/4

https://repl.it/HfCV

Beginner level

  1. I decided to split sentence into words
  2. A list comprehension takes returned list with words reversed,
  3. I used ’ '.join method to change list elements into strings
  4. I returned the new string

HARD (no punctuation)
This is my attempt at an in-place pure-python solution for reversing words without punctuation.

I start by converting the input string to a list of characters (len 1 strings) I will keep referring to the list of chars as a string. It’s simpler that way.

my intent is to start by moving one word from the back of the string to the front of the string, one char at a time, and then move my insert position(pos) forward in the string to the end of the word I just finished. Then I add the non-alpha char (this will be the space) step forward the insert position one step more and then start adding in the next work from the back, one char at a time. I continue to do this until I have popped all chars from the back of the string exactly once.

https://repl.it/HfIT/1

EASY
This is the most compact easy solution I can come up with

  • split string by space
  • reverse list of words
  • join words by space

https://repl.it/HfKc/1

EXTRA
I split the string into two two-dimensional lists. One for words and one for punctuation. Each of the two-dimensional lists holds a list of indices and a list of elements (words of punctuation)

When the splitting is complete I convert the lists to a dict. This is where I apply a small trick. I add the indices of words and punctuation into one list and use them as keys. I do the same for the actual words and punctuation lists, except I reverse the word list. This means that I have now reversed the indices of the words but not the punctuation.

All I have to do now is join the list of strings by sorted dict keys. In the final list comprehension I added a few conditions to sort out the space/no-space situation surrounding the insertion of punctuation.

https://repl.it/HfMy/5

Maybe not the most efficient solution - and when commenting I noticed a couple of things that could definitely be improved, but it works - Extra Credit so far.

I may update and add the hard task tonight, but I remember big O notation hurting my brain last time i looked at it.

Repl.it link, done in JS

https://repl.it/HfSt/4

import java.util.Scanner;

public class Solution {

public static void main(String[] args) {

	Scanner in = new Scanner(System.in);

	/*
	 * Used StringBuilder since its faster than StringBuffer as it is not
	 * synchronized
	 */
	StringBuilder reverseWords = new StringBuilder();

	/* used below code since there can be multiple lines of input */
	while (in.hasNext()) {
		reverseWords.append(in.nextLine()); // concatenate input with buffer
	}

	/*
	 * reverse the buffer and print. This will keep the punctuation and
	 * other characters in place
	 */
	System.out.println(reverseWords.reverse());
	in.close();
}

}

1 Like

https://repl.it/Hdjx/4