C#泛型链表获取每第n个元素的方法实现问题
C#泛型链表获取每第n个元素的方法实现问题
嘿,我明白你的困扰了——你现在遇到的核心问题是对「每第n个元素」的计数逻辑有两种不同的理解,而你的代码目前只能适配其中一种。我们来拆解一下:
你的两个例子对应了两种完全不同的“每nth元素”规则:
- 第一个例子(0-99,nth=10):你期望取的是索引为0、10、20...的元素(从列表第一个元素开始,每数10个元素取第一个,包括开头的0)。这时候你的代码把
count初始化为0,用count % nth == 0判断是完全正确的。 - 第二个例子(a/b/c/d,nth=4):你期望取的是第4个元素(从1开始计数的位置),也就是索引为3的d。这时候你的代码把
count初始化为1,用count % nth == 0判断才会生效(因为count走到4时,4%4=0,对应d)。
这两种规则是互斥的,所以你的代码没办法同时满足——因为它们对“第n个元素”的起始计数点定义不一样:一个从0开始(索引),一个从1开始(位置)。
那怎么解决呢?给你两个方案:
方案1:明确规则,修改代码适配
先确定你真正需要的是哪种规则:
如果要适配第一个例子的规则(从索引0开始,取nth倍数的元素):
保留你原代码中count初始化为0的逻辑,这时候第二个例子应该返回a而不是d——这说明你可能对第二个例子的需求描述有误,或者你其实想取的是“每4个元素里的第一个”(也就是a)。
代码就是你最初的版本:public OurList<T> SkipList(int nth) { if (nth <= 0) throw new ArgumentOutOfRangeException("Nth must be positive"); OurList<T> newList = new OurList<T>(); Node pTmp = first; int count = 0; while (pTmp != null) { if ((count % nth) == 0) newList.AddLast(pTmp.Data); pTmp = pTmp.Next; count++; } return newList; }如果要适配第二个例子的规则(从位置1开始,取nth倍数的元素):
把count初始化为1,这时候第一个例子会返回10、20...90(也就是位置10、20...100的元素),如果这不是你想要的,那你需要调整对第一个例子的预期。
代码如下:public OurList<T> SkipList(int nth) { if (nth <= 0) throw new ArgumentOutOfRangeException("Nth must be positive"); OurList<T> newList = new OurList<T>(); Node pTmp = first; int count = 1; while (pTmp != null) { if ((count % nth) == 0) newList.AddLast(pTmp.Data); pTmp = pTmp.Next; count++; } return newList; }
方案2:让方法支持两种模式
如果你确实需要两种规则都能支持,可以给方法加一个布尔参数,让调用者决定是从索引0开始还是从位置1开始:
public OurList<T> SkipList(int nth, bool startFromIndexZero = true) { if (nth <= 0) throw new ArgumentOutOfRangeException("Nth must be positive"); OurList<T> newList = new OurList<T>(); Node pTmp = first; int count = startFromIndexZero ? 0 : 1; while (pTmp != null) { if ((count % nth) == 0) newList.AddLast(pTmp.Data); pTmp = pTmp.Next; count++; } return newList; }
- 调用
SkipList(10)时,默认从索引0开始,返回0、10...90; - 调用
SkipList(4, false)时,从位置1开始,返回d。
这样就能同时满足你提到的两个场景啦!
备注:内容来源于stack exchange,提问作者Snipermtd24




