You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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:明确规则,修改代码适配

先确定你真正需要的是哪种规则:

  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;
    }
    
  2. 如果要适配第二个例子的规则(从位置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

火山引擎 最新活动