2013-10-11 75 views
0

我有这个循环。 TicketList以109票开始。 nColumns = 100。根据票数来计算我需要的行数。所以在这种情况下,我需要2行。第一行将被填满,第二行将只有9个条目。我有下面的循环。它只运行NumOfRows一次,并填充前100个,从不循环。For循环 - 不做最后一个循环

我错过了什么?

for (int j = 0; j < NumOfRows; j++) 
    { 
     for (int i = 0; i < nColumns; i++) 
     { 
      if (TicketList.Count() > 0) 
      { 
       t = rand.Next(0, TicketList.Count() - 1); 
       numbers[i, j] = TicketList[t]; 
       TicketList.Remove(TicketList[t]); 
      } 
     }     
    } 
+4

如何通过调试器逐步完成?或者添加一些'Trace'语句来看看它在做什么? –

+0

要清楚,你的外循环只执行一次** ** –

+0

显示'NumOfRows'的值。附注:最好先洗牌,然后再填充行... –

回答

3

尝试更改您的代码以使用更类似于LINQ的功能方法。如果可能会使逻辑更容易。事情是这样的:

TicketList 
    .OrderBy(x => rand.Next()) 
    .Select((ticket, n) => new 
    { 
     ticket, 
     j = n/NumOfRows, 
     i = n % NumOfRows 
    }) 
    .ToList() 
    .ForEach(x => 
    { 
     numbers[x.i, x.j] = x.ticket; 
    }); 

您可能需要前后翻页x.i & x.j或使用nColumns代替NumOfRows - 我不知道你的逻辑一直在寻找 - 但是这个代码可能会更好地工作。

+0

+1。代码清楚地分离步骤。请注意,'Aggregate()'而不是'ToList.ForEach'序列也可以工作,不需要额外的副本来列出。 –

+0

@AlexeiLevenkov - 'Aggregate'不允许赋值语句。你仍然需要某种循环来允许分配。 – Enigmativity

+0

为什么? '.Aggregate(0,(_,x)=>数字[x.i,x.j] = x.ticket);' –

1

除了一些不好的选择,你的循环似乎很好。我想冒险NumOfRows是不是正确计算。

表达式NumOfRows = (TotalTickets + (Columns - 1))/Columns;应计算正确的行数。

另外,您应该使用属性版本Count而不是Linq扩展方法,并使用IList<T>.RemoveAt()List<T>.RemoveAt而不是Remove(TicketList[T])

使用Remove()要求枚举列表以查找要删除的元素,该列表可能与您定位的索引不同。更不用说,当您已经知道要删除的正确索引时,您将扫描每次删除呼叫的列表的50%(平均)。

前面列出的功能方法似乎是矫枉过正。

我试图复制你的问题,假设使用中的各种变量的某些事实。该循环重复预期的次数。

static void TestMe() 
    { 
     List<object> TicketList = new List<object>(); 

     for (int index = 0; index < 109; index++) 
      TicketList.Add(new object()); 

     var rand = new Random(); 
     int nColumns = 100; 
     int NumOfRows = (TicketList.Count + (nColumns - 1))/nColumns; 
     object[,] numbers; 
     int t; 

     numbers = new object[nColumns, NumOfRows]; 

     for (int j = 0; j < NumOfRows; j++) 
     { 
      Console.WriteLine("OuterLoop"); 
      for (int i = 0; i < nColumns; i++) 
      { 
       if (TicketList.Count > 0) 
       { 
        t = rand.Next(0, TicketList.Count - 1); 
        numbers[i, j] = TicketList[t]; 
        TicketList.RemoveAt(t); 
       } 
      } 
     } 
    } 

您看到的问题必须是您没有包括在样品中的问题的结果。

+0

大声笑。矫枉过正?在我心中优雅简单。 :-) – Enigmativity

+0

@Enigmativity - 不只是矫枉过正,效率也不高。 – William

+0

在这种情况下,我怀疑它比OP的代码更有效率。阅读和调试当然更容易。 – Enigmativity