Reversing Order of Words in a Sentence

Reversing the word order in a string in place

You just need to move the start pointer in the inprev function to skip the space between words. As this appears to be homework (correct me if I'm wrong) I'll just say that all you need to do is move the location of one operator.

But, this produces a problem, namely, the inprev performs a buffer overrun because the search isn't terminated properly. A better way to do it is:

while not end of string
search for start of word
start = start of word
search for end of word
strrev (start, end)

and that will take care of multiple spaces too. Also, U+0020 (ASCII 32, a space) is not the only white space character. There are standard library functions that test characters. They are in <ctype.h> and start with is..., e.g. isspace.

Reversing order of words in a sentence

As the other answers suggest you should use std::string which can save lot of hassles.
But just for the note,

void reverse(char* sentence)
{
int index = strlen(sentence) - 1,hold,last = '\0';
/*For the 1st iteration last is `\0` for all others it is ` `*/
while (index >= 0)
{
/*
In your original code,
This while loop(below) will continue to keep decrementing index
even below `0`,You wont exit this while loop until you encounter a ` `.
For the 1st word of the sentence you will never come out of the loop.
Hence the check, index>=0
*/

while (index>=0 && sentence[index] != ' ')
index--;

/* You can print the whitespace later*/

hold = index - 1; // This keeps track of the last character
// of preceding word

index++; //character after space

while (sentence[index] != last)
{
cout << sentence[index];
index++;
}
last = ' ';
index = hold;

/* Dont print space after 1st word*/
if(index > 0)
cout<<" ";
}

}
int main()
{
char* sentence = new char[256];
cin.getline(sentence, 256);
reverse(sentence);
delete[] sentence; // Delete the allocated memory
}

Tryin to keep it as close to your logic

Reverse word letters of a sentence with keeping same word order as entered in emu8086

You correctly used procedure REVERSE to reverse the entire STRING. When you need to reverse each lexical word of the STRING separately, you should similarly split up the task:
parse the input string to words and apply a subprocedure ReverseWord to each such word.

Dividing the task to smaller subprocedures makes is better apprehensible and it's easier to debug. You can try to optimize it later, if necessary.

REVERSE PROC                ; Reverse words in STRING.
LEA SI,[STRING]
CLD ; LODSB will parse forward.
NextWord: MOV DI,SI ; Let SI=DI=at the first char of the word.
NextChar: LODSB ; Load AL from [SI], increment SI.
CMP AL," " ; Search for white-space terminator.
JBE WordEnd
CMP AL,"$" ; $ terminates the word, too.
JE StringEnd
JMP NextChar ; Repeat when the word is not terminated yet.
WordEnd: CALL ReverseWord ; Reverse the word between DI and SI.
JMP NextWord
StringEnd:CALL ReverseWord ; Reverse the last word between DI and SI.
RET ; All words are reversed in situ.
ENDP

ReverseWord PROC ; Reverse the word between DI and SI-1.
PUSHAW ; Do not clobber any register.
DEC SI ; Let SI=behind the last char of the word.
MOV CX,SI
SUB CX,DI ; Let CX=number of chars in the word.
SHR CX,1 ; Divide CX in half, ignore remainder.
JZ Done ; Do nothing when the word is 1 char or less.
Again:DEC SI ; Let SI=at the last char of the word.
MOV AL,[SI] ; Load AL with the last char.
MOV DL,[DI] ; Load DL with the first char.
MOV [SI],DL ; Swap the first and the last chars.
MOV [DI],AL
INC DI
LOOP Again ; Repeat with the inner chars.
Done:POPAW ; Restore all registers.
RET ; The word between DI..SI was reversed.
ENDP

The inner subprocedure ReverseWord is used twice, string terminator $ remains unclobbered in situ.
Notice that the number of character exchanges is half of the word size, and when the word size is odd, the middle character stays in its original position (in situ).

How to reverse the order of the words in a string

You can use split to get the separate words, reverse to reverse the list, and finally join to join them again to make the final string:

s = "This is New York"
# split first
a = s.split()
# reverse list
a.reverse()
# now join them
result = " ".join(a)
# print it
print(result)

results in:

'York New is This'

Reversing words in a sentence

Another methodology to think about:

you can cage a swallow can't you?
uoy t'nac wollaws a egac nac uoy?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
you t'nac wollaws a egac nac uoy?
^^^
you can't wollaws a egac nac uoy?
^^^^^
you can't swallow a egac nac uoy?
^^^^^^^
you can't swallow a egac nac uoy?
^
you can't swallow a cage nac uoy?
^^^^
you can't swallow a cage can uoy?
^^^
you can't swallow a cage can you?
^^^

For each thing you want to reverse (be it a whole sentence or a word):

  1. Find the beginning and end
  2. Swap the beginning and end characters
  3. Move "inwards" once
  4. keep going until you reach "the middle"

Since reversing a chunk of a string is a common operation, it makes sense to make it its own function. And since the only information the function need to do its job is:

  1. the string
  2. the beginning index
  3. the ending index

What do you think the parameters for the function would be?

The other common thing that needs to be done over and over is "finding" something, be it a space or a punctuation mark. You may need to write this yourself, or if you can use library functions, or want a hint, look up:

man strcspn

Reverse order of words in a sentence without using built in functions

<?php

$str = "My Name is Fred";
$i = 0;
while( $d = $str[$i] )
{
if( $d == " "){

$out = " ".$temp.$out;
$temp = "";
}else{
$temp.=$d;

}
$i++;
}
echo $temp.$out;
?>

Efficiently reverse the order of the words (not characters) in an array of characters

A solution in C/C++:

void swap(char* str, int i, int j){
char t = str[i];
str[i] = str[j];
str[j] = t;
}

void reverse_string(char* str, int length){
for(int i=0; i<length/2; i++){
swap(str, i, length-i-1);
}
}
void reverse_words(char* str){
int l = strlen(str);
//Reverse string
reverse_string(str,strlen(str));
int p=0;
//Find word boundaries and reverse word by word
for(int i=0; i<l; i++){
if(str[i] == ' '){
reverse_string(&str[p], i-p);
p=i+1;
}
}
//Finally reverse the last word.
reverse_string(&str[p], l-p);
}

This should be O(n) in time and O(1) in space.

Edit: Cleaned it up a bit.

The first pass over the string is obviously O(n/2) = O(n). The second pass is O(n + combined length of all words / 2) = O(n + n/2) = O(n), which makes this an O(n) algorithm.

Reverse word order in sentence

// Pass string which comes after space
// reverse("This is a sentence.")
// reverse("is a sentence.")
// reverse("a sentence.")
// reverse("sentence.")
// will not find space
// start print only word in that function

void reverse(const std::string str)
{
int pos = str.find_first_of(" ");
if (pos == string::npos) // exit condition
{
string str1 = str.substr(0, pos);
cout << str1.c_str() << " " ;
return;
}

reverse(str.substr(pos+1));
cout << str.substr(0, pos).c_str() << " ";
}

Simple to understand:

void reverse(const std::string str)
{
int pos = str.find_first_of(" ");
if (pos != string::npos) // exit condition
{
reverse(str.substr(pos + 1));
}
cout << str.substr(0, pos).c_str() << " ";
}

Reverse each word in string without changing word order

Try something like this.

function wordsReverser(string){
return string.split("").reverse().join("").split(" ").reverse().join(" ")
}

console.log(wordsReverser('New string, same results.'));


Related Topics



Leave a reply



Submit