【问题标题】:Count digits of number without loop C++计算没有循环C ++的数字位数
【发布时间】:2014-09-08 09:32:23
【问题描述】:

我必须计算一个数字的位数。

我将数字除以 10,直到得到 0。每次迭代都会递增计数器。

int num;
cin>>num;  
while(num > 0)  
{  
  counter++;
  num = num / 10;   
}

挑战不是使用任何循环或递归,只是一个if 语句。

有可能吗?

【问题讨论】:

  • 递归函数怎么样?
  • @dolan,好主意!像!但在这种情况下也是禁止的:-(
  • @yaelaviv log10(n)+1 其中n 是数字。例如,log10(1234) + 1 是 4。
  • 如果你不能使用递归,你应该在问题中说明。
  • @MarounMaroun,为什么是+1

标签: c++


【解决方案1】:

计数器 = log(num) / log(10)

在 C++ 中:

#include <cmath>
....
counter = num == 0 ? 1 : log10(std::abs(num)) + 1;

你想要的是日志功能。

cplusplus - log10

cplusplus - std::abs

【讨论】:

  • 虽然num == 0 还是坏了。
  • @Vladp,log10 必须使用双变量吗?
  • 这不适用于 num == int min (在 2s 补码机器上)。我不确定 std::abs 在这种情况下的标准是什么,但它给出的答案显然是错误的。 [见ideone.com/exvOQK]
  • @Mike, std::abs() 继承自 C 的 stdlib 标头,如果无法表示结果,则指定未定义的行为。
【解决方案2】:

简单的方法虽然有点贵,但是把你的数字变成字符串,并像下面的例子那样取它的大小:

#include <iostream>
#include <string>

int main() {
  int i = 1232323223;
  std::string str = std::to_string(std::abs(i));
  std::cout << "Number of Digits: " << str.size() <<std::endl;
}

LIVE DEMO

【讨论】:

  • 不适用于 int min(在 2s 补码机器上)
【解决方案3】:

如果您认为int 的最大大小是有限的,这实际上很容易。只需检查数字是否大于 10、大于 100、大于 1000 等。您甚至可以进行二分查找。

int num = abs(number);
if (num < 10000)
{
    if (num < 100)
        return num < 10 ? 1:2;
    else
        return num < 1000 ? 3:4;   
}
else
{
    ...
}

【讨论】:

  • you could even do binary search 怎么样?
  • @yael 编辑:提供了一个例子
【解决方案4】:

一种方法是使用sprintf,因为它返回发出的字符数:

int digits(int n)
{
    char s[32];
    int len = sprintf(s, "%d", n);
    if (n < 0) len--; // NB: handle negative case
    return len;
}

【讨论】:

  • 我认为s 应该是temp(反之亦然),是吗?
  • @paxdiablo:谢谢 - 已修复。
【解决方案5】:

当然可以,比如(对于 32 位数字):

int numDigitsU (unsigned int n) {
    if (n <         10) return 1;
    if (n <        100) return 2;
    if (n <       1000) return 3;
    if (n <      10000) return 4;
    if (n <     100000) return 5;
    if (n <    1000000) return 6;
    if (n <   10000000) return 7;
    if (n <  100000000) return 8;
    if (n < 1000000000) return 9;
    /*      4294967295 is 2^32-1 - add more ifs as needed
       and adjust this final return as well. */
    return 10;
}

签名变体有点棘手,因为符号先反转,你必须注意MININT

int numDigitsS (int n) {
    if (n == MININT) n = MAXINT;  // same number of digits, usually.
    if (n < 0) n = -n;            // reverse sign.
    return numDigitsU (n);        // call the unsigned variant.
}

只需根据你最大unsigned int的大小调整最高比较值和返回值即可。

这应该适用于所有允许的负编码:二进制补码、二进制补码和符号/大小。

【讨论】:

  • 该死,你快了 10 秒 :),+1。
  • 这里实际上是展开循环。 OK 比使用 for 循环更快,但也很冗长。
【解决方案6】:

你可以通过以下方法找到整数的长度:

int countDigits(int *num){
    int count =0;
    while(*num>0){
        count++;
        *num /=10;
    }
    return count;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-04
    • 2022-01-23
    • 1970-01-01
    • 2017-03-05
    • 1970-01-01
    • 2017-01-17
    • 2015-11-13
    • 1970-01-01
    相关资源
    最近更新 更多