HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Simply print the string backwards

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
thebackwardsprintsimplystring

Problem

This code is very, very simple, but I was wondering how it could be improved:

#include 

int main() {
    std::string input;
    std::getline(std::cin, input);

    for(int i = 1; i <= input.length(); i++){
        std::cout << input[input.length() - i];
    }

    std::cout << '\n';
    return 0;
}


This code takes a string input, and prints it backwards. For example:

This will be printed backwards.


Becomes:

.sdrawkcab detnirp eb lliw sihT


Given the simplicity of this code, is there a way to optimize it? I understand that since it is very short, it will run fast no matter what. However, I hate inefficiencies in code, and I want to help improve the way that I write code.

This is related to, but not copied directly from, this SO answer. (I only found this SO answer after writing the code)

Solution

One simple improvement would be to restructure the for() loop:

for(int i = input.length() - 1; i >= 0; --i){
    std::cout << input[i];
}


A simple decrement operation might lead to more efficient machine code than calculating input.length() - i in every iteration.

Another improvement would be to use a more c++-ish way. But that means to change the string itself:

std::getline(std::cin,input);
 std::reverse(std::begin(input),std::end(input));
 std::cout << input << '\n';


Or using the reverse iterators in the loop:

for(auto it = input.rbegin(); it != input.rend(); ++it) {
      std::cout << *it;
 }


As I've mentioned in my comment, the most generic (and c++stylish) way to achieve that is to write your own adapter to achieve iterating a sequence in the reverse order. So I'm citing that solution here:

// -------------------------------------------------------------------
 // --- Reversed iterable
 using namespace std; // for rbegin() and rend()

 template 
 struct reversion_wrapper { T& iterable; };

 template 
 auto begin (reversion_wrapper w) { return rbegin(w.iterable); }

 template 
 auto end (reversion_wrapper w) { return rend(w.iterable); }

 template 
 reversion_wrapper reverse (T&& iterable) { return { iterable }; }


Above taken from here.

Code Snippets

for(int i = input.length() - 1; i >= 0; --i){
    std::cout << input[i];
}
std::getline(std::cin,input);
 std::reverse(std::begin(input),std::end(input));
 std::cout << input << '\n';
for(auto it = input.rbegin(); it != input.rend(); ++it) {
      std::cout << *it;
 }
// -------------------------------------------------------------------
 // --- Reversed iterable
 using namespace std; // for rbegin() and rend()

 template <typename T>
 struct reversion_wrapper { T& iterable; };

 template <typename T>
 auto begin (reversion_wrapper<T> w) { return rbegin(w.iterable); }

 template <typename T>
 auto end (reversion_wrapper<T> w) { return rend(w.iterable); }

 template <typename T>
 reversion_wrapper<T> reverse (T&& iterable) { return { iterable }; }

Context

StackExchange Code Review Q#152615, answer score: 4

Revisions (0)

No revisions yet.