Review: small recursive code
Hi Guys,
i just wrote a program to print a sentence backwards using recursion. But i'm not too happy about it, if someone can give me a more optimized solution i'll be glad. You have to use std::string class.
input:
where the streets have no name
output:
name no have streets the where
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
// read a sentence and print it backwards using recursion
std::string mySentence(std::string);
int main()
{
std::string query;
std::cout << "enter a sentence" << std::endl;
if ( std::getline ( std::cin,query ) )
std::cout << mySentence(query) << std::endl;
}
std::string
mySentence(std::string sentence)
{
std::stringstream ss(sentence);
std::string token;
int wordCount = 0;
while(ss>>token)
{
wordCount++;
}
if(wordCount == 1)
return sentence;
int count = 0;
std::string::iterator it;
it = sentence.end();
while(*it != ' ')
{
it--;
count++;
}
int len = sentence.length();
int pos = len - count;
std::string subString = sentence.substr(0,pos);
return sentence.substr(pos) + mySentence(subString);
}
Agni
Practically a Master Poster
655 posts since Dec 2007
Reputation Points: 431
Solved Threads: 116
Try to compress:
bool Reverser(std::istream& sentence = std::cin, bool im1st = true)
{
std::string word;
if (sentence >> word)
{
if (Reverser(sentence,false))
std::cout << " ";
std::cout << word;
if (im1st)
std::cout << std::endl;
return true;
}
return false;
}
ArkM
Postaholic
2,001 posts since Jul 2008
Reputation Points: 1,234
Solved Threads: 348
You might try the following untested logic:
declare mySentence() to:
1) have return type void
2) receive a reference to a stringstream
3) have a local string variable called token
4) if you can extract a string from the stringstream into token
a) recursively call mySentence again passing it the
stringstream which is now advanced 1 word from where it was
b) output token after return from the recursive call
in main()
1) receive user input into a string
2) declare and initialize a stringstream with user input
3) call mySentence passing it the stringstream
Edit: Beaten by ArkM who is using similar logic. Here's the actual code I had written
void mySentence(std::stringstream & ss)
{
std::string token;
if(ss >> token)
{
mySentence(ss);
std::cout << token << std::endl;
}
}
Lerner
Nearly a Posting Maven
2,382 posts since Jul 2005
Reputation Points: 739
Solved Threads: 396
Yes, it's the same (obvious) recursive pattern.
Regrettably, I was forced to add some bells and twistles to separate words with blanks.
It seems there is some compression reserve here...
ArkM
Postaholic
2,001 posts since Jul 2008
Reputation Points: 1,234
Solved Threads: 348
to reproduce the white spaces in the original in the reversed sentence:
#include <string>
#include <algorithm>
#include <iterator>
#include <iostream>
#include <ctype.h>
template< typename REV_CHAR_ITER >
void print_reverse( REV_CHAR_ITER rbeg, REV_CHAR_ITER rend )
{
REV_CHAR_ITER found = std::find_if( rbeg, rend, ::isspace ) ;
std::copy( found.base(), rbeg.base(),
std::ostream_iterator<char>(std::cout) ) ;
if( found != rend )
{
std::cout << *found ;
print_reverse( ++found, rend ) ;
}
}
int main()
{
const std::string sentence = "test sentence, containing "
"a few extra spaces,\t\ttabs" ;
print_reverse( sentence.rbegin(), sentence.rend() ) ;
std::cout << '\n' << sentence << '\n' ;
}
vijayan121
Posting Virtuoso
1,606 posts since Dec 2006
Reputation Points: 1,159
Solved Threads: 287
Yet another variant(s):
void Reverser(std::istream& sentence = std::cin, char delim = '\n')
{
std::string word;
if (sentence >> word)
{
Reverser(sentence,' ');
cout << word << delim;
}
}
inline
void Reverser(const std::string& sentence)
{
Reverser(std::istringstream(sentence));
}
ArkM
Postaholic
2,001 posts since Jul 2008
Reputation Points: 1,234
Solved Threads: 348
Depending on the spacing...(if it doesn't matter) you can use a LIFO stack... I'd use the STL stack...the code would look like this:
#include <iostream>
#include <string>
#include <stack>
using namespace std;
stack<string> sstack;
string word;
int main( void )
{
while( cin >> word ) sstack.push( word );
while( !sstack.empty() ) {
cout << sstack.top() << " ";
sstack.pop();
return 0;
}
gregorynoob
Junior Poster in Training
86 posts since Jun 2008
Reputation Points: 12
Solved Threads: 5
Thanks a lot guys ... all these were excellent solutions... i'm trying to condition my 'approach' to solving problems ....
Agni
Practically a Master Poster
655 posts since Dec 2007
Reputation Points: 431
Solved Threads: 116