【问题标题】:Redirecting standard output to integer将标准输出重定向到整数
【发布时间】:2016-01-15 16:27:58
【问题描述】:

我正在解决以下问题: 反转整数的数字。 现在问题的代码很简单。

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

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

但问题要求答案以整数形式返回。所以我想知道有什么方法可以将输出流重定向到一个整数。我知道我可以将它重定向到一个字符串,然后转换为整数。但是有什么直接的方法吗?

【问题讨论】:

  • 考虑到整数很少被认为或用作数字序列而不是值,这并不真正保证标准库的添加。如果你愿意,你可以制作一个类似于std::ostringstream 的东西。
  • 不清楚您所说的 redirect 是什么意思。请您详细说明一下。
  • @Cheersandhth.-Alf 例如在上面的代码中,我必须实际返回一个整数而不是将其打印到标准输出。
  • “直接”方式是计算具有倒序数字的值,而不是试图截取输出。

标签: c++ iostream


【解决方案1】:

不要使用cout直接显示结果,而是尝试将结果存储到一个变量中,比如rev并返回结果。

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;
}

【讨论】:

  • 这充其量是不完整的。您的 rev 变量没有符号(仍打印到 STDOUT),该函数不断覆盖它,以便您只有一位数字,然后您什么也不做。智能编译器会将此函数优化为仅if (x &lt; 0) { cout &lt;&lt; "-"; }。我想这不是 OP 想要的,甚至不是 想要的。
  • 这样能解决吗?这在我看来是最简单、最快和整体最佳的解决方案。
【解决方案2】:

您可以使用std::ostringstream,保存std::cout 缓冲区,然后将其转换为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

【讨论】:

    【解决方案3】:

    为什么不创建一个返回 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;
    }
    

    【讨论】:

    • 我知道我可以这样做。但我对反转数字不感兴趣,这是一个微不足道的问题。但是将输出重定向到整数。
    • 如果您确实只想要一个反转整数,则无需预先计算长度;只需将输入除以 10 时将答案乘以 10:int ans=0; while(x) { ans = ans * 10 + (x%10); x /= 10; }(忽略符号:您会在开始时记住/标准化并在需要时在末尾应用 ans *= -1)。
    【解决方案4】:

    您可以将其转换为字符串并向后发送并将其发送到字符串流。

    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());
    

    添加

    #include <sstream>
    

    我运行了 int 和 string 版本 2.5 磨机。一次循环,字符串版本在我的 macbook pro 2012 上是两倍。1.2 秒。与 2.4 秒相比。考虑使用字符串的东西,即使它可能很少使用。

    更新:

    另一个 SO answer 建议 std::reverse 并且当我将代码更新为

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

    它使用了 0.8 秒,比交换数字快三倍。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-15
      • 1970-01-01
      • 2015-10-21
      • 1970-01-01
      • 1970-01-01
      • 2012-05-26
      • 2016-04-26
      • 1970-01-01
      相关资源
      最近更新 更多