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):
- Find the beginning and end
- Swap the beginning and end characters
- Move "inwards" once
- 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:
- the string
- the beginning index
- 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
How to Use Other C++ Compilers with Cuda on Windows
Right Justifying Output Stream in C++
C++11 Std::Async Doesn't Work in Mingw
How to Keep My Topmost Window on Top
Are the Character Digits ['0'..'9'] Required to Have Contiguous Numeric Values
How to Use Wndproc as a Class Function
Static Member Variable in a Class
Knight's Tour Backtrack Implementation Choosing the Step Array
C/C++ Counting the Number of Decimals
How to Pass a Boost Asio Tcp Socket to a Thread for Sending Heartbeat to Client or Server
Compiler Cannot Recognize My Class in C++ - Cyclic Dependency
Create 2D Array Using Size from Parameters in C++
Why Cast to a Pointer Then Dereference