C递归实现数分解

题目描述:

把一个给定的整数分解成若干个素数的和。

Input

一个数。(32位无符号整型数范围内。)

Output

一些素数。

Sample Input

9

Sample Output

3 3 3

实现代码:

#include<stdio.h>
#include<math.h>
int prime(unsigned int n)  //素数判断
{
   unsigned int i;
   int flag=0;  //标志位设为0

   for(i=2;i<=sqrt(double(n))+1;i++)
   {
    if(n==2) { flag=1; break; }
    if(n%i!=0) flag=1;
    else { flag=0; break; }
   }
 if(flag==1) return 1;
 if(flag==0) return 0;
}
void serparte(unsigned int n,int k,int i)  //分解数
{
 if(n%i==0||prime(n))
 {
  k=n-i;
  printf("%d ",i);
  if(prime(k)) printf("%d ",k);
  else
       serparte(k,k,i);
 }
 else
 {
  ++i;
  serparte(n,k,i);
 }
}
int main()
{
 int n,k=0;
 while(scanf("%d",&n)!=EOF)
  serparte(n,k,2);
 return 0;
}
 

<think>嗯,用户想了解如何用C语言递归实现字反转。首先,我得回忆一下递归的基本原理。递归就是函自己调用自己,每次调用解决一个更小的子问题,直到达到基本情况。那字反转的话,比如输入12345,输出应该是54321。 那怎么用递归来做呢?我需要考虑每一步递归如何处理字的位。比如,假设函reverse(n)返回n的反转。那递归的思路可能是每次取出最后一位,然后递归处理剩下的字,再把最后一位放到前面。例如,reverse(123) = 3 * 10^2 + reverse(12),而reverse(12) = 2*10 + 1,这样组合起来就是321。 不过这里有个问题,如何确定每次需要乘以的10的幂次?可能需要一个辅助参来保存当前已经反转的部分,或者在每次递归时累积结果。比如,可以定义辅助函reverse_helper(n, reversed),其中reversed是已经反转的部分。初始调用时reversed为0,每次递归将n的最后一位加到reversed的末尾,然后递归处理n/10。例如,reverse_helper(123,0) → reverse_helper(12,3) → reverse_helper(1,32) → reverse_helper(0,321),返回321。 这样的话,主函reverse(n)调用reverse_helper(n, 0)。这样处理的话,递归的终止条件应该是当n等于0时返回reversed。那具体怎么实现呢?每次取出n的最后一位可以用n % 10,剩下的部分用n / 10。然后将当前reversed乘以10加上余,传递给下一次递归。 那这样的话,代码的大概结构是: int reverse(int n) { return reverse_helper(n, 0); } int reverse_helper(int n, int reversed) { if (n == 0) { return reversed; } else { return reverse_helper(n / 10, reversed * 10 + n % 10); } } 不过需要考虑负的情况。比如,输入-123,应该输出-321。所以在主函中,可能要先处理符号,将负转为正处理,最后再加上符号。或者,在递归过程中处理符号,但可能比较复杂。比如在reverse函中,检查n是否为负,如果是,先转为正,反转后再加上负号。 例如: int reverse(int n) { if (n < 0) { return -reverse_helper(-n, 0); } else { return reverse_helper(n, 0); } } 这样处理负的情况。不过要注意,如果反转后的超出int的范围,可能会溢出。比如,反转1000000003在32位int下会溢出,因为结果3000000001超过了INT_MAX。但题目可能暂时不考虑这个,或者需要用户自行处理。 测试一下例子,比如输入12345,递归过程: reverse_helper(12345, 0) → reverse_helper(1234, 5) → reverse_helper(123, 54) → reverse_helper(12, 543) → reverse_helper(1, 5432) → reverse_helper(0, 54321) → 返回54321 正确。再测试负:-123 → reverse_helper(123,0)得到321,然后取负得到-321。 那这样应该可行。需要注意n为0的情况,直接返回0。另外,如果输入的末尾有0,比如100,反转后是001,但作为整数会变成1。所以用户可能需要知道这一点,比如输入100反转得到1,而不是001。这是符合整数处理的常规做法的。 总结步骤的话,步骤如下: 1. 处理负,转为正处理,最后加上负号。 2. 递归每次取最后一位,加到反转的末尾。 3. 递归终止条件是被处理的变为0,返回累积的反转。 可能的代码实现如上述。不过需要确保递归的正确性,比如每次n减少一位,reversed乘以10加上余。这应该正确累积反转的结果。 另外,是否要考虑前导零?比如输入100,反转得到001,但作为整数是1。所以用户需要明确,反转后的字作为整数,前导零会被忽略,这可能符合预期。 总之,这样的递归方法可以实现字反转,但需要注意边界情况可能的溢出问题。</think>### C语言递归实现字反转的步骤说明 字反转是指将整数的各位字逆序排列。例如,输入 `12345`,反转后得到 `54321`。以下是使用递归实现的具体步骤: --- #### **1. 递归核心思路** 递归的核心思想是: - 每次取出原的最后一位(通过 `n % 10` 获取)。 - 将这一位追加到反转结果的末尾(通过 `reversed * 10 + digit` 实现)。 - 对剩余的继续递归处理(通过 `n / 10` 缩小问题规模)。 递归终止条件:当原 `n` 缩减为 `0` 时,返回累积的反转结果。 --- #### **2. 处理负** 若输入为负: - 先将其转换为正处理。 - 反转完成后,恢复负号。 --- #### **3. 代码实现** ```c #include <stdio.h> // 辅助递归 int reverse_helper(int n, int reversed) { if (n == 0) { return reversed; // 终止条件:返回累积结果 } else { // 取出当前最后一位,更新反转结果 return reverse_helper(n / 10, reversed * 10 + n % 10); } } // 主函(处理负) int reverse(int n) { if (n < 0) { return -reverse_helper(-n, 0); // 负转为正处理 } else { return reverse_helper(n, 0); } } // 测试 int main() { printf("%d\n", reverse(12345)); // 输出:54321 printf("%d\n", reverse(-123)); // 输出:-321 printf("%d\n", reverse(100)); // 输出:1(前导0被忽略) return 0; } ``` --- #### **4. 执行过程示例** 以输入 `123` 为例: 1. **第1层递归**:`n=123`, `reversed=0` - 计算:`123 % 10 = 3`, `reversed = 0 * 10 + 3 = 3` - 调用 `reverse_helper(12, 3)` 2. **第2层递归**:`n=12`, `reversed=3` - 计算:`12 % 10 = 2`, `reversed = 3 * 10 + 2 = 32` - 调用 `reverse_helper(1, 32)` 3. **第3层递归**:`n=1`, `reversed=32` - 计算:`1 % 10 = 1`, `reversed = 32 * 10 + 1 = 321` - 调用 `reverse_helper(0, 321)` 4. **终止条件**:返回 `321` --- #### **5. 注意事项** - **溢出问题**:若反转后的超出 `int` 范围(如 `2147483647` 反转后溢出),需额外处理(代码未包含)。 - **前导零**:输入如 `100` 会反转得到 `1`(前导零被忽略)。 --- 通过递归逐层分解问题,最终实现字反转。该方法简洁但需注意边界条件。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值