C#未知新数组长度时如何避免两次循环筛选数组并存入符合条件元素
单循环实现方案
可以仅通过一次遍历完成需求,最简洁的实现方式是借助List<int>的动态扩容能力,无需提前统计符合条件的元素数量,完整实现完全匹配你给出的接口约束:
public static int[] FilterByDigit(int[] source, int digit) { // 参数校验,符合接口定义的异常规则 if (source == null) throw new ArgumentNullException(nameof(source)); if (source.Length == 0) throw new ArgumentException("Source array cannot be empty.", nameof(source)); if (digit < 0 || digit > 9) throw new ArgumentOutOfRangeException(nameof(digit), "Digit must be between 0 and 9."); List<int> result = new List<int>(); foreach (int num in source) { if (num.ToString().Contains(digit.ToString())) { result.Add(num); } } return result.ToArray(); }
该实现全程仅遍历一次原数组,符合条件的元素直接加入临时集合,最后转数组返回即可。
如果你的开发环境受限不允许使用List<T>,也可以用原生数组操作实现单循环逻辑:先开辟和原数组等长的临时数组存储符合条件的元素,同时统计有效元素数量,遍历完成后再截取有效长度的数组返回,仅多一次小数组拷贝操作,性能仍远优于两次遍历原数组:
public static int[] FilterByDigit(int[] source, int digit) { // 参数校验逻辑和上面一致 if (source == null) throw new ArgumentNullException(nameof(source)); if (source.Length == 0) throw new ArgumentException("Source array cannot be empty.", nameof(source)); if (digit < 0 || digit > 9) throw new ArgumentOutOfRangeException(nameof(digit), "Digit must be between 0 and 9."); int[] temp = new int[source.Length]; int count = 0; foreach (int num in source) { if (num.ToString().Contains(digit.ToString())) { temp[count] = num; count++; } } int[] result = new int[count]; Array.Copy(temp, result, count); return result; }
可选性能优化
原逻辑中通过转字符串判断数字是否包含指定位的实现会产生额外的字符串内存分配,在意性能的话可以替换为数学运算实现判断,避免GC开销:
private static bool HasDigit(int number, int digit) { // 处理负数和0的特殊情况 number = Math.Abs(number); if (number == 0 && digit == 0) return true; while (number > 0) { if (number % 10 == digit) return true; number /= 10; } return false; }
直接把之前代码里的字符串判断替换为if (HasDigit(num, digit))即可。
内容的提问来源于stack exchange,提问作者Linascts
相关产品推荐
相关产品推荐

