for 循环跳过列表元素

时间:2021-02-27 14:03:27

标签: c#

我对下面显示的代码有问题。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace problem2
{
    class Program
    {
        static void Main(string[] args)
        {

            int[] nums = Console.ReadLine().Split().Select(int.Parse).ToArray();
            List<int> lst = nums.OfType<int>().ToList();
            while (true)
            {
                string des = Console.ReadLine();
                var output = Regex.Replace(des.Split(" ")[0], @"[^0-9a-zA-Z\ ]+", "");
                

                if (output == "Add")
                {
                    string val = Regex.Replace(des, "[^0-9]", "");
                    int value = int.Parse(val);
                    lst.Add(value);
                }
                else if(output == "Remove")
                {
                    string val = Regex.Replace(des, "[^0-9]", "");
                    int value = int.Parse(val);
                    lst.Remove(value);
                }else if(output == "Replace")
                {
                    String result1 = System.Text.RegularExpressions.Regex.Match(des, @"\d+").Value;
                    
                    var lastno = des.Split().Last();
                    List<int> lst2 = lst;
                    

                    for (int i = 0; i < lst2.Count; i++)
                    {
                        if(lst[i] == int.Parse(result1))
                        {
                            lst[i] = int.Parse(lastno);
                            break;
                        }
                    }
                    lst = lst2;
                }
                else if(output == "Collapse")
                {
                    string val = Regex.Replace(des, "[^0-9]", "");
                    int value = int.Parse(val);
              

                    for(int i = 0; i < lst.Count; i+=1)
                    {
                        int element = (int)lst[i];
                        if (element < value)
                        {
                            lst.RemoveAt(i);
                        }
                        else
                        {
                            continue;
                        }
                    }
                    
                    
                }else if (output == "Mort")
                {
                    PrintValues(lst);
                    break;
                }
            }
        }

        public static void PrintValues(IEnumerable myList)
        {
            foreach (Object obj in myList)
                Console.Write("{0} ", obj);
            Console.WriteLine();
        }
    }
}

这部分代码更准确:

else if(output == "Collapse")
{
    string val = Regex.Replace(des, "[^0-9]", "");
    int value = int.Parse(val);


    for(int i = 0; i < lst.Count; i+=1)
    {
        int element = (int)lst[i];
        if (element < value)
        {
            lst.RemoveAt(i);
        }
        else
        {
            continue;
        }
    }

我尝试了各种选项,但循环遗漏了元素。举个例子

entrance:
1 2 -1 0 -3 9 8 7 2
Collapse 8
Mort

output:
9 8

但程序给了我这个输出:

2 0 9 8 2

我试图通过调试器查看问题所在,发现循环丢失了元素

3 个答案:

答案 0 :(得分:1)

您正在修改正在迭代的集合。这会将元素移动到其他索引并使您为 i 标头中的后续元素确定的 for 无效。更好地向后循环

for (int i = lst.Count - 1; i >= 0; i--) {
    // Now you can safely remove (or add) elements without affecting 
    // the index of non yet processed elements.
}

您仍在修改前面元素的索引,但现在正在向后移动。

在 Visual Studio 中,您可以使用 forr 代码段创建反向 for 循环。输入

<块引用>

forr .

(当然还有用于普通 for 循环的 for 代码片段。它将使用 i++ 而不是 i += 1 来增加索引。)


此外,如果列表很长并且您要删除许多元素,则值得考虑性能。这种方法可以移动大量元素。在这种情况下,将要保留的元素复制到新列表(使用适当的初始容量进行初始化)会更有效。

答案 1 :(得分:1)

详细说明@Berkay 的评论:您在循环时更改了列表。如果 i 是 2 并且您删除该元素,那么曾经位于索引 3 的元素现在变为 2,依此类推。他递减 i 的方法会奏效。另一种方法是改用 linq .Where 语句:

var newList = lst.Where(e=> e>=value).ToList();

答案 2 :(得分:1)

应该是,

for(int i = 0; i < lst.Count; i+=1)
{
       int element = (int)lst[i];
       if (element < value)
       {
           lst.RemoveAt(i);
           i--;
       }
       else
       {
           continue;
       }
}

正如评论中提到的@David784。当您从迭代集合中删除元素时。每次删除 i 项后,您都会错过 1 个元素。