1

I was solving the following problem: Reverse the digits of an integer. Now the code for the problem is straightforward.

void reverse(int x){
   if(x < 0){
      cout << "-";
      x*=(-1);
   }

   while(x!=0){
      cout << x%10;
      x/=10;
   }
}

But the problem asked the answer to be returned as integer. So I was wondering is there any way the output stream can be redirected to an integer. I know I could redirect it to a string and then convert to integer. But is there any direct way?

Shafi
  • 1,850
  • 3
  • 22
  • 44
Akshay Arora
  • 729
  • 1
  • 8
  • 20
  • 1
    Considering integers are rarely thought of or used as a sequence of digits instead of a value, this doesn't really warrant a standard library addition. You could make one akin to `std::ostringstream` if you wanted to. – chris Jan 15 '16 at 16:30
  • It's unclear what you mean by *redirect*. Could you elaborate on that, please. – Cheers and hth. - Alf Jan 15 '16 at 17:24
  • @Cheersandhth.-Alf For instance in the code above, I had to actually return an integer instead of printing it to stdout. – Akshay Arora Jan 16 '16 at 09:14
  • The "direct" way would be to compute the value that has digits in reverse order, rather than trying to intercept output. – Peter Jan 16 '16 at 09:23

4 Answers4

2

Instead of using cout to directly display the result, try storing the result to a variable, say rev and return the result.

int reverse(int x)
{    
    bool neg = x < 0;
    int rev = 0;

    while (x != 0) {
        rev = (rev * 10) + (x % 10);
        x /= 10;
    }
    return neg ? -rev : rev;
}
trojanfoe
  • 120,358
  • 21
  • 212
  • 242
aliasm2k
  • 883
  • 6
  • 12
  • This is incomplete at best. Your `rev` variable doesn't have the sign (which is still printed to STDOUT), the function keeps overwriting it so that you only have one digit, and then you do nothing with it. A smart compiler would optimize this function to just `if (x < 0) { cout << "-"; }`. Not what the OP wanted, and not even what *you* wanted, I suppose. – Fabio says Reinstate Monica Jan 15 '16 at 17:02
  • Does that fix it? This look to me like the simplest, fastest, and overall best solution. – trojanfoe Jan 16 '16 at 09:36
1

Why not creating a function that returns int?

#include <cmath> // needed for pow()

int reverse(int x)
{    
  int y=0;
  int numDigits=0;
  int x2=x;

  // first count number of digits

  while(x2!=0){
  x2/=10;
  numDigits++;
  }

  // then do the reversion by adding up in reverse direction

  for(int i=0; i<numDigits; i++){
  y+=(x%10)*pow(10,numDigits-i-1);
  x/=10;
  }

  return y;
}
  • I know I could do it this way. But I'm not interested in reversing the digit, it's a trivial problem. But that of redirecting output to an integer. – Akshay Arora Jan 15 '16 at 16:48
  • 1
    And if you _did_ just want a reversed integer, there's no need to pre-compute the length; just multiply the answer by 10 as you divide the input by 10: `int ans=0; while(x) { ans = ans * 10 + (x%10); x /= 10; }` (ignoring sign: you'd remember/normalise at the start and apply `ans *= -1` at the end if needed). – TripeHound Jan 15 '16 at 17:23
1

You can use an std::ostringstream, save std::cout buffer, and then convert it to int:

void reverse(int x)
{
    std::ostringstream local_buffer;
    auto old_buff = std::cout.rdbuf(local_buffer.rdbuf()); // save pointer to std::cout buffer

    if(x < 0){
        std::cout << "-";
        x*=(-1);
    }

    while(x!=0){
        std::cout << x%10;
        x/=10;
    }

    std::cout.rdbuf(old_buff); // back to old buffer

    int rev = std::atoi(local_buffer.str().c_str());

    std::cout << "rev is: " << rev << "\n";
}

Online on Coliru

hlscalon
  • 7,304
  • 4
  • 33
  • 40
1

You can convert it to a string and go backwards and send it to a stringstream.

std::stringstream s;

std::string s = std::to_string(x);
for (std::string::reverse_iterator rit = s.rbegin(); rit != s.rend(); ++rit) {
    std::cout << *rit;
    ss << *rit;
}
std::cout << std::endl;
return stoi(ss.str());

Add

#include <sstream>

I ran the int- and string-version 2.5 mill. times in a loop and the string-version is twice as fast on my macbook pro 2012. 1.2 secs. vs 2.4 secs. Something to consider using strings even though it may be seldom used.

Update:

Another SO answer suggests std::reverse and when I updated the code to

auto s = std::to_string(x);
std::reverse(s.begin(), s.end());
return stoi(s);

it used 0.8 secs., three times faster than swapping digits.

Community
  • 1
  • 1
kometen
  • 6,536
  • 6
  • 41
  • 51