我可以将 int 转换为 string 然后计算位数吗?
Can I convert an int to string then count the number of digits?
我知道计算 int 位数的常用方法是使用循环,并一直除以 10 直到它消失。我很好奇,我可以先将int转换成字符串,然后计算字符串的长度以获得位数(假设只有正整数)吗?
如果这个方法可行,那和使用循环有什么区别?
是的,这个方法可以。
不同之处在于,如果您先转换为字符串,则会涉及一个额外的步骤。字符串转换实际上与您描述的循环类似。
下面是一个如何通过字符串长度计算整数位数的示例:
#include <string>
int number_of_digits(int number) {
// Using C++11
return std::to_string(number).length();
}
您可以使用 itoa()
函数(在下面的示例中,_itoa_s()
是 itoa()
的 safe 版本)。此函数基本上将整数转换为字符串(itoa=整数到字母表)。
这是一个例子:
int number;
char temp[12];
cout << "Enter your number: ";
cin >> number;
//itoa(number, temp, 10);
//_itoa_s(number, temp, 12, 10);
_itoa_s(number, temp, 10);
cout << "The number of digits is: " << strlen(temp) << endl;
itoa()
有 3 个参数:您要转换的数字 (number
),转换后数字将保存的缓冲区 (temp
),以及您要转换到的数字系统(10
以 10 为底,也称为十进制数字系统)。
_itoa_s()
采用第 4 个参数,缓冲区的大小。还有一个专门用于静态数组的 _itoa_s()
模板版本(在上面的示例中使用)。它需要 3 个参数,让编译器推断出第 4 个参数的缓冲区大小。
此外,我为 temp
缓冲区选择了 12 个字符,因为整数的最大值是 2,147,483,647,它有 10 个数字,加上空终止符和一些额外对齐的空间。
对于输入 0,明显的除以 10 方法将 return 0,这可能是也可能不是您想要的。除此之外,这两种方法 return 相同,但除以 10 快得多。
如果您像我在下面的示例(分配内存)中那样使用 std::string,那么除以 10 的方法很容易快数百倍。
int numlen_using_divide_by_10(int n) {
int ret = 0;
for (; n; n /= 10) ++ret;
return ret;
}
int numlen_using_string(int n) {
return std::to_string(n).size();
}
是的,你可以。不,你不想真的这样做。它将比使用循环慢 2 个数量级 (~100x)。为什么?因为整数到字符串的转换不仅要执行某种循环来生成字符串的数字,还必须分配和释放堆来保存字符串,除非字符串有一些某种小字符串优化。
在大多数情况下,人们会认为您的方法很丑陋。如果你想计算整数中的数字,你甚至不需要循环:
constexpr int digits(int32_t x) {
return
(x < 0 ? digits(-x) :
(x < 10 ? 1 :
(x < 100 ? 2 :
(x < 1000 ? 3 :
(x < 10000 ? 4 :
(x < 100000 ? 5 :
(x < 1000000 ? 6 :
(x < 10000000 ? 7 :
(x < 100000000 ? 8 :
(x < 1000000000 ? 9 :
10))))))))));
}
我知道计算 int 位数的常用方法是使用循环,并一直除以 10 直到它消失。我很好奇,我可以先将int转换成字符串,然后计算字符串的长度以获得位数(假设只有正整数)吗?
如果这个方法可行,那和使用循环有什么区别?
是的,这个方法可以。
不同之处在于,如果您先转换为字符串,则会涉及一个额外的步骤。字符串转换实际上与您描述的循环类似。
下面是一个如何通过字符串长度计算整数位数的示例:
#include <string>
int number_of_digits(int number) {
// Using C++11
return std::to_string(number).length();
}
您可以使用 itoa()
函数(在下面的示例中,_itoa_s()
是 itoa()
的 safe 版本)。此函数基本上将整数转换为字符串(itoa=整数到字母表)。
这是一个例子:
int number;
char temp[12];
cout << "Enter your number: ";
cin >> number;
//itoa(number, temp, 10);
//_itoa_s(number, temp, 12, 10);
_itoa_s(number, temp, 10);
cout << "The number of digits is: " << strlen(temp) << endl;
itoa()
有 3 个参数:您要转换的数字 (number
),转换后数字将保存的缓冲区 (temp
),以及您要转换到的数字系统(10
以 10 为底,也称为十进制数字系统)。
_itoa_s()
采用第 4 个参数,缓冲区的大小。还有一个专门用于静态数组的 _itoa_s()
模板版本(在上面的示例中使用)。它需要 3 个参数,让编译器推断出第 4 个参数的缓冲区大小。
此外,我为 temp
缓冲区选择了 12 个字符,因为整数的最大值是 2,147,483,647,它有 10 个数字,加上空终止符和一些额外对齐的空间。
对于输入 0,明显的除以 10 方法将 return 0,这可能是也可能不是您想要的。除此之外,这两种方法 return 相同,但除以 10 快得多。
如果您像我在下面的示例(分配内存)中那样使用 std::string,那么除以 10 的方法很容易快数百倍。
int numlen_using_divide_by_10(int n) {
int ret = 0;
for (; n; n /= 10) ++ret;
return ret;
}
int numlen_using_string(int n) {
return std::to_string(n).size();
}
是的,你可以。不,你不想真的这样做。它将比使用循环慢 2 个数量级 (~100x)。为什么?因为整数到字符串的转换不仅要执行某种循环来生成字符串的数字,还必须分配和释放堆来保存字符串,除非字符串有一些某种小字符串优化。
在大多数情况下,人们会认为您的方法很丑陋。如果你想计算整数中的数字,你甚至不需要循环:
constexpr int digits(int32_t x) {
return
(x < 0 ? digits(-x) :
(x < 10 ? 1 :
(x < 100 ? 2 :
(x < 1000 ? 3 :
(x < 10000 ? 4 :
(x < 100000 ? 5 :
(x < 1000000 ? 6 :
(x < 10000000 ? 7 :
(x < 100000000 ? 8 :
(x < 1000000000 ? 9 :
10))))))))));
}