递归函数,用于计算数字中的位数
Recursive function to count the amount of digits in a number
有没有办法编写一个递归函数,该函数打印数字中的位数,以便:
-这是一个空洞功能
-"if"条件是if(num==0),返回
-"else"将调用递归。
我看到了 2 种不同类型的代码,其中一种是"if"条件具有递归调用,另一种是"返回"。但这不是我想要的。
我对递归很糟糕,并试图通过自己编码来理解它,但没有成功。
这是我的代码(我明白为什么它打印 122 而不是 3,但我真的不知道编码有何不同。帮助任何人?
#include <iostream>
#include <string.h>
using namespace std;
void numOfDigits(unsigned int num);
int main(){
int num = 994;
numOfDigits(num);
}
void numOfDigits(unsigned int num)
{
int size = 1;
if (num==0)
return;
else
{
if (num / 10 != 0)
size++;
numOfDigits(num / 10);
}
cout << size;
}
使此代码正常工作的一个快速技巧是使size
静态的,即更改
int size = 1;
自
static int size = 1;
但这仅在您第一次调用函数时有效。
对于更可靠的解决方案,在对函数的每次调用中,您必须传递到目前为止的计数:
void numOfDigits(unsigned int num, int countSoFar = 0) {
if (num == 0)
std::cout << countSoFar << 'n';
else
numOfDigits(num / 10, countSoFar + 1);
}
numOfDigits() 函数中有许多错误。
- 首先,每次调用函数时,都要声明一个名为 size 的新局部变量。这与调用函数中定义的"大小"无关。要查看此信息,请在初始化后打印大小。要解决此问题,请将大小设置为静态;然后,每次调用函数时,它将使用相同的静态变量。 当您在函数
末尾打印大小时,它只是在运行该函数后给出大小变量的值。即使将大小设置为静态,您也将打印大小的中间值。解决此问题的一种简单方法是允许函数返回大小,并且您只需在 main 函数中打印函数的值。
#include <iostream> #include <string.h> using namespace std; int numOfDigits(unsigned int num); int main(){ int num = 994; cout<<numOfDigits(num); } int numOfDigits(unsigned int num) { static int size = 1; if (num==0) return 0; else { if (num / 10 != 0) size++; numOfDigits(num / 10); } return size ; }
确保根据需要输入 (num == 0) 的大小写;在这种情况下,它会打印 0 作为答案。
PS:打印数字后始终加空格。否则,您可能会认为 1 2 2(实际打印的数字)是数字 122。
你可以通过引用传递一个值并使用它,每次调用这个函数时初始化ans=0
void recursive(unsigned int num,int &ans){
if(num == 0){
return;
}
else{
ans++;
recursive(num/10,ans);
}
}
看到这个和这个
不使用任何全局变量,此代码即可工作。只是一点说明:您声明了无符号的 int 参数,但您给函数的数字是一个有符号整数。
#include <iostream>
#include <string.h>
using namespace std;
void numOfDigits(unsigned int num, unsigned int& digits);
int main(){
unsigned int num = 93934;
unsigned int digits = 1;
numOfDigits(num, digits);
cout <<digits <<endl;
return 0;
}
void numOfDigits(unsigned int num, unsigned int& digits) {
if (num==0){
return;
}else{
if (num / 10 != 0){
++digits;
numOfDigits(num / 10, digits);
}
}
}
尝试全局声明大小,因为每次执行函数时都会初始化大小
int size = 1;
void numOfDigits(unsigned int num)
{
if (num==0)
return;
else
{
if (num / 10 != 0)
size++;
numOfDigits(num / 10);
}
}
主内尺寸的打印值
#include <iostream>
#include <string.h>
using namespace std;
void numOfDigits(unsigned int num);
void main(){
int num = 994;
int size = 1;
cout << numOfDigits(num, size);
}
void numOfDigits(unsigned int num, int &size)
{
if (num==0)
cout<<size;
else
{
if (num / 10 != 0)
size++;
numOfDigits(num / 10, size);
}
}
我认为您的误解是您认为size
是一个变量。但是,在函数的每次调用中,您都有一个不同的函数。此外,函数的每次调用都会再次打印它。
主cout
不执行任何操作,因为它打印了一个没有内容的空白。
通常,你会给它一个返回参数,即累积的数字,比如
int numOfDigits(unsigned int num);
void main(){
cout << numOfDigits(994) << endl;
}
如果您出于某种原因不希望这样做,您可以通过引用来完成:
int numOfDigits(unsigned int num, unsigned int& digits);
void main(){
unsigned int digits;
numOfDigits(994,digits);
cout << digits << endl;
}
但这并不那么好。
也就是说,就风格而言,我要做的是让它成为一个循环(想法是你想避免大多数时候递归):
unsigned int numOfDigits(unsigned int num){
if(num == 0) { return 1; }
unsigned int size = 0;
while(num != 0){
size++;
num /= 10;
}
return size;
}
这也可以通过引用返回值的调用来完成。但同样,如果没有必要,这有点奇怪。
您甚至可以通过使用数学、cout << floor(log_10(num)) << endl;
(如果 num 为零,则不考虑特殊情况)使其成为单行代码
一种可行的解决方案是将大小作为全局变量。但是,我建议不要这样做。一般应避免使用全局变量。只是想提一下,如果别人推荐的话。
最后,你可以使用一个类,比如DigitsCounter
,它通常是短暂的,并且对方法进行递归调用,大小变量是一个类成员。不过,这对您来说太过分了。
试试这段代码:
int numOfDigits(unsigned int num)
{
int size = 1;
if (num!=0)
{
if (num / 10 != 0)
size+= numOfDigits(num / 10);
}
return size;
}
在主函数中使用返回值
在递归函数上使用void
返回类型的问题是,嵌套调用不可能将任何信息返回到调用它们的方法。如果我们想在第一次(外部)调用时打印值,则第一次调用无法从其递归调用中获取任何信息。
正如你所观察到的,不可能简单地打印值,因为从递归调用到输出字符没有一对一的映射(如果我们使用基数 10......请参阅附录)。如果我们放宽if
条件必须立即返回的条件,我们可以通过将信息作为参数传递给递归调用,然后在递归的最深层次打印值来避免这个问题。例如:
// The accumulator starts at 0, then increases by 1 for each recursive call
void numOfDigits(unsigned int num, unsigned int accumulator = 0) {
if (num == 0) {
if (accumulator == 0) cout << 1; // Special case: numOfDigits(0) = 1
else cout << accumulator;
} else numOfDigits(num / 10, accumulator + 1);
}
旁注:这现在是一种尾递归方法:它将递归调用作为其最后一个操作。这很有用,因为它允许编译器降低方法的空间复杂性(请参阅说明)。实质上,编译器将方法转换为简单迭代,无需累积堆栈帧。
附录:我可以看到保留约束 (2) 的唯一方法是打印基数 1 中的位数,因为从参数中获取的每个数字都直接对应于基数 1 中的单个字符)。这可能不是你的意思,但这里有一个解决方案:
// The accumulator starts at 0, then increases by 1 for each recursive call
void numOfDigits(unsigned int num) {
if (num == 0) return;
else {
cout << 1
numOfDigits(num / 10);
}
}
注:注:此方法不会为numOfDigits(0)
打印任何内容,如果我们想保持行if (num == 0) return;
,这是必需
-
numOfDigits 是一个 void 函数
-
"if"条件是if(num==0),返回
-
"else"将调用递归。
这里:
void numOfDigits(unsigned int num) {
if (num == 0)
return;
// The "else" will call the recursion.
else {
static int size = 1;
if (num / 10 != 0) {
size++;
numOfDigits(num / 10);
}
else {
cout << size << 'n';
size = 1;
}
}
}
- 用于检查数字是否有数字或可被该数字的值整除的程序
- C++ 函数,用于查找传入的 N 个数字的平均值、总和、最小值和最大值
- 在C++不适用于猜数字游戏的情况下再次播放选项
- C++ 为什么数字限制不适用于uint8_t和int8_t?
- C++ for 循环,用于反转数字 10 - 99
- 一个C++程序,用于在输入位数时输出具有特定位数的 .txt 文件中的所有数字
- 循环中的线程 Runnin 用于对 c++ 中的数字求和
- 为什么这个代码不适用于大数字
- 用于筛子的最佳数据结构是什么(即一些被划掉的数字列表)?
- 如何实现通用比较?(用于数字和字符串)
- C/C++ - 用于按顺序打印数字的 sem_t 类型的单个信号量
- 递归函数用于计算 n 个数字之和的意外输出
- 找到printf的意外错误,该格式为0.1F,用于四舍五入数字
- 递归函数,用于计算数字中的位数
- C++:有哪些常规方法可以使代码更有效地用于大数字
- Timsort 实现C++不适用于 10,000 个数字
- 位掩码,用于确定数字是正数还是负数 c++
- 用于计算不包含给定数字的第n个数字的程序
- 像儒略数字用于计算日期一样,是否有任何特定的数字来计算时间
- 如何使从函数返回的数字用于定义数组中的任何元素