C#实现1/n小数循环节的递归算法编写及错误排查
1/n小数循环节递归算法修复
原代码缺陷
- 终止条件错误:循环的核心判断依据是余数重复,而非单个数字在结果中重复出现,原逻辑会误判提前终止或触发无限递归
- 未覆盖有限小数场景:当n的素因子仅含2、5时,1/n为有限小数无循环节,原代码未判断余数为0的边界情况,会导致栈溢出
- 无循环节截取逻辑:原代码直接输出所有已计算的小数位,无法拆分非循环前缀和循环节部分
修正后递归代码
using System; using System.Collections.Generic; namespace LB_5._2 { class Program { static void Main(string[] args) { Console.WriteLine("Enter number: "); int n = int.Parse(Console.ReadLine()); // 字典存储已出现过的余数,以及对应的小数位位置 Dictionary<int, int> remainderPos = new Dictionary<int, int>(); string period = GetPeriod(n, 10, remainderPos); if (string.IsNullOrEmpty(period)) { Console.WriteLine("该数值不存在循环节"); } else { Console.WriteLine($"循环节为({period})"); } } /// <summary> /// 递归获取1/n的循环节,返回空字符串表示无循环节 /// </summary> public static string GetPeriod(int n, int current, Dictionary<int, int> remainderPos, string currentRes = "") { int part = current / n; int remainder = current % n; // 余数为0,是有限小数,无循环节 if (remainder == 0) { return string.Empty; } // 余数已经出现过,说明找到循环起点 if (remainderPos.ContainsKey(remainder)) { // 从第一次出现该余数的位置截取到当前,就是循环节 return currentRes.Substring(remainderPos[remainder]); } // 记录当前余数对应的小数位位置 remainderPos.Add(remainder, currentRes.Length); currentRes += part.ToString(); // 递归计算下一位 return GetPeriod(n, remainder * 10, remainderPos, currentRes); } } }
测试结果验证
- 输入3:输出
循环节为(3) - 输入7:输出
循环节为(142857) - 输入2:输出
该数值不存在循环节 - 输入12:输出
循环节为(3)(对应1/12=0.08333...)
内容的提问来源于stack exchange,提问作者Death_Dealer
相关产品推荐
相关产品推荐

