if (rowCount[i] >= 10)
{
for (int j = 0; j < blocks.Count; j++)
{
if (blocks[j].Row == i)
{
blocks.RemoveAt(j);
rowCount[i]--;
}
}
foreach (Block b in blocks)
{
if (b.Row < i)
{
b.Row++;
rowCount[b.Row]++;
}
}
}
所以说我在阻止名单中有20个区块。我经历了逐行调试的程序,我看到它没有检查列表中的每个块 - 它通常会留下4或5个未选中状态。我是疯了还是有什么我想念的?
答案 0 :(得分:10)
对于已接受的解决方案的更好解决方案是以不同方式分解它。您希望在第一个循环中执行两项操作:按匹配数减少rowcount[i]
,并从列表中删除匹配的行。现在,如果没有任何循环,你会怎么做?第一个很简单:
rowCount[i] -= blocks.Where(block=>block.Row == i).Count();
完成。第二个也很容易:
blocks.RemoveAll(block=>block.Row == i);
两行代码。没有循环。显然是正确的。
如果你没有写任何循环,那么你就不会在循环条件中出错。
答案 1 :(得分:5)
当你循环遍历数组时,你正在减小数组的大小,所以如果删除索引4,索引5将成为新的索引4,你永远不会检查它。
修复它的两种方法是递减迭代器
if (rowCount[i] >= 10)
{
for (int j = 0; j < blocks.Count; j++)
{
if (blocks[j].Row == i)
{
blocks.RemoveAt(j);
rowCount[i]--;
j--;
}
}
foreach (Block b in blocks)
{
if (b.Row < i)
{
b.Row++;
rowCount[b.Row]++;
}
}
}
或以相反顺序循环
if (rowCount[i] >= 10)
{
for (int j = blocks.Count - 1; j >= 0; j--)
{
if (blocks[j].Row == i)
{
blocks.RemoveAt(j);
rowCount[i]--;
}
}
foreach (Block b in blocks)
{
if (b.Row < i)
{
b.Row++;
rowCount[b.Row]++;
}
}
}