C#查找列表最长重复序列报错:索引计数超出列表长度
我是C#新手,目标是实现查找列表中的最长重复模式,参考了字符串最长重复序列的实现思路,编写了如下代码:
using System; using System.Collections.Generic; public class Solution { //Checks for the largest common prefix public static List<int> lcp(List<int> s, List<int> t){ int n = Math.Min(s.Count,t.Count); for(int i = 0; i < n; i++){ if(s[i] != t[i]){ return s.GetRange(0,i); } } return s.GetRange(0,n); } public static void Main() { int[] use = {1,2,3,4,5,1,2}; List<int> list = new List<int>(use); List<int> lrs = new List<int>(); int n = list.Count; for(int i = 0; i < n; i++){ for(int j = i+1; j < n-i; j++){ List<int> x = new List<int> (); x = lcp(list.GetRange(i,list.Count-1),list.GetRange(j,list.Count-1)); if(x.Count > lrs.Count) lrs=x; } } Console.WriteLine("Longest repeating sequence: "+lrs); } }
运行时抛出如下异常,调整索引后仍无法解决,恳请帮忙排查修复:
Unhandled Exception:
System.ArgumentException: index and count exceed length of list
at System.Collections.Generic.List1[System.Int32].CheckRange (Int32 idx, Int32 count) [0x00000] in <filename unknown>:0 at System.Collections.Generic.List1[System.Int32].GetRange (Int32 index, Int32 count) [0x00000] in:0
at Solution.Main () [0x00000] in:0
[ERROR] FATAL UNHANDLED EXCEPTION: System.ArgumentException: index and count exceed length of list
at System.Collections.Generic.List1[System.Int32].CheckRange (Int32 idx, Int32 count) [0x00000] in <filename unknown>:0 at System.Collections.Generic.List1[System.Int32].GetRange (Int32 index, Int32 count) [0x00000] in:0
at Solution.Main () [0x00000] in:0
问题根源
异常核心是对List.GetRange的参数理解错误:第二个参数是要获取的元素总数,不是结束位置索引。你用list.Count-1作为count值,当起始索引i大于0时,i + count必然超过列表总长度(比如列表长度7,i=5时,5+6=11>7),直接触发越界异常。
另外内层循环条件j < n-i写得不合理,会跳过很多可能的起始位置对,导致漏查重复序列。
修复后的代码
using System; using System.Collections.Generic; public class Solution { // 查找两个列表的最长公共前缀 public static List<int> lcp(List<int> s, List<int> t){ int n = Math.Min(s.Count, t.Count); for(int i = 0; i < n; i++){ if(s[i] != t[i]){ return s.GetRange(0, i); } } return s.GetRange(0, n); } public static void Main() { int[] use = {1,2,3,4,5,1,2}; List<int> list = new List<int>(use); List<int> lrs = new List<int>(); int n = list.Count; for(int i = 0; i < n; i++){ // 遍历所有i之后的起始位置 for(int j = i+1; j < n; j++){ // 计算从i开始能取到的最大元素数:总长度 - 起始索引 List<int> subListI = list.GetRange(i, n - i); List<int> subListJ = list.GetRange(j, n - j); List<int> x = lcp(subListI, subListJ); if(x.Count > lrs.Count){ lrs = x; } } } // 正确输出列表元素,避免直接输出类型名 Console.Write("Longest repeating sequence: "); foreach(int num in lrs){ Console.Write(num + " "); } } }
修复要点
- 修正GetRange参数:把
list.GetRange(i, list.Count-1)改成list.GetRange(i, n - i),确保起始索引+元素总数不超过列表长度。 - 调整内层循环范围:将
j < n-i改为j < n,覆盖所有可能的起始位置组合。 - 优化结果输出:原代码直接输出列表对象会显示类型名称,改为遍历元素输出实际数值。
内容的提问来源于stack exchange,提问作者Henrique Moniz

